1.基本思想
先从数列中选取一个数为基准数;
把所有大于基准数的数放在基准数的右边,小于基准数的放在左边;
对上面的数列以上个基准数为轴,分别对左右两个数列再次递归调用函数选择新的基准数继续比较;
2.算法实现
#include<stdio.h>
int quick(int arry[],int left,int right)
{
int key = arry[left]; //取数组的第一个值作为基准数
int l = left; //l和r的作用是指针
int r = right;
int temp;
if(l < r)
{
while(l != r) //l和r不相遇时
{
//先从右边找,直到找到比基准数小的值,指针r停止移动,再从左边找
while(arry[r] >= key && l < r)
r--;
//从左边开始找时,当指针l所指的值大于基准数时停止移动指针
while(arry[l] <= key && l < r)
l++;
if(l < r)
{
temp = arry[l];
arry[l] = arry[r];
arry[r] = temp;
}
}
arry[left] = arry[l];
arry[l] = key; //当相遇时则执行本句,即将key值与两指针共同所指的值互换位置
//此时这组数的基准数key以右都是比key大的,以左都是比key小的
quick(arry,left,l-1); //递归,将key左边的数继续以最左边的数为基准排序
quick(arry,l+1,right); //将key右边的数继续以最左边的数为基准排序
}
return *arry;
}
int main()
{
int i;
int arry[6] = {4,2,6,3,7,5};
quick(arry,0,5);
for(i = 0;i < 6;i++)
printf("%d",arry[i]);
}
3.算法分析
在本算法中,每次选取的基准数都是数列中最左侧的数,通常选取首元素或最后一个元素作为基准数;
最优情况是数列分布较为均匀时,这个意思就是在进行第一趟排序后,第一次选取的基准数正好在数列的中心位置,这样就把数列均匀的分布成了两个元素个数相当的数列。若排序的数列为n个,则需要递归lb n次,时间复杂度为O(n lb n)。
最坏情况是,每次所选的基准数为最大或最小的数,这样的话每次经过一趟排序后被划分的两个数列就有一个是空的,另一个数列的长度为原来长度减1,时间复杂度为O(n²)。
平均时间复杂度为O(n lb n)。
经过分析我们可以知道,基准数的选取是影响算法性能的关键。