数据结构-排序-快排
快速排序
首先快速排序步骤:
- 首先选择轴值
- 把待排序内容分为两部分,左边为小于或者等于轴值,右边为大于轴值
- 然后对左右重复上面步骤直到整个序列有序
- 直接上代码这里先写一次划分的代码
- 这里的一次划分是那第一个数字为轴值,我们也可以用最后一个或者中间的。
-
#include<iostream> #include<vector> using namespace std; //不含暂存单元的数组v1 int temp1[]={59,20,17,36,98,14,23,83,13,28}; vector<int> v1(begin(temp1),end(temp1)); //打印数组 inline void printV(const vector<int> &v) { for(auto a:v) cout<<a<<" "; cout<<endl; } //第一次划分 //快速排序第一次划分 int Partition(vector<int> &v,int first,int end) { int i=first; int j=end; printV(v); cout<<"此时i="<<i<<" 此时j="<<j<<" "; while(i<j) { while(i<j&&v[i]<v[j]) {j--; cout<<"此时i="<<i<<" 此时j="<<j<<endl;} if(i<j)//假如i<j 交换ij { cout<<"交换"<<" "; int temp=v[j]; v[j]=v[i]; v[i]=temp; i++; printV(v); cout<<"此时i="<<i<<" 此时j="<<j<<" "; } cout<<endl; while(i<j&&v[i]<=v[j]) { i++; cout<<"此时i="<<i<<" 此时j="<<j<<endl;} if(i<j) { cout<<"交换"<<" "; int temp=v[j]; v[j]=v[i]; v[i]=temp; j--; printV(v); cout<<"此时i="<<i<<" 此时j="<<j<<" "; } } printV(v); return i; } //这里我们先直接调用一次划分理解下如何划分的 int main(int argc, char *argv[]) { Partition(v1,0,v1.size()-1); return 0; }
然后上运行截图分析
- 首先取59为轴值,然后因为要左边比59小,右边比59大
- 59与28比较发现59大于28 交换
- 交换后继续遍历左侧。于是i++,遍历到98发现59小了,交换
- 然后此时左边必然都小于59,但是右边不确定,开始遍历J
- J=8发现13小于59然后再次交换,然后右边必然大于59,左边不确定,继续遍历i
- i=7时59<83交换
- 这是i=j不满足i<j的条件跳出循环
- 此时以59为轴值,左边都小于59右边都大于
接下来就是完整的包含递归的快排了
先上代码
#include<iostream> #include<vector> using namespace std; //不含暂存单元的数组v1 int temp1[]={59,20,17,36,98,14,23,83,13,28}; vector<int> v1(begin(temp1),end(temp1)); //打印数组 inline void printV(const vector<int> &v) { for(auto a:v) cout<<a<<" "; cout<<endl; } //快速排序一次划分 int Partition(vector<int> &v,int first,int end) { int i=first; int j=end; printV(v); cout<<"此时i="<<i<<" 此时j="<<j<<" "; while(i<j) { while(i<j&&v[i]<v[j]) {j--; cout<<"此时i="<<i<<" 此时j="<<j<<endl;} if(i<j)//假如i<j 交换ij { cout<<"交换"<<" "; int temp=v[j]; v[j]=v[i]; v[i]=temp; i++; printV(v); cout<<"此时i="<<i<<" 此时j="<<j<<" "; } cout<<endl; while(i<j&&v[i]<=v[j]) { i++; cout<<"此时i="<<i<<" 此时j="<<j<<endl;} if(i<j) { cout<<"交换"<<" "; int temp=v[j]; v[j]=v[i]; v[i]=temp; j--; printV(v); cout<<"此时i="<<i<<" 此时j="<<j<<" "; } } printV(v); cout<<"一次part结束"<<endl; return i; } //快排 void QuickSort(vector<int> &v,int first,int end) { if(first<end) { int pivot=Partition(v,first,end); QuickSort(v,first,pivot-1);; QuickSort(v,pivot+1,end); } } int main(int argc, char *argv[]) { QuickSort(v1,0,v1.size()-1); return 0; }
- 我们先看下QuickSort函数,当partition函数返回i,i就是刚才59的位置
- 我们此时以59为分界线,分为左右两侧,分别对左右继续划分,直到所有的每次递归first-end的范围的数量=1则跳出
- 看下下面的递归第一次partition调用结束后,QuickSort后面的参数是v,,first,i的位置-1 比如第一次递归就是 v[0]到59的位置减1
- 然后后面的就是59+1到v.end();
- 我们运行程序看下
-
这是不停的对左侧左侧左侧的递归
-
这是不停的对右侧右侧递归。由于右侧数字很少,递归也很快结束了。
转载请标明出处