基本排序之快速排序

快速排序分为经典快速排序和随机快速排序,因为经典快速排序在工程上使用比较少,因此本文只将随机快速排序,它可以看作是经典快速排序的升级版本。

快速排序:

概述:

(1) 先生成一个随机数,作为下标,此下标对应的元素作为划分值。

(2) 将划分值与元素末尾的数值进行交换,让划分值处于末尾。

(3) 然后用Partition算法,将小于划分值的数放在左边,等于划分值的数放在中间,大于划分值的数放在右边,分为三部分。

Partiton算法三标准如下:

i)   当前数(index)<划分值,小于区下一个数和当前数交换,小于区向右扩一个位置

ii)   当前数=划分值,index++

iii)  当前数>划分值,当前数和大于区前一个数交换(交换是为了把当前数给大于区),大于区向左扩一个位置,index原地不动。

原地不动是因为大于区前那个数交换到了当前数的位置,这个数还没有进行判断,所以不动,等待下一次判断。


注意:此函数返回一个两个长度的数组,保存等于区的起始两个index!!!这样就能够很好的处理接下来要进行的递归所需要的参数。

算法稳定性:

  不稳定算法。

时间复杂度:

  NlogN

代码如下:

#include <iostream>
#include <random>
using namespace std;

class QuickSort_
{
public:
    void QuickSort(int array[], int length);
    void QuickSort(int array[], int L, int R);
    void swap(int array[], int a, int b);
    int *Partiton(int array[], int L, int R);
    int result[2];
};
void QuickSort_::swap(int array[], int a, int b)
{
    int temp = array[a];
    array[a] = array[b];
    array[b] = temp;
}
void QuickSort_::QuickSort(int array[],int length)
{
    //如果数组长度为空或者只有一个元素,那么直接进行返回
    if (length < 2)
        return;
    QuickSort(array, 0, length-1);
}

void QuickSort_::QuickSort(int array[], int L, int R)
{
    if (L < R)
    {
        //把划分值放到数组末尾去
        //产生一个0到R-L的随机数
        uniform_int_distribution<unsigned> u(0, R-L);   //产生无符号,0到R-L的随机数
        default_random_engine e;    //随机数引擎
        int index = L+u(e);    //将L偏移随机数index处位置的地方和末尾R交换
        swap(array, index, R);
        int *p = Partiton(array, L, R);
        QuickSort(array, L, p[0]-1);
        QuickSort(array, p[1]+1, R);
    }
    
}

int* QuickSort_::Partiton(int array[], int L, int R)
{
    int less = L-1;
    int more = R;
    while (L < more)
    {
        if (array[L] < array[R]) 
        {
            swap(array, ++less, L++);  //小于区向右扩一个位置就是++less
                                      //同时小于区下一个数就是++less后的对应值,和当前值L交换,L++继续下一次比较
        }
        else if (array[L] > array[R]) 
        {
            swap(array, --more, L); // 同理,大于区向左就是--more
                                    //同时,大于区前一个数就是--more之后对应值和当前数进行交换,L不变,等待下一次判断
        }
        else 
        {
            L++;     //若在等于划分值,就直接进行下一个数的判断。
        }
    }
    swap(array, more, R);
    result[0] = less + 1;
    result[1] = more;
    return result;
}

int main()
{
    int array[10] = {0,21,-1,3,3,2,8,6,-9,-5};
    QuickSort_ quick;
    quick.QuickSort(array, 10);
    for (int i = 0; i < 10; i++)
    {
        cout << array[i] << " ";
    }
    return 0;
}
原文地址:https://www.cnblogs.com/love-jelly-pig/p/8344088.html