QuickSort(快速排序)原理及C++代码实现

快速排序可以说是最重要的排序,其中延伸的思想和技巧非常值得我们学习。

快速排序也使用了分治的思想,原理如下:

分解:数组A[p..r]被划分为两个(可能为空)子数组A[p..q-1]和A[q+1..r],使得A[p..q-1]中的每一个元素都小于等于A[q],而A[q]也小于等于A[q+1..r]中的每个元素。其中计算下标q也是划分过程的一部分。

解决:通过递归调用快速排序,对子数组A[p..q-1]和A[q+1..r]进行排序。

合并:因为子数组都是原址排序的,所以不需要合并操作,数组A[p..r]已经有序。

只要划分不是极端的,那么快速排序的时间复杂度为O(nlgn),否则时间复杂度为θ(n2)。

可以利用随机化思想(随机选择主元)来使快速排序的期望时间复杂度达到O(nlgn)。

快速排序不是稳定排序。

代码如下:(仅供参考)

 1 int Partition(int * const begin, int * const end) { //lomuto划分
 2     int i = -1;
 3     for (int j = 0; j < (end - begin); ++j) {
 4         if (*(begin + j) <= *(end - 1)) {       //以最后一个值为关键值划分
 5             ++i;
 6             swap(*(begin + i), *(begin + j));
 7         }
 8     }
 9     return i;
10 }
11 
12 void QuickSort(int * const begin, int * const end) {
13     if (begin >= end - 1)
14         return ;
15     int mid = Partition(begin, end);
16     QuickSort(begin, begin + mid);    //调用的是lomute划分,因为lomuto划分结束以后
17     QuickSort(begin + mid + 1, end);  //mid一定在它应该在的位置
18 }
1 void QuickSort(int * begin, int * const end) {  //尾递归
2     while (begin < end - 1) {
3         int mid = Partition(begin, end);
4         QuickSort(begin, begin + mid);    //调用的是lomute划分
5         begin = begin + mid + 1;
6     }
7 }

另外一种划分方法:

 1 int Partition(int * const begin, int * const end) { //hoare划分
 2     int key = *begin;         //以第一个值为关键值划分
 3     int i = -1, j = end - begin;  //i, j根本不会越界
 4     while (1) {
 5         for (++i; *(begin + i) < key; ++i); //可看做do{}while;
 6         for (--j; *(begin + j) > key; --j);
 7         if (i < j)
 8             swap(*(begin + i), *(begin + j));
 9         else
10             return j;
11     }
12 }
13 
14 void QuickSort(int * const begin, int * const end) {
15     if (begin >= end - 1)
16         return ;
17     int mid = Partition(begin, end);
18 
19     QuickSort(begin, begin + mid + 1);   //调用hoare划分,因为hoare划分只能保证
20     QuickSort(begin + mid + 1, end);     //mid(包括mid)以前的元素小于等于mid以后的元素
21 }
posted @ 2020-01-14 19:09  简讯  阅读(760)  评论(0编辑  收藏  举报