排序算法--快速排序(分治法)

来源:互联网 发布:网络拓扑图结构的意义 编辑:程序博客网 时间:2024/06/05 16:25

思想

快速排序采用的思想是分治思想。
快速排序是找出一个元素(理论上可以随便找一个)作为基准(pivot),然后对数组进行分区操作,使基准左边元素的值都不大于基准值,基准右边的元素值 都不小于基准值,如此作为基准的元素调整到排序后的正确位置。递归快速排序,将其他n-1个元素也调整到排序后的正确位置。最后每个元素都是在排序后的正 确位置,排序完成。所以快速排序算法的核心算法是分区操作,即如何调整基准的位置以及调整返回基准的最终位置以便分治递归。
举例说明一下吧,这个可能不是太好理解。

贴上分析代码(交流学习):

#include<stdio.h>#include<stdlib.h>/*函数声明*/void QuickSort(int *A,int p,int r);    //快速排序int Partition(int *A,int p,int r);//分治法void Display(int *a,int size);//打印函数/*主函数*/int main(int argc, char* argv[]){int size,*a;printf("输入字符串长度:\n");scanf("%d",&size);if(size > 0) {printf("请输入%d个待排序数字:\n",size);a = (int*)malloc(size*sizeof(int)); //a = new int [size];for(int i=0; i<size; i++)  //输入数组{scanf("%d",&a[i]);}QuickSort(a,0,size-1); //调用快速排序函数}elseprintf("输入长度错误!\n");Display(a,size);   //打印数组return 0;}/*函数定义*/void QuickSort(int *A,int p,int r) //快速排序{int q;if(p<r)               //如果p大于等于r 那么就程序不执行{q = Partition(A,p,r);  //调用分治法 找到q的值QuickSort(A,p,q-1);QuickSort(A,q+1,r);}}int Partition(int *A,int p,int r) //分治法,作用就是将数组分为A[p..q-1] 和A[q+1..r]{//然后调整元素使得A[p..q-1]小于等于q,也小于等于A[q+1..r]int x,i,j,temp;x = A[r];                      //将最后一个值保存在x中,将最后这个数作为参考值。i = p-1;                      //开始的时候将i 移动到数组的外面for( j=p; j<=r-1; j++){if(A[j]<=x)               //将小于A[r] 的值放在左边。{i +=1;temp = A[i]; A[i] = A[j];A[j] = temp;}}temp = A[i+1];                // A[i+1]即为中间值的位置,故此处应将参考值A[r],与该位置调换数值。A[i+1] = A[r];A[r] = temp;return i+1;                   //返回q值,返回参考值下标。}void Display(int *a,int size)     //打印函数{printf("排序结果为:\n");for(int i=0; i<size; i++)    //打印数组{printf("%d ",a[i]);}printf("\n");}

分析
快速排序的时间主要耗费在划分操作上,对长度为k的区间进行划分,共需k-1次关键字的比较。
最坏情况是每次划分选取的基准都是当前无序区中关键字最小(或最大)的记录,划分的结果是基准左边的子区间为空(或右边的子区间为空),而划分所得的另一个非空的子区间中记录数目,仅仅比划分前的无序区中记录个数减少一个。时间复杂度为O(n*n)
在最好情况下,每次划分所取的基准都是当前无序区的"中值"记录,划分的结果是基准的左、右两个无序子区间的长度大致相等。总的关键字比较次数:O(nlgn)
尽管快速排序的最坏时间为O(n2),但就平均性能而言,它是基于关键字比较的内部排序算法中速度最快者,快速排序亦因此而得名。它的平均时间复杂度为O(nlgn)。


0 0
原创粉丝点击