• 快速排序


    快速排序(Quicksort)是对冒泡排序的一种改进。它的核心思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

    快速排序一趟算法思想:

    如果要对某含有n个元素的序列A进行排序。

    快速排序的一趟算法思想是:

    1.设置两个变量 i , j ,令 i = 0 ; j = n - 1 ;

    2.以第一个数组元素作为关键数据,赋值给key,即 key = A[0];

    3.从 j 开始向前搜索,即由后开始向前搜索(j - -),找到第一个小于key的值A[j],将A[j]和A[i]互换;

    4.从 i 开始向后搜索,即由前开始向后搜索(i + +),找到第一个大于key的值A[i],将A[i]和A[j]互换;

    5.重复第3、4步,直到 i = j 结束。

    快速排序举例:

    我们将以序列A:{ 6, 2, 7, 3, 8, 9, 5, 4 } 为例子,叙述一遍快速排序的排序算法流程。按照上述每一趟的算法思想,我们设置两个变量 i , j ,显而得知 序列长度 n = 8 , i = 0,j = 7

    第一趟:

    首先,取该序列的第一个元素 A[0]为关键元素,赋值为key,key = 6。

    1.1:从 j = 7开始往前寻找,此时A[j]=4,小于key,符合要求,则交换A[i]和A[j],那么此时 i=0,j=7,序列A:{ 4, 2, 7, 3, 8, 9, 5, 6 }

    1.2:从 i = 0开始往后寻找,此时A[i]=4,小于key,不符合要求

    1.3:i ++,i = 1,A[i]=2,小于key,不符合要求

    1.4:i ++,i = 2,A[i]=7,大于key,符合要求,则交换A[i]和A[j],那么此时 i=2,j=7,序列A:{ 4, 2, 6, 3, 8, 9, 5, 7 }

    1.5:j = 7 ,A[j]=7,大于key,不符合要求

    1.6:j - -,j = 6,A[j]=5,小于key,符合要求,交换A[i]和A[j],那么此时 i=2 ,j=6,序列A:{ 4, 2, 5, 3, 8, 9, 6, 7 }

    1.7:i = 2,A[i]=5,小于key,不符合要求

    1.8:i ++,i = 3,A[i]=3,小于key,不符合要求

    1.9:i ++,i = 4,A[i]=8,大于key,符合要求,交换A[i]和A[j],那么此时 i=4,j=6,序列A:{ 4, 2, 5, 3, 6, 9, 8, 7 }

    1.10:j=6,A[j]=8,大于key,不符合要求

    1.11:j - -,j = 5,A[j]=9,大于key,不符合要求

    1.12:j - -,j = 4,此时 i = j = 4 ,一趟终于结束了!!!

    细心的朋友一定发现了一个规律,我们选择 key = 6,结果,大于key的元素,都跑到了key的右边,小于key的元素,都跑到了key的左边。。

    没错,这就是次算法的核心思想。

    第二趟:

    此时,第一趟走完后,key左边是一个序列,我们称为A1:{ 4, 2, 5, 3 },key右边是一个序列,我们成为A2:{ 9, 8, 7 },此时分别对这两个序列进行快速排序,那么第一个序列的关键数据 key = A1[0] = 4,

    第二个序列的关键数据 key = A2[0] = 9,然后递归调用一趟的算法流程。

    第3,4 ...... n-1 趟:

    此后,每趟结束都会产生新的序列,继续递归。

    第 n 趟(最后一趟):

    继续分组到无法分组为止。这里的无法分组就是,每个组都是一个元素,也就是 i = j = 1。

    快速排序代码实现:

    #include<stdio.h>
    
    //输出数组
    void printArr(int a[], int n)
    {
        for (int i = 0; i < n; i++)
        {
            printf("%d--", a[i]);
        }
        printf("
    ");
    }
    
    //快速排序
    void QuickSort(int a[], int left, int right)
    {
        if (left >= right) {
            return;
        }
    
        // 定义两个标识
        int i = left;
        int j = right;
        int key = a[left];//将序列的第一个元素设为基数
        int temp;
    
        while (i < j)
        {
            while (i < j && a[j] >= key)
            {
                j--;
            }
            if (i != j)//如果i j没有相遇,交换位置
            {
                temp = a[i];
                a[i] = a[j];
                a[j] = temp;
            }
            while (i < j && a[i] <= key)
            {
                i++;
            }
            if (i != j)//如果i j没有相遇,交换位置
            {
                temp = a[i];
                a[i] = a[j];
                a[j] = temp;
            }
            else
            {
                printArr(a, 8);
            }
        }
    
        QuickSort(a, left, i - 1);
        QuickSort(a, i + 1, right);
    
    }
    
    void main()
    {
    
        int a1[8] = { 6, 2, 7, 3, 8, 9, 5, 4 };
        QuickSort(a1, 0, 7);
    
        getchar();
    }

    运行结果:

     

    从结果中可以看出,这个序列共需要5趟,其中第一趟所得结果与我们上述演算结果{ 4, 2, 5, 3, 6, 9, 8, 7 }一致。

    时间复杂度:

    最坏情况:O(n^2)

    最优情况:O(nlogn)

    平均情况:O(nlogn)

    稳定性:

    快速排序是一种不稳定的排序算法。

  • 相关阅读:
    第一次个人编程作业
    第一次博客作业
    Put-Me-Down项目Postmortem
    Alpha总结
    git分支与版本管理、版本回退、冲突解决记录
    【Alpha】Daily Scrum Meeting第五次
    【Alpha】Daily Scrum Meeting第四次
    【Alpha】Daily Scrum Meeting第三次
    【Alpha】Daily Scrum Meeting第二次
    一、Daily Scrum Meeting【Alpha】------Clover
  • 原文地址:https://www.cnblogs.com/zh1996/p/8351801.html
Copyright © 2020-2023  润新知