快速排序作为20世纪最重要的10大算法思想之一,其地位可想而知。而它也是目前公认的最快的排序算法之一,很多比较高级的算法也是从快速排序的思想上衍生而来。快速排序的主要思想就是归并法,想把原来的问题分解成n个子问题,然后递归的来解决这些子问题,然后合并其结果就可以得到原问题的解了。
快速排序的主要思想思路就是,从数组中拿出一个元素来(一般是第一个元素),与数组的其它元素进行比较,比它小的都放在它的左边,比它大的都放在它的右边。以这个数为中间数,把原来的数组划分为2部分:1.比它小的数构成的数;2.比它大的数构成的数组。然后按照上述的方法递归的处理这些元素,依次这样下去,就可以排好序了。
快速排序的c语言代码如下:
# include <stdio.h>
void quicksort(int *arr,int low,int high);
int partition(int *arr,int low,int high);
int main(void){
int i;
intarr[10] = {3,6,5,10,17,42,18,15,32,8}; //排序的元素
quicksort(arr,0,9); //把最开始的数组下标的low和high传过去
for(i=0;i<10;i++){
printf("%d",arr[i]);
}
return 0;
}
int partition(int *arr,int low,int high){
int priot= arr[low]; //把第一个数字取特定的值,此函数的目录就是要让这个数字左边的数都比它小,右边的数都比它大
int t;
while(low<high){ //如果low<high,证明还没有比完,就继续比下去
while(low<high&& priot<arr[high]){
high--; //从最右边开始,如果选取的特定的值比arr[high]要小的话,就让high--,然后与这个数的左边的一个数继续比较
}
t =arr[low]; //如果找到arr[high]的值比priot小的话,我们就交换两个数,此时arr[high](即priot)右边的数都比它大
arr[low]= arr[high];
arr[high]= t;
while(low<high&& priot>arr[low]){
low++; //从最左边开始,如果选取的特定的值比arr[low]要大的话,就让low++,然后与这个数的右边的一个数继续比较
}
t =arr[high]; //如果找到arr[low]的值比priot大的话,我们就交换两个数,此时arr[low](即priot)左边的数都比它小
arr[high]= arr[low];
arr[low]= t;
}
//当循环结束的时候,我们一定可以得到priot左边的数比它小,右边的数比它大
returnlow; //把当前选取特定值对应的key返回
}
void quicksort(int *arr,int low,int high){
intpriot;
if(low<high){ //如果当前的low小于high的话,证明元素还不是剩下只有1个
priot= partition(arr,low,high); //将对应的数组一分为2,得到中间值
quicksort(arr,low,priot-1); //把中间值左边的数组继续排序
quicksort(arr,priot+1,high); //把中间值右边的数组继续排序
}
}
我们来看这个算法的时间复杂度,最坏的情况下在划分过程中产生的两个区域分别包含n-1和1个元素。分割算法耗时如果为o(n),那么最坏情况下的复杂度为:T(n)= T(n-1)+o(n);也就是o(n2(n的平方));而最好
情况下,每次划分产生两个均匀大小的块,则时间复杂度为:T(n) = 2T(2/n)+o(n);也就是o(nlogn);所以快速排序的效率取决于划分的对称性。