基本思想
分治算法,Divide-and-conquer algorithms;
实现快速排序的主要步骤:
1、找到轴值,将其固定在第一位或者最后一位,用来比较。
2、分割以轴值为中间数的数组
3、分别递归轴值的左边和右边
第一种方法:取两端的数作为轴数;如:将最后一位数作为轴数,将数组分割。
int PartitionLast(std::vector< int > &arry,int left,int right)
{
int lindex=left,rindex=right;//left and right can't use immediately;
int pivot=arry[right];//将最后一个数作为轴数,临时保存
while(lindex!=rindex)
{
while(arry[lindex]<=pivot && lindex<rindex)
++lindex;
if(lindex<rindex)
arry[rindex--]=arry[lindex];
while(arry[rindex]>=pivot && rindex>lindex)
--rindex;
if(rindex>lindex)
arry[lindex++]=arry[rindex];
}
arry[lindex]=pivot;
return lindex;
}
第二种方法:随机取数,作为轴数。
int const PivotRand(std::vector< int > &arry, int left ,int right)
{
int randomIndex =rand()%(right-left)+left;//取数组中随机下标
return randomIndex;
}
第三种方法:取中间数。即获取数组第一位,中间位,最后一位,比较三者的大小,将三者中排在中间的数最为轴数。
int const PivotThree(std::vector< int > &arry,int left,int right)
{
int middle=(right+left)/2;
if(arry[left]>arry[right])
std::swap(arry[left],arry[right]);
if(arry[middle]>arry[right])
middle=right;
else if(arry[middle]<arry[left])
middle=left;
return middle;
}
以下是实现三种方法的源代码,IDE为CodeBlocks;
#include<iostream>
#include <vector>
#include<stdio.h>
#include <algorithm>
//No1 固定基准元
int PartitionLast(std::vector< int > &arry,int left,int right)
{
int lindex=left,rindex=right;//left and right can't use immediately;
int pivot=arry[right];
while(lindex!=rindex)
{
while(arry[lindex]<=pivot && lindex<rindex)
++lindex;
if(lindex<rindex)
arry[rindex--]=arry[lindex];
while(arry[rindex]>=pivot && rindex>lindex)
--rindex;
if(rindex>lindex)
arry[lindex++]=arry[rindex];
}
arry[lindex]=pivot;
return lindex;
}
//No.2随机取基准元
int const PivotRand(std::vector< int > &arry, int left ,int right)
{
int randomIndex =rand()%(right-left)+left;//取数组中随机下标
return randomIndex;
}
int PartitionRand(std::vector< int > &arry,int left,int right)
{
int const index=PivotRand(arry,left,right);
std::swap(arry[index],arry[right]);
int const pivot=arry[right];
int lindex=left,rindex=right;
while(lindex!=rindex)
{
while(arry[lindex]<=pivot && lindex<rindex)
++lindex;
if(lindex<rindex)
arry[rindex--]=arry[lindex];
while(arry[rindex]>=pivot && rindex>lindex)
--rindex;
if(rindex>lindex)
arry[lindex++]=arry[rindex];
}
arry[lindex]=pivot;
return lindex;
}
//No.3三数取中
int const PivotThree(std::vector< int > &arry,int left,int right)
{
int middle=(right+left)/2;
if(arry[left]>arry[right])
std::swap(arry[left],arry[right]);
if(arry[middle]>arry[right])
middle=right;
else if(arry[middle]<arry[left])
middle=left;
return middle;
}
int PartitionMiddle(std::vector< int > &arry,int left,int right)
{
int const index=PivotThree(arry,left,right);
std::swap(arry[index],arry[right]);
int const pivot=arry[right];
int lindex=left,rindex=right;
while(lindex!=rindex)
{
while(arry[lindex]<=pivot && lindex<rindex)
++lindex;
if(lindex<rindex)
arry[rindex--]=arry[lindex];
while(arry[rindex]>=pivot && rindex>lindex)
--rindex;
if(rindex>lindex)
arry[lindex++]=arry[rindex];
}
arry[lindex]=pivot;
return lindex;
}
void QuickSort(std::vector< int > &arry,int left,int right)
{
if(right<=left)
return;
//int pivot=PartitionLast(arry,left,right);
//int pivot=PartitionMiddle(arry,left,right);//分别实现
int pivot=PartitionRand(arry,left,right);
QuickSort(arry,left,pivot-1);
QuickSort(arry,pivot+1,right);
}
int main()
{
std::vector< int > arry{2,4,7,8,9,10,11,12,23,1};
int left=0;
int right=arry.size()-1;
QuickSort(arry,left,right);
for(auto i:arry)
std::cout<<i<<" ";
return 0;
}
下面这个链接有更详细的解说:三种快速排序算法以及快速排序的优化