排序算法之快排

快排(quick sort),是快速排序的简称。快速排序由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
快排有很多版本,不同的版本其写法略有差别,此处给出一种双指针扫描法。
具体做法是:(此处是升序,降序同理)

1.需要排序的区间是 [l,r] ,当 l<r 时,选取下标 pos=l 的数,设为val,否则退出
2.在 [l,r] 区间中,将小于val的数放在左边,将大于等于val的数放在右边,将val这个值放在中间,让pos等于此位置
3.递归将 [l,pos1] 排序,递归将 [pos+1,r] 排序

/*
    Author: Royecode
    Date: 2015-07-22
*/
//将数组升序排序
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <vector>
using namespace std;
//将l到r排好序
void quick_sort(int l, int r, int *arr)
{
    if(l < r)
    {
        int begin = l, end = r, val = arr[l];
        while(begin < end)
        {
            while(begin < end && arr[end] >= val) --end;     //将大于等于val的数放在右边
            if(begin < end) arr[begin] = arr[end];
            while(begin < end && arr[begin] < val) ++begin;  //将小于val的数放在左边
            if(begin < end)arr[end] = arr[begin];
        }
        arr[begin] = val;   
        //begin位置的数已确定,将[l, begin - 1]排序,将[begin + 1, r]排序 
        quick_sort(l, begin - 1, arr);
        quick_sort(begin + 1, r, arr);
    }
}
int main()
{
    srand(time(NULL));
    const int size = 8;
    int arr[size];
    for(int i = 0; i < size; ++i) //随机生成范围[0,size)的size个数
        arr[i] = rand() % size;
    for(int i = 0; i < size; ++i) //排序前
        cout << arr[i] << "\n"[i != size - 1];
    quick_sort(0, size - 1, arr);
    for(int i = 0; i < size; ++i) //排序后
        cout << arr[i] << "\n"[i != size - 1];
    return 0;
}

一般来说,快排的时间复杂度是 O(nlogn) ,但有时最坏的情况会退化到 O(n2) ,可以采取一定措施避免这一点,那就是在开始排序的时候,写一个函数将需要排序的数组打乱顺序。做法如下:

void disorderly(int *arr, int n)
{
    srand(time(NULL));
    for(int i = 0; i < n; ++i)
    {
        int x = rand() % n, y = rand() % n;//随机生成[0, n)的两个下标
        swap(arr[x], arr[y]);
    }
}

所以快排的时间复杂度是 O(nlogn) ,空间复杂度 O(1)

你可能感兴趣的:(快速排序,排序算法)