就是利用分治的思想将大问题分成小问题解决。
首先随便找一个作为标准(为方便每次以左边第一个为标准),将所有比他大的移到其右边,比他小的移到其左边,然后将其左边的和右边的所有数作为整体递归执行同样的操作,直到要执行的整体为一;
例如要排序的数为:44,71,28,61,37,29;
第一次以基准值:temp=44为标准经过移动得:29 ,37,28,44,61,71;
然后再分别对29,37,28和61,67排序;
对29,37,28以29为标准经过移动得28,29,37,
对61,71以61为标准经过移动得61,71;
此时在细分的到的整体为28和37还有71都是一个数,
顾不需再排序可得28,28,37,44,61,71;
具体实现:
用两个指针i,j分别指在要排序的一串数的起点和终点;每一次先从右往左移动指针j寻找第一个小于基准值temp的数移动到i所在位置并将i向右移动一个位置,再从左往右寻找第一个大于基准值temp的值移到j所在位置并将j向左移动一格;重复操作直到I与j重合;具体操作看代码,以下用随机数测试:
#include<iostream>
using namespace std;
#include<cstdlib>
#include<ctime>
#define MAX 100
int p[100],n;
void quick_sort(int left,int right)
{
if(left<right)//若要排序的整体数量不止一个,则进行以下排序
{
int i=left,j=right,x=p[left];//x为分类的基准数
while(i<j)
{
while(i<j&&p[j]>=x)j--;//从右往左寻找第一个小于x的数
if(i<j)p[i++]=p[j];//移到i所在位置
while(i<j&&p[i]<x)i++;//从左往右找第一个大于x的数
if(i<j)p[j--]=p[i];//移到j所在位置
}
p[i]=x;//基准数所在位置
quick_sort(left,i-1);//对基准数左边的进行排序
quick_sort(i+1,right);// 对基准数右边的进行排序
}
}
int main()
{
int i;
while(cin>>n)
{
srand(time(0));
for(i=0;i<n;i++)
{
p[i]=rand()%MAX+1;//随机数进行赋值
if(i==0)cout<<p[i];
else cout<<' '<<p[i];
}
cout<<endl;
quick_sort(0,n-1);
for(i=0;i<n;i++)cout<<p[i]<<' ';
cout<<endl;
}
}
快速排序的改进
1.只对长度大于k的子序列递归调用快速排序,让原序列基本有序,然后再对整个基本有序序列用插入排序算法排序。
2.快速排序是通常被认为在同数量级(O(nlog2n))的排序方法中平均性能最好的。但若初始序列按关键码有序或基本有序时,快排序反而蜕化为冒泡排序。为改进之,通常以“三者取中法”来选取基准记录,即将排序区间的两个端点与中点三个记录关键码居中的调整为支点记录。快速排序是一个不稳定的排序方法。