C++实现快速排序和随机快速排序

1 快速排序

快速排序算法是由C.A.R. Hoare于1962年提出的;该算法使用了分而治之的策略(divide and conquer),它是一种"就地(in place)"算法,也即不需要额外的内存空间即可实现排序,这一点和insertion sort类似,但是不同于merge sort。该算法只需要做一些微调(fine tune)即可变得非常实用

1.1 分而治之

分:将数组沿着主元x(pivot x)分为左右两个子数组,且满足:左侧子数组的所有元素不大于x,右侧子数组的所有元素不小于x;
治:递归地对左右两个子数组进行排序;
合:无特殊操作

1.2 将数组划分为两个子数组的伪代码
C++实现快速排序和随机快速排序_第1张图片
1.3 将数组划分为两个子数组的示例:
C++实现快速排序和随机快速排序_第2张图片 C++实现快速排序和随机快速排序_第3张图片 C++实现快速排序和随机快速排序_第4张图片 C++实现快速排序和随机快速排序_第5张图片
1.4 快速排序伪代码
C++实现快速排序和随机快速排序_第6张图片
1.5 复杂度分析

最坏情况: θ ( n 2 ) {\theta(n^{2})} θ(n2)
最好情况: θ ( n l o g n ) {\theta(nlogn)} θ(nlogn)
平均情况: θ ( n l o g n ) {\theta(nlogn)} θ(nlogn)

2. 随机快速排序

区别于普通快速排序的地方是:主元随机选取,这样可以实现算法复杂度合输入序列的次序无关;

3. 代码

#include<iostream>
using namespace std;

template<typename T>
int partion(T arr[], int p, int q) { //数组作为函数参数
    T x = arr[p]; // 主元x
    int i = p; //初始情况,左侧子区间为空
    for (int j = p + 1; j <= q; j++) { //右侧子区间元素大于主元
        if (arr[j] < x) {
            i++;
            swap(arr[i], arr[j]);
         }
     }
     swap(arr[p], arr[i]); //最后交换arr[p]和arr[i]
     return i;
}

//随机产生一个主元索引
template<typename T>
int rand(T arr[], int p, int q) {
   int k = rand() % (q - p) + p; //随机产生索引
   swap(arr[k], arr[p]); //交换主元和rand
   return partion(arr, p, q);
}

template<typename T>
void quickSort(T arr[], int p, int r) {
   if (p < r) { //数组尚可划分
    //int q = partion(arr, p, r);
       int q = rand(arr, p, r);
       quickSort(arr, p, q - 1); //递归地对左侧子数组排序
       quickSort(arr, q + 1, r); //递归地对右侧子数组排序
    }
}

template<typename T>
void printArr(T arr[], int n) {
    for (int i = 0; i < n; i++) {
     cout << arr[i] << " ";
    }
    cout << endl;
}

int main() {
    int a[8] = { 6, 10, 13, 5, 8, 3, 2, 11 };
    cout << "排序前:" << endl;
    printArr(a, 8);

    cout << "排序后:" << endl;
    quickSort(a, 0, 7);
    printArr(a, 8);
    return 0;
}

你可能感兴趣的:(算法,c++)