一、 快速排序
思想:自上而下的分治法。对于区间 [ l , r ] [l,r] [l,r],一般选择 n u m s [ l ] nums[l] nums[l]作为标兵pivot,经过一轮排序,比pivot大的都在pivot右边,比pivot小的都在pivot左边。接下来分别对 [ l . p i v o t P o s − 1 ] [l.pivotPos-1] [l.pivotPos−1], [ p i v o t P o s + 1 ] [pivotPos+1] [pivotPos+1]进行快排。
实际上,pivot相当于对标兵元素进行了暂存,因此标兵元素对应位置相当于为空,可以被其他元素直接覆盖。
例: n u m s = [ 51 , 46 , 18 , 43 , 32 , 112 , 41 , 84 , 53 , 2 , 15 ] nums=[51,46,18,43,32,112,41,84,53,2,15] nums=[51,46,18,43,32,112,41,84,53,2,15]
class SortMethods{
public:
// 双函数递归版本
void quickSort(vector<int> &nums,int l,int r){
if(r-l<=0)return ;
int pivotPos=quickSort_findPivotPos(nums,l,r);
quickSort(nums,l,pivotPos-1);
quickSort(nums,pivotPos+1,r);
}
int quickSort_findPivotPos(vector<int> &nums,int l,int r){
int pivot=nums[l];
while(l<r){
while(l<r && pivot<=nums[r])--r;
nums[l]=nums[r];
while(l<r&& pivot>=nums[l])++l;
nums[r]=nums[l];
}
nums[l]=pivot;
return l;
}
//单函数递归版本
void quickSort2(vector<int> &nums,int l,int r){
if(l>=r)return ;
int i=l,j=r;
int pivot=nums[i];
while(i<j){
while(i<j&&pivot<=nums[j])--j;
nums[i]=nums[j];
while(i<j&&pivot>=nums[i])++i;
nums[j]=nums[i];
}
nums[i]=pivot;
quickSort2(nums,l,i-1);
quickSort2(nums,i+1,r);
}
//迭代版 借助栈对[l.r]进行存储,模拟函数调用
//迭代版
void quickSort3(vector<int> &nums,int l,int r){
if(l>=r)return ;
stack<pair<int,int>> stk;
stk.push(pair<int,int>(l,r));
while(!stk.empty()){
auto pa=stk.top();
stk.pop();
//int l=pa.first,r=pa.second;
//int i=l,j=r;
int l,r,i,j;
tie(l,r)=pa;
tie(i,j)=pa;
int pivot=nums[i];
while(i<j){
while(i<j&&pivot<=nums[j])--j;
nums[i]=nums[j];
while(i<j&&pivot>=nums[i])++i;
nums[j]=nums[i];
}
nums[i]=pivot;
//仅存储可行区间,与递归版的if(l>=r)return ;功能对应
if(l<i-1)stk.push(make_pair(l,i-1));
if(i+1<r)stk.push(make_pair(i+1,r));
}
}
};
// int main() {
// vector<int> nums={51,46,18,43,32,112,41,84,53,2,15};
// cout<<"排序前:";
// for(auto val:nums)cout<<val<<",";
// cout<<endl;
// SortMethods s;
// s.quickSort(nums,0,nums.size()-1);
// cout<<"排序后:";
// for(auto val:nums)cout<<val<<",";
// cout<<endl;
// }
二、归并排序
思想:自底而上的分治思想。
class SortMethods{
public:
//归并排序 递归
void mergeSort(vector<int> &nums,int l,int r){
if(l>=r) return;
int mid=l+(r-l)/2;
mergeSort(nums,l,mid);//递归的“递”,分治
mergeSort(nums,mid+1,r);//递归的“递”,分治
vector<int> tmp(nums.begin()+l,nums.begin()+r+1);
int i=0,j=mid+1-l;//注意:i,j用于索引tmp,[0,r-l],k用于索引nums,[l,r]
int len=r-l;
int k=l;
while(i<=mid-l && j<=len){
if(tmp[i]<=tmp[j]){
nums[k++]=tmp[i++];
}else{
nums[k++]=tmp[j++];
}
}
while(i<=mid)nums[k++]=tmp[i++];
while(j<=len)nums[k++]=tmp[j++];
}
};
// int main() {
// vector<int> nums={51,46,18,43,32,112,41,84,53,2,15};
// cout<<"排序前:";
// for(auto val:nums)cout<<val<<",";
// cout<<endl;
// SortMethods s;
// s.mergeSort(nums,0,nums.size()-1);
// cout<<"排序后:";
// for(auto val:nums)cout<<val<<",";
// cout<<endl;
// }
三、堆排序
- 使用C++ make_heap(v.begin(),v.end(),less< int >() );将序列容器中的元素建立为大顶堆;
- 每次使用pop_heap(v.begin(),v.end()-i,less< int >() ),将堆顶元素调整到当前堆的末尾;
(C++ 堆的原理 可参考: https://mp.weixin.qq.com/s/U9sJqvxvCGuwVZrdA-0PKQ )
class SortMethods{
public:
void heapSort(vector<int> & nums){
if(nums.size()<=0)return ;
make_heap(nums.begin(),nums.end(),less<int>());
int i=0;
while(i<nums.size()){
pop_heap(nums.begin(),nums.end()-i,less<int>());
++i;
}
}
};
// int main() {
// vector<int> nums={51,46,18,43,32,112,41,84,53,2,15};
// cout<<"排序前:";
// for(auto val:nums)cout<<val<<",";
// cout<<endl;
// SortMethods s;
// // s.quickSort(nums,0,nums.size()-1);
// // s.mergeSort(nums,0,nums.size()-1);
// s.heapSort(nums);
// cout<<"排序后:";
// for(auto val:nums)cout<<val<<",";
// cout<<endl;
// }
四、冒泡排序(优化)
思想 每轮中每步调整两个相邻元素的顺序,每轮保证最大元素排在末尾
class SortMethods{
public:
//bubble sort with optimization
void bubbleSort(vector<int> &nums){
if(nums.size()<=1)return ;
for(int i=0;i<nums.size()-1;++i){
bool isSorted=true;//每轮设置flag,如果剩余元素均为有序,跳出i的循环
for(int j=i+1;j<nums.size();++j){
if(nums[i]>nums[j]){
swap(nums[i],nums[j]);
isSorted=false;
}
}
if(isSorted)break;
}
}
};
int main() {
vector<int> nums={51,46,18,43,32,112,41,84,53,2,15};
cout<<"排序前:";
for(auto val:nums)cout<<val<<",";
cout<<endl;
SortMethods s;
// s.quickSort(nums,0,nums.size()-1);
// s.mergeSort(nums,0,nums.size()-1);
// s.heapSort(nums);
s.bubbleSort(nums);
cout<<"排序后:";
for(auto val:nums)cout<<val<<",";
cout<<endl;
}