1、快速排序
引例:三色旗思想:
问题描述:
有一个只由 0,1,2 三种元素构成整数数组,请使用交换、原地排序而不是使用计数进行排序
解题思路:
定义两个下标 left 和 right;
left 的含义:使数组中下标 <=left 的部分都比 1 小,left 的初始值为 -1;
right 的含义:使数组中下标 >=right 的部分都比 1 大,right 的初始值为 n;
从index = 0 开始遍历;
根据 index 所指向的值分别进行不同的操作;
如果 vec[index] = 0,swap(vec[index++],vec[++left];
(这里 index++ 的原因是 index 左边不可能有 ==2 的数据了)
如果 vec[index] = 1,index++;
如果 vec[index] = 2,swap[vec[index],vec[--right]);
代码实现:
以 {0,1,2,0,0,1,2,1,0} 为例:
#include<iostream>
#include<vector>
using namespace std;
void Quick(vector<int>&vec,int L,int R){
int left = L - 1;
int right = R + 1;
int temp = 1;
int index = 0;
while(index < right){
if(vec[index] == temp){
index++;
}
else if(vec[index] < temp){
swap(vec[index++],vec[++left]);
}
else {
swap(vec[index], vec[--right]);
}
}
}
int main(){
vector<int>vec = {0,1,2,0,0,1,2,1,0};
Quick(vec,0,vec.size()-1);
for(auto it : vec){
cout<<it<<" ";
}
return 0;
}
思想:
1)三色旗问题:找一个基准值(这里选取待排序数组最左边的那个值),然后将待排序数组分为三部分;
第一部分:数据全部小于基准值
第二部分:数据全部等于基准值
第三部分:数据全部大于基准值
2)将第一部分和第三部分分别进行三色旗问题处理,直到 index >= j, 即数组有序
#include<iostream>
#include<vector>
using namespace std;
pair<int,int> Quick(vector<int>& vec, int L, int R) {
int i = L - 1;
int j = R + 1;
int temp = vec[L];
int index = L;
while (index < j) {
if (vec[index] > temp) {
swap(vec[index], vec[--j]);
}
else if (vec[index] < temp) {
swap(vec[index++], vec[++i]);
}
else {
index++;
}
}
return make_pair(i, j);
}
void quickSort(vector<int>& vec, int L, int R) {
if (L >= R)return;
pair<int, int>p = Quick(vec, L, R);
quickSort(vec, L, p.first);
quickSort(vec, p.second, R);
}
int main() {
vector<int>vec = { 0,1,2,0,0,1,2,1,0 };
quickSort(vec, 0, vec.size() - 1);
for (auto it : vec) {
cout << it << " ";
}
return 0;
}
平均时间复杂度:O(n*logn)
稳定性:不稳定 实例 5 7 7 1 1