C++排序算法之快速排序

来源:互联网 发布:怎么搜索网络的打印机 编辑:程序博客网 时间:2024/06/12 21:26
快速排序算法

快速排序是实际中最常用的一种排序算法,速度快,效率高。

思想:快速排序采用的是分治的思想
(1)在待排序的元素中任取一个元素作为基准(通常选第一个元素,但是最好的选择方法是从待排元素中随机选取一个作为基准),成为基准元素;
(2)将待排的元素进行分区,比基准元素大的元素放在它的右边,比它小的元素放在左边;
(3)对左右两个分区重复以上步骤直到所有的元素都是有序的。

下面举例说明一下:
原始待排序列:3  6  4  2  1  8  5  7
选择第一个元素3作为基准元素,然后设置两个指针 i(绿色) 和 j(红色) 分别指向第一个元素和最后一个元素,然后开始从两边扫描,把比3大的元素和比3小的元素分开。
(1)首先比较3和7,3<7,j 向左移动: 3  6  4  2  1  8  5  7
(2)比较3和5,3<5,j 继续向左移动: 3  6  4  2  1  8  5  7
(3)比较3和8,3<8,j 继续向左移动: 3  6  4  2  1 8  5  7
(4)比较3和1,3>1,把1放在i的位置,此时从i+1处开始向右进行扫描: 1  6  4  2  1 8  5  7
(5)比较3和6,3<6,把6放在j的位置,此时从j-1处开始向左进行扫描:  1  6  4  2  6 8  5  7
(6)比较3和2,3>2,把2放在i的位置,此时从i+1处开始向右进行扫描: 1  2  4  2  6 8  5  7
(7)比较3和4,3<4,把4放在j的位置,此时从j-1处开始向左进行扫描:  1  2  4  4  6 8  5  7
由于此时不满足j>i的循环条件,循环结束,
(8)将基准元素放在i的位置上: 1  2  3  4  6 8  5  7
经过第一轮的快速排序之后,元素变为 [1  2] 3 [4  6  8  5  7]
(9)之后,递归的对3左半部分的元素和右半部分的元素进行快速排序,生成最终的排序结果。

代码实现如下:
#include <iostream>#include <vector>using namespace std;//快速排序法时间复杂度,最好情况下O(nlog2(n)),最坏为O(n*n),平均为O(nlog2(n));空间复杂度为O(log2(n)),递归排序,需要栈辅助。//序列越无序,算法效率越高,越有序,算法效率越低void QickSort(vector<int> &R, int l, int r)                //对从R[l]-R[r]的元素进行排序{int temp;int i = l;int j = r;if (l < r){temp = R[l];//下面的循环完成一次排序,即以第一个元素为轴,将大于temp的元素放在右边,小于temp的元素放在左边while (i < j){while (j > i&&R[j] > temp)                  //从右往左扫描到第一个小于temp的元素j--;if (j > i){R[i] = R[j];                                       //放在temp左边++i;}while (i < j&&R[i] < temp)                //从左往右扫描到第一个大于temp的元素++i;if (i < j){R[j] = R[i];                                      //放在temp的右边--j;}}R[i] = temp;    //将temp放在最终的位置上QickSort(R, 1, i - 1);                              //递归地对temp左边的元素排序QickSort(R, i + 1, r);                             //递归地对temp右边的元素排序}}void main(){vector<int> R = { 3,  6,  4,  2,  1,  8,  5,  7 };QickSort(R, 0, R.size() - 1);for (auto x: R)cout << x << " ";cout << endl;}

运行结果如下:



复杂度分析:
(1)时间复杂度
最好情况下的时间复杂度为O(nlogn),待排序列越接近无序,本算法的效率越高。
最坏情况下的时间复杂度为O(n^2),待排序列越接近有序,本算法效率越低。
平均时间复杂度为O(nlogn)。就平均时间而言,快速排序是所有排序算法中最好的。
(2)空间复杂度
空间复杂度为O(logn)。因为快速排序是递归排序,递归需要栈的辅助。

扩展:快速排序算法当序列中元素的排列比较随机时效率最高,但是当序列种元素接近有序时,会达到最坏的时间复杂度O(n^2),产生这种情况的主要原因在于基准元素的选择没有把当前区间划分为两个长度接近的子区间。有什么办法能解决这个问题呢???其中一个办法就是随机选择一个元素最为基准元素,这样虽然算法的最坏时间复杂度仍然是O(n^2),但是对任意输入数据的期望时间复杂度都能达到O(nlogn),也就是说,不存在一组特定的数据能使这个算法出现最坏情况。
原创粉丝点击