八大排序算法(6) 快排序

来源:互联网 发布:自学c语言要多久 编辑:程序博客网 时间:2024/06/16 13:02

基本思想

用分治的思想,在序列中选取一个基准数,把序列分成两个部分,一个部分比基准数小,一部分比基准数大,这样数列就被分成了两个部分,这两个部分间是有序的,然后就使用递归的思想,继续划分这两个部分,直到每个部分的数据个数都为1。

算法思路

 1. 假定将序列头作为基准数, 那么可以看成是将数列头提取出来的,需要在剩余的序列中找到一个数填进去。 2. 要将序列分出两个部分,左边的小于基准数,右边的大于基准数 3. 要保证 2 的话,则应该从右边开始遍历,找到第一个小于基准数的扔到左边去,找到的数的右边都是大于基准数的。此时可看成 右边 的部分少了一个大于基准数的数,那么就应该从左边开始遍历,找到第一个大于基准数的数扔到右边去,依次类推。如此可以保证左边、右边的部分都符合基本思路。 4. 当分出的两个部分的序列大于 1 的时候,则再对每个序列进行依次快排序

示例:

// 升序,左起/*初始值*/    3, 7, 5, 1, 2, 4, 9, 6, 10, 8// 将 3 设为基准数,基准数是 第 1 个,从右边起找到第一个小于 3 的数、交换、记录其位置/*第一趟*/    2, 7, 5, 1, 3, 4, 9, 6, 10, 8// 基准数 是 第5个。此时 第5个 右边的数都比 3 大,然后从左起找第一个大于 3 的数、交换、记录其位置/*第二趟*/    2, 3, 5, 1, 7, 4, 9, 6, 10, 8// 基准数 是 第2个。此时,第2个 左边的数都比 3 小,第5个 右边的数都比3大。接下来从 第5个 起向左找第一个小于 3 的数、交换、记录其位置/*第三趟*/    2, 1, 5, 3, 7, 4, 9, 6, 10, 8// 基准数 是 第4个。此时,第2个 左边的数都比 3 小,第4个 右边的数都比3大。 接下来从 第2个 起向右找第一个大于 3 的数、交换、记录其位置/*第四趟*/    2, 1, 3, 5, 7, 4, 9, 6, 10, 8// 基准数 是 第3个。此时,第3个 左边的数都比 3 小,第4个 右边的数都比3大。 接下来从 第4个 起向右找第一个小于 3 的数、交换、记录其位置// 此时,已顺利将序列 以第三个为界限 分为两个部分,左边的部分所有值、都比右边的部分小

重点:

如何高效的将序列分为小于/大于基准数的两个个部分。

思路:

 1. 在与基准数比较的时候,从右往左找到第一个小于基准数后,假设 index 为 m, 则此时 m 右边的值都是大于基准数的。此时,再将 m 与序列左边起第一个尚未与基准数比较过的位置交换,设该 index 为 n,即、将比基准数小的扔到了的左边。 2. 此时,可以保证的是,m 、不包括m 、右边的都比基准数大,n、包括n、左边的都比基准数小, m为基准数。 3. 下一个要找的数是 比基准数 大的,放在 m 的位置。 4. 所以接下来,从 n 开始往右遍历,找到第一个比 基准数 大的,假设 index 为 n1,然后放到 m 的位置。 5. 此时,可以保证的是, m 、包括m 、右边的都比基准数大, n1、不包括n1、左边的都比基准数小, n1 为基准数。 6. 下一个要找的数是 比基准数 小的,放在 n1 的位置。 7. 所以接下来,从 m 开始往左遍历,找到第一个比 基准数 大的,假设 index 为 m1,然后放到 n1 的位置。

代码:

void printList(int *l, int n) {    for (int i = 0; i < n; i++) {        printf("%d ", l[i]);    }    printf("\n");}void swap(int &m, int &n) {    int j = m;    m = n;    n = j;}void quickSort(int l[], int lenth ) {    if (lenth > 1) {        int index = 0;        // 升序         bool left = false;        printf("\nquik sort start\n");        printList(l, lenth);        for (int i = 0, j = lenth - 1; i < j;) {            printf("left: %d, i;%d, j:%d, index: %d\n", left, i, j, index);            if ( left ) {                // 从左往右 找第一个大于 l[index] 的                if (l[i] > l[index]) {                    swap(l[i], l[index]);                    index = i;                    // 变更遍历方向                    left = false;                    printList(l, lenth);                }                else {                    i++;                }            } else {                // 从右往左 找第一个小于 l[index] 的                if ( l[j] < l[index]) {                    swap(l[j], l[index]);                    index = j;                    // 变更遍历方向                    left = true;                    printList(l, lenth);                }                else {                    j--;                }            }        }        printList(l, lenth);        printf("quik sort end\n");        // 迭代左边部分和右边部分        quickSort(l, index);        quickSort(l + index + 1, lenth - index - 1);    }}int main(){    int a[10] = { 3,7,5,1,2,4,9,6,10,8 };    printf("初始值:");    printList(a, 10);    quickSort(a, 10);    printf("结果:");    printList(a, 10);    system("pause");    return 0;}

以上

原文链接 http://blog.csdn.net/u011546766/article/details/74055269