快速排序算法代码实现

1 算法介绍

快速排序是一个“交换类”的排序,以军训排队为例,教官说:“第一个同学出列,其他人以他为中心,比他矮的全排到他的左边,比他高的全排他右边。”这就是一趟快速排序。可以看出,一趟快速排序是以一个“枢轴”为中心,将序列分成两部分,枢轴的一边全是比它小(或者小于等于)的,另一边全是比他大(或者大于等于)的。

2 执行流程

原始序列:
    49 38 65 97 76 13 27 49
    i                     jij开始时分别指向头,尾元素)
    进行第一趟快速排序,以第一个数49作为枢纽(通常都选第一个元素作为枢纽),整个过程是一个交替扫描和交换的过程。
    1)使用j,从序列最右端开始向前扫描,直到遇到比枢轴49小的数27j停在这里。
    49 38 65 97 76 13 27 49
    i                  j
    2)将27交换到序列前端i的位置。
    27 38 65 97 76 13    49
    i                  j
    3)使用i,交换扫描方向,从前向后扫描,直到遇到比较枢轴49大的数65i停在这里。
    27 38 65 97 76 13    49
          i            j
    4)将65交换到序列后端j的位置。
    27 38    97 76 13 65 49
           i           j
    5)使用j,交换扫描方向,从后向前扫描,直到遇到比枢轴49小的数13j停在这里。
    27 38    97 76 13 65 49
           i        j
    6)将13交换到i的位置。
    27 38 13 97 76    65 49
           i        j
    7)使用i,交换扫描方向,从前向后扫描,直到遇到比49大的数97i停在这里。
    27 38 13 97 76    65 49
             i      j
    8)将97交换到j位置。
    27 38 13    76 97 65 49
             i      j
    9)使用j,交换扫描方向,直到遇到比49小的数,当扫描到ij相遇时,说明扫描过程结束了。
    27 38 13    76 97 65 49
             ij
    10)此时i等于j的这个位置就是枢轴49的最终位置,将49放入这个位置,第一趟快速排序结束。
    27 38 13 49 76 97 65 49
             ij

可以看出一次快速排序后,将原来的序列以49为枢轴,划分为两部分,49左边的数都小于或等于它,右边的数都大于或等于它。接下来按照同样的方法对序列{27 38 13}和序列{76 97 65 49}分别进行快速排序。经过几次这样的快速排序,最终得到一个有序的序列。
快速排序代码如下:

#include 

void QuickSort(int *arr, int l, int r)
{
    int len = r;        // 存储当前数组的最后一个元素的坐标
    int num = arr[l];   // 用来存放枢轴元素
    bool dir = 0;       // 用来表示移动方向

    /*一趟快速排序*/
    while (l != r)
    {
        if (dir == 0)
        {
            if (arr[r] < num)
            {
                arr[l] = arr[r];
                dir = 1;
            }
            else
            {
                r--;
            }
        }
        else
        {
            if (arr[l] > num)
            {
                arr[r] = arr[l];
                dir = 0;
            }
            else
            {
                l++;
            }
        }
    }
    arr[l] = num;               // 将枢轴元素放入最终位置
    if (l > 1)
    {
        QuickSort(arr, 0, l - 1);
    }
    if (len - l - 1 > 1)
    {
        QuickSort(arr, l + 1, len);
    }
}

int main()
{
    int arr[] = { 49, 38, 65, 97, 76, 13, 27, 49 };
    int len = 8;
    QuickSort(arr, 0, len - 1);

    for (int i = 0; i < len; i++)
    {
        std::cout << arr[i] << " ";
    }
    std::cout << std::endl;
    system("pause");
    return 0;
}

简化后的快速排序算法实现代码:

void QuickSort(int *pArray, int iBegin, int iEnd)
{
    if (iBegin < iEnd)
    {
        int iLeft = iBegin;
        int iRight = iEnd;
        int iPivot = pArray[iBegin];

        while (iLeft < iRight)
        {
            while (iLeft < iRight && pArray[iRight] >= iPivot)
            {
                iRight--;
            }
            if(iLeft < iRight) pArray[iLeft++] = pArray[iRight];

            while (iLeft < iRight && pArray[iLeft] <= iPivot)
            {
                iLeft++;
            }
            if(iLeft < iRight) pArray[iRight--] = pArray[iLeft];
        }
        pArray[iLeft] = iPivot;
        QuickSort(pArray, iBegin, iLeft - 1);
        QuickSort(pArray, iRight + 1, iEnd);
    }
}

性能分析

(1)时间复杂度分析
快速排序最好情况下的时间复杂度为O(nlog2n),待排序列越接近无序,本算法效率越高。最坏情况下的时间复杂度为O(n2),待排序列越接近有序,本算法效率越低。平均时间复杂度为O(nlog2n)。就平均时间而言,快速排序是所有排序算法中最好的。快速排序的排序趟数与初始序列有关。
(2)空间复杂度分析
本算法空间复杂度为O(log2n)。快速排序是递归进行的,递归需要栈的辅助,因此它需要的辅助空间较多。

你可能感兴趣的:(C/C++程序设计)