本文以原地排序实现升序排序。
基本思路
身高排队为例:找一个人为基准,比他高的站右边,比他矮的站左边。
左边一队和右边一队,再重复以上操作,直到划分队伍剩下一个人即不需要排序的状态。
分析
根据以上思路可以分成两个步骤:
1】根据基准划分成为左右两队
2】左右两队重复1】的操作。
划分实现
1】原地排序思路:
1、借助一个临时变量,记住基准值flag,比flag小的可以直接放在flag的位置。
2、此时这个比flag小数的原位置就可以充当下一次交换的目标位置。
2】如何调整比flag大或者小的位置:
1、以队伍1号为flag,从 n号 往回找第一个小于flag的数据x,把x放到1号。
2、从1号往n号方向找第一个大于flag的数据 k。把k放在x原来的位置。
3、当两个方向相遇则结束划分。
int patition(vector<int>&vec,unsigned low,unsigned high){
int flag=vec[low];//基准
while(low<high) {
while(low<high&&flag<=vec[high])
--high;
vec[low]=vec[high];
while(low<high&&flag>=vec[low])
++low;
vec[high]=vec[low];
}
vec[low]=flag;
return low;
}
重复划分
思路:可以看见在划分函数patition()返回了flag的位置。以这个位置划分成的左右两队
重复执行
void Qsort(vector<int>&vec,unsigned low,unsigned high){
if(low>=high)return;//当长度等于1时。跳出
int loc=patition(vec,low,high);//一次划分得到的flag的位置
Qsort(vec,low,loc-1);
Qsort(vec,loc+1,high);
}
附录完整代码及测试
#include<iostream>
#include<vector>
using namespace std;
int patition(vector<int>&vec,unsigned low,unsigned high){
int flag=vec[low];
while(low<high) {
while(low<high&&flag<=vec[high])
--high;
vec[low]=vec[high];
while(low<high&&flag>=vec[low])
++low;
vec[high]=vec[low];
}
vec[low]=flag;
return low;
}
void Qsort(vector<int>&vec,unsigned low,unsigned high){
if(low>=high)return;
int loc=patition(vec,low,high);
Qsort(vec,low,loc-1);
Qsort(vec,loc+1,high);
}
int main(){
vector<int>vec={5,6,4,2,7,8,4,3,5,44,55,66,22,44,52};
Qsort(vec,0,14);
for(int i: vec)
cout<<i<<" ";
cout<<endl;
}