快速排序的基本思想是,首先选择记录中的一个记录,作为枢轴(可以理解为是临界值),通过一趟排序将待记录分成两部分,其中一部分的记录都比枢轴小,另一部分的记录都比枢轴大,再分别对这两部分记录以此方法继续排序,直到整个记录是有序的。这里用到了递归的思想。
假设我们有一组待排序的序列{3,1,5,2,4,6},选择第一个记录3作为枢轴,从数组的两端向中间比较,将大于枢轴的记录交换到右边,小于枢轴的记录交换到左边。
设置变量low=0从左边第一个记录开始记录数组下标,设置变量high=5从右边第一个(也就是数组的最后一个)记录下标。
设枢轴值pivotkey=a[low]=a[0]=3.遍历开始:
我们先从右边开始,0(low)<5(high),a[5]=6 > pivotkey=3,那么high--(减减),也就是向左移动high的值,high=4时,a[4]=4 > pivotkey=3,high接着减减,此时high=3,a[3]=2<pivotkey=3,那么将a[3]与a[low]=a[0]交换位置,将2换到左边的小数据集合中,那么记录变为{2,1,5,3,4,6}。
现在从左边开始,a[0]=2 < pivotkey=3,将low++,即向右边继续比较,low=1时,a[1]=1<pivotkey=3;
low接着加加,low=2,a[2]=5>pivotkey=3,那么将a[2]与a[high]=a[3]交换位置,记录变为{2,1,3,5,4,6}
此时low=2,high=3,继续判断a[3]=5>pivotkey=3,high--,变为high=2=low.则枢纽的位置即2.这样就将整个记录分为小数据集合{2,1}和大数据集合{5,4,6}。按照以上过程分别对这两个集合进行排序,直到所有记录有序为止。
代码如下,其中的swapValue函数是用来交换数组的两个元素的位置的。
void quickSort(int array[],int low,int high)
{
//定义枢轴值;
int pivot=0;
if(low<high)
{
/************************************************************************/
/*将数组一分为二,一部分是都小于枢轴值的,另一部分是都大于枢轴值的。同时返回枢轴的位置。*/
/************************************************************************/
pivot=partition(array,low,high);
//对小表递归排序
quickSort(array,low,pivot-1);
//对大表递归排序
quickSort(array,pivot+1,high);
}
}
int partition(int array[],int low,int high)
{
//用数组的第一个记录作为枢轴值
int pivotValue=array[low];
while (low<high)
{
//从右边向数组中间扫描
while (low<high && array[high]>=pivotValue)
{
high--;
}
//将右边小值记录交换到左边
swapValue(array,low,high);
//从左边向数组中间扫描
while (low<high && array[low]<pivotValue)
{
low++;
}
//将左边大值记录交换到右边
swapValue(array,low,high);
}
return low;
}
快速排序算法的平均时间复杂度为O(nlogn),最坏情况是O(n^2),是不稳定排序算法,适用于大数据量的排序。