时间复杂度:最差是有序的时候 O( n^2), O(nlog(n))
空间复杂度:O(logN)
稳定性:不稳定
核心思想:选择一个基准元素,通常选择第一个元素或者最后一个元素;
通过一趟排序讲待排序的记录分割成独立的两部分,其中一部分记录的元素值均比基准元素值小。另一部分记录的 元素值比基准值大;
此时基准元素在其排好序后的正确位置;
然后分别对这两部分记录用同样的方法继续进行排序,直到整个序列有序。
三色旗问题:
有一个数组只由0,1,2三种元素构成的整数数组,请使用交换、原地排序而不
是使用计数进行排序。
解题思路(文字):
1.定义两个变量,i和j(下标),从index =0开始遍历
2.如果a[index]==0, swap(a[index++], a[++i]);(这里index++的原因是,index左边不可能有==2的数据了);
3.如果a[index]==1, index++;
4.如果a[index]==2,swap(a[index],a[--]);(这里没有index++,是因为在右侧不知道交换过来的数据是大于1还是小于1还是等于1)
5.i的含义: <=i的部分都是比1小的,所以i 的初值== -1
6.j的含义: >=j的部分都是比1大的,所以j的初值==n
例如: vector<int> vec= {1,2,0,1,2,0,1,2,1,0];
解题思路(图像):
代码实现:
#include<iostream>
using namespace std;
#include<vector>
void Quick_Sort(vector<int> &vec, int L, int R)
{
int i = L - 1;
int j = R + 1;
int index = L;
int temp = 1;
while (index < j)
{
if (vec[index] < temp) swap(vec[++i], vec[index++]);
else if (vec[index] == temp) index++;
else swap(vec[index], vec[--j]);
}
}
int main()
{
vector<int> vec = { 1,2,0,1,2,0,1,2,1,0 };
Quick_Sort(vec, 0, vec.size() - 1);
for (auto it : vec) //增强for循环
{
cout << it << " ";
}
}
快排思想:
第一步(即三色旗问题):
找一个基准值(这里选取待排序数组最左边的那个值),然后将待排序数组分成三部分
第一部分:数据全都小于基准值
第二部分:数据全都等于基准值 第三部分:数据全都大于基准值
第二步:
将第一部分和第三部分分别进行三色旗问题处理,直至i>=j
解题思路(图像):
代码实现:
#include<iostream>
using namespace std;
#include<vector>
pair<int,int> Quick(vector<int> &vec, int L, int R)
{
int temp = vec[L];//基准值
int i = L - 1;
int j = R + 1;
int index = L;
while (index < j)
{
if (vec[index] < temp)
{
swap(vec[++i], vec[index++]);
}
else if (vec[index] == temp)
{
index++;
}
else
{
swap(vec[index], vec[--j]);
}
}
return make_pair(i, j);
}
void Quick_Sort(vector<int> &vec, int L, int R)
{
if (L >= R) return;
pair<int, int> p = Quick(vec, L, R);//p接收了基准值左边的结束位置和基准值右边的起始位置
Quick_Sort(vec, L, p.first);
Quick_Sort(vec, p.second,R);
}
int main()
{
vector<int> vec = { 5,4,2,5,6,8,1,0,9 };
Quick_Sort(vec, 0, vec.size() - 1);
for (auto it : vec) //增强for循环
{
cout << it << " ";
}
return 0;
}