排序--5--C++--快速排序
快速排序是对冒泡排序的一种改进。
时间复杂度:
- 最好:O(n log2 n)
- 最坏:O(n^2)
- 平均:O(n log2 n)
空间复杂度:O(log2 n)
稳定性:不稳定
快速排序的一次划分算法从两头交替搜索,直到low和hight重合,因此其时间复杂度是O(n);而整个快速排序算法的时间复杂度与划分的趟数有关。理想的情况是,每次划分所选择的中间数恰好将当前序列几乎等分,经过log2n趟划分,便可得到长度为1的子表。这样,整个算法的时间复杂度为O(nlog2 n)。快速排序需要一个栈空间来实现递归,快速排序的空间复杂度为O(log2n)。
它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。(来自百度)
实现原理:
1.设置两个变量 low、high,排序开始时:low=0,high=size-1。
2.2、整个数组找基准正确位置,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面
- 默认数组的第一个数为基准数据,赋值给key,即key=array[low]。
- 因为默认数组的第一个数为基准,所以从后面开始向前搜索(high–),找到第一个小于key的array[high],就将 array[high] 赋给 array[low],即 array[low] = array[high]。(循环条件是 array[high] >= key;结束时 array[high] < key)
- 此时从前面开始向后搜索(low++),找到第一个大于key的array[low],就将 array[low] 赋给 array[high],即 array[high] = array[low]。(循环条件是 array[low] <= key;结束时 array[low] > key)
- 循环 2-3 步骤,直到 low=high,该位置就是基准位置。
- 把基准数据赋给当前位置。
2.3、第一趟找到的基准位置,作为下一趟的分界点。
2.4、递归调用(recursive)分界点前和分界点后的子数组排序,重复2.2、2.3、2.4的步骤。
2.5、最终就会得到排序好的数组。
快速排序一次划分原理图:
C++代码实现:
#include <string>
#include <iostream>
using namespace std;
/*
* 快速排序
* 参数说明:
* a -- 待排序的数组
* l -- 数组的左边界(例如,从起始位置开始排序,则l=0)
* r -- 数组的右边界(例如,排序截至到数组末尾,则r=a.length-1)
*/
void quick_sort(vector<int>& vector1, int l, int r)
{
if (l < r)
{
int i, j, x;
i = l;
j = r;
x = vector1[i];
while (i < j)
{
while (i < j && vector1[j] > x)
j--; // 从右向左找第一个小于x的数
if (i < j)
vector1[i++] = vector1[j];
while (i < j && vector1[i] < x)
i++; // 从左向右找第一个大于x的数
if (i < j)
vector1[j--] = vector1[i];
}
vector1[i] = x;
quick_sort(vector1, l, i - 1); /* 递归调用 */
quick_sort(vector1, i + 1, r); /* 递归调用 */
}
}
int main()
{
vector<int> vector1;
int num;
int size = 5;
for (int i = 0; i < size;i++)
{ cin >> num;
vector1.push_back(num);
}
//xuanze_sort(vector1, size);
//maopao_sort(vector1, size);
//charu_sort(vector1, size);
//xier_sort(vector1, size);
quick_sort(vector1, 0,4);
for (int i = 0; i < size;i++)
{
cout << vector1[i] << " ";
}
cout << endl;
return 0;
}
编译结果: