首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

关于wiki上快速排序例子的一个有关问题

2013-09-05 
关于wiki上快速排序例子的一个问题例子如下,我的问题是,其中有这样一句:/* 关键数据放到‘中间’ */swap(&a[

关于wiki上快速排序例子的一个问题
例子如下,我的问题是,其中有这样一句:
    /* 关键数据放到‘中间’ */
    swap(&a[left],&a[j]);
这句话在干什么?
我理解是a[left]是要比较的值,然后i,j分别为从头,尾两个方向进行交换,如果小于A[left]就放到头这边,大于就放到尾那边,最后ij会重叠在中间的莫个位置,
但这时候他把这个重叠点和a[left]交换了,我觉得有问题,ij相交的那个值和a[left]一样正好应该是左右两边的一个分界,左边永远小于它,右边永远大于他。交换后没有任何意义,而且导致了取了一个左边最大的数作为了左边递归的下一个pivot。这样左边的递归效率永远是最差的。

但我运行校验了下,又不符和我所想,请教下,我错在哪了?
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

#include <stdio.h>
int a[100] = { 1, 2, 8, 7, 9, 5, 6, 4, 3, 66, 77, 33, 22, 11 };
 
/* 输出数组前n各元素 */
void prt(int n) {
    int i;
    for (i = 0; i < n; i++) {
        printf("%d\t", a[i]);
    }
    printf("\n");
}
 
/* 数据交换 */
void swap(int *a, int *b)
{
    int tmp;
    tmp = *a; *a = *b; *b = tmp;
}
 
void quick_sort(int a[], int left, int right)
{
    int i = left + 1, j = right;
    int  key = a[left];
 
    if (left >= right) return;
 
    /* 从i++和j--两个方向搜索不满足条件的值并交换  *
     * 条件为:i++方向小于key,j--方向大于key      */
    while (1) {
       while (a[j] > key) j--;
       while (a[i] < key&&i<j) i++;
       if(i >= j) break;
       swap(&a[i],&a[j]);
       if(a[i]==key)j--;
       else  i++;
    }
 
    /* 关键数据放到‘中间’ */
    swap(&a[left],&a[j]);
 
    if(left  < i - 1)   quick_sort(a, left, i - 1);
    if(j + 1 < right)  quick_sort(a, j + 1 , right);
 
}
 
int main(void) {
 
    /* 排序与输出 */


    quick_sort(a, 0, 13);
    prt(14);
 
    return 0;
} 快速排序 算法
[解决办法]
不是啊。    比如8 7 6 5 10 9快排,第一次排序最终i和j都指向5这个数,   
 /* 关键数据放到‘中间’ */
    swap(&a[left],&a[j]);
这样操作之后刚好保证了5 7 6 8 10 9,它这样一换刚好保证了8在排序的正确位置上,因为下把左递归的时候是quick_sort(a, left, i - 1);指的是5 7 6这三个数进行递归排序。这样8的位置已经排正确了,不需要参与之后的递归排序。
[解决办法]
a[j]最终指向的是小于a[left]的值,因为你的所有元素都是和a[left]比较,如果不交换a[left]和a[j]的话,你左侧的元素就不一定小于a[j]

热点排行