#include <vector>
#include <iostream>
using namespace std;
/*快速排序的思路是:
定一个base基准点比如a[0]位置的值,然后在序列头和序列尾巴分别放一个路标,分别从尾到头和从左到右遍历,分别把大于base值的值和小于base值的值放在base值的右边和左边
然后在通过递归的方式对左边和右边进行处理。*/
void QuickSort(vector<int> &a, int low, int high)//必须传引用,否则出错,因为vector是一个类对象
{
if( low > high)/*这里需要做判断。目的是防止前后过度遍历*/
return;
int l = low;/*一个左指针从左往右遍历,一旦遇得大于base值的元素停止遍历*/
int r = high;/*一个右指针从尾往左遍历,一旦遇到小雨base的元素停止遍历等待数据交换*/
int base= a[low];//记录base值
while (l < r)/*最大让两个指针碰到,不能超过分界线遍历*/
{
/*如果遍历的数据本身大于base值,则继续遍历,否则遇到的是小于base值的,此时循环停止,继续遍历前半部分
特别注意的是:一定要先d扫面后面部分,在扫描前半部分,不能把顺序反了。*/
while (a[r] >= base&& l < r) /*这一定要>=,不能忘记=*/
r--;
/*退出循环则说明在尾巴上找到了小于Base的值*/
/*如果遍历的数据本身小于base值,则继续遍历,否则遇到的是大于base值的,此时循环停止*/
while (a[l] <= base && l < r)/*这一定要<=,不能忘记=*/
l++;
/*退出循环则说明在前半部分上找到了大于Base的值*/
/*交换找到的这两个值的位置关系*/
swap(a[l],a[r]);
/*这一轮结束,然后在l<r过程中继续遍历下一轮找到左右两边所有的小于大于base的值,并且放在base的左边部分和右边部分*/
}
/*运行到这里则说明l和r碰头(也就是l一定等于r)了,则退出遍历,此时l对应的元素一定是小于base值的,因此此时将这个l对应的数据和base值(a[low])交换位置
此时就把这个数列以base为基准值,左边放的是小于base的值,右边放的是大于Base的值,然后在对左右两边进行递归最终就可以把序列转换成
一个有序序列*/
swap(a[low], a[l]);
QuickSort(a, low, l-1);
QuickSort(a, r + 1, high);/*这里写成l+1也行的*/
}
int main()
{
vector<int > a;
a.push_back(5);
a.push_back(4);
a.push_back(8);
a.push_back(2);
a.push_back(7);
a.push_back(9);
a.push_back(3);
a.push_back(1);
for(auto &t:a){
cout<<t<<" ";
}
cout<<endl;
QuickSort(a, 0, a.size()-1);
for(auto &t:a){
cout<<t<<" ";
}
cout<<endl;
}
/*还有一种方法就是不选择数组的第一个数为哨兵数,而是任意选择一个值。此时就不需要要求遍历是需要冲尾巴开始了,而是可以从左到右也可以从右到左,任意开始遍历。但是有一个地方需要注意的就是递归时候的区间,需要按照0-->r和l->end的方式,而不是0->l-1和l+1->r的方式,这里需要注意。*/
void QuickSort(vector<int> &nums, int start, int end){
if(start >= end){ /*因为有递归运算,所以需要有退出条件*/
return ;
}
int l = start;
int r = end;
int key =nums[start];/*任意找一个点点的数据,可以是任意的点,这里随便写了一个start点*/
while(l<r){/*从头开始遍历,从左到右找到比keyd大的数据停下,从右找比key小的数据,然后两个交换位置。*/
while(nums[l] < key&& l<=r){/*从左到右找大于key的数据*/
l++;
}
while(nums[r] > key&& l<=r){/*从右到d左找小于key的数据*/
r--;
}
/*找到则交换,但需要实在左边小于等于右边的情况下才交换,同时交换后为了继续找下一对,s需要l和r继续增加和减少*/
if(l <= r){/*最终交汇处就是等于,所以需要等于*/
swap(nums[r],nums[l]);
l++;/*这里要继续增加或者减少*/
r--;/*这里要继续增加或者减少*/
}
}
/*注意走到这里r和l不一定相等,而且还存在r在l的左边,甚至r=-1的可能*/
QuickSort(nums,start,r); /*这里为什么不是l-1和l+1*/
QuickSort(nums,l,end);
}
C++快速排序方法
最新推荐文章于 2024-07-22 14:00:00 发布