C语言快速排序算法.docx_第1页
C语言快速排序算法.docx_第2页
C语言快速排序算法.docx_第3页
C语言快速排序算法.docx_第4页
C语言快速排序算法.docx_第5页
全文预览已结束

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

C语言快速排序算法(一)概述快速排序(Quick Sort)是一种有效的排序算法。虽然算法在最坏的情况下运行时间为O(n2),但由于平均运行时间为O(nlogn),并且在内存使用、程序实现复杂性上表现优秀,尤其是对快速排序算法进行随机化的可能,使得快速排序在一般情况下是最实用的排序方法之一。快速排序被认为是当前最优秀的内部排序方法。(二)实现快速排序的实现基于分治法,具体分为三个步骤。假设待排序的序列为Lm.n。分解:序列Lm . n被划分成两个可能为空的子序列Lm . pivot-1和Lpivot+1 . n,使Lm . pivot-1的每个元素均小于或等于Lpivot,同时Lpivot+1. n的每个元素均大于Lpivot。其中Lpivot称为这一趟分割中的主元(也称为枢轴、支点)。解决:通过递归调用快速排序,对子序列Lm . pivot-1和Lpivot+1 . r排序。 合并:由于两个子序列是就地排序的,所以对它们的合并不需要操作,整个序列Lm . n已排好序。(三)性质内部排序快速排序是一种内部排序方法。也就是说快速排序的排序对象是读入内存的数据。比较排序快速排序确定元素位置的方法基于元素之间关键字大小的比较。所有基于比较方法的排序方法的时间下界不会低于O(nlgn)。这个结论的具体证明,请参考有关算法的书籍,例如算法导论(第一版)第8章(第二版在第七章QuickSort)。在理想情况下,能严格地达到O(nlgn)的下界。一般情况下,快速排序与随机化快速排序的平均情况性能都达到了O(nlgn)。不稳定性快速排序是一种不稳定的排序方法。简单地说,元素a1, a2的关键字有a1.key=a2.key,则不稳定的排序方法不能保证a1, a2在排序后维持原来的位置先后关系。原地排序在排序的具体操作过程中,除去程序运行实现的空间消费(例如递归栈),快速排序算法只需消耗确定数量的空间(即S(1),常数级空间)。这个性质的意义,在于在内存空间受到限制的系统(例如MCU)中,快速排序也能够很好地工作。(四)时空复杂度快速排序每次将待排序数组分为两个部分,在理想状况下,每一次都将待排序数组划分成等长两个部分,则需要logn次划分。而在最坏情况下,即数组已经有序或大致有序的情况下,每次划分只能减少一个元素,快速排序将不幸退化为冒泡排序,所以快速排序时间复杂度下界为O(nlogn),最坏情况为O(n2)。在实际应用中,快速排序的平均时间复杂度为O(nlogn)。快速排序在对序列的操作过程中只需花费常数级的空间。空间复杂度S(1)。但需要注意递归栈上需要花费最少logn 最多n的空间。(五)随机化算法快速排序的最坏情况基于每次划分对主元的选择。基本的快速排序选取第一个元素作为主元。这样在数组已经有序的情况下,每次划分将得到最坏的结果。一种比较常见的优化方法是随机化算法,即随机选取一个元素作为主元。这种情况下虽然最坏情况仍然是O(n2),但最坏情况不再依赖于输入数据,而是由于随机函数取值不佳。实际上,随机化快速排序得到理论最坏情况的可能性仅为1/(2n)。所以随机化快速排序可以对于绝大多数输入数据达到O(nlogn)的期望时间复杂度。一位前辈做出了一个精辟的总结:“随机化快速排序可以满足一个人一辈子的人品需求。”随机化快速排序的唯一缺点在于,一旦输入数据中有很多的相同数据,随机化的效果将直接减弱。对于极限情况,即对于n个相同的数排序,随机化快速排序的时间复杂度将毫无疑问的降低到O(n2)。(六)减少递归栈使用的优化快速排序的实现需要消耗递归栈的空间,而大多数情况下都会通过使用系统递归栈来完成递归求解。在元素数量较大时,对系统栈的频繁存取会影响到排序的效率。一种常见的办法是设置一个阈值,在每次递归求解中,如果元素总数不足这个阈值,则放弃快速排序,调用一个简单的排序过程完成该子序列的排序。这样的方法减少了对系统递归栈的频繁存取,节省了时间的消费。一般的经验表明,阈值取一个较小的值,排序算法采用选择、插入等紧凑、简洁的排序。一个可以参考的具体方案:阈值T=10,排序算法用选择排序。阈值不要太大,否则省下的存取系统栈的时间,将会被简单排序算法较多的时间花费所抵消。另一个可以参考的方法,是自行建栈模拟递归过程。但实际经验表明,收效明显不如设置阈值。(七)C例程以下是C语言权威The C Programming Language中的例程,在这个例程中,对于数组v的left到right号元素以递增顺序排序。/Qsort.c by Tydus.#include int arr = 14,10,11,5,6,15,0,15,16,14,0,8,17,15,7,19,17,1,18,7;/* swap函数:交换vk与vj的值 */inline void swap(int v, int k, int j)int temp;temp = vk;vk = vj;vj = temp;void qsort(int v, int left, int right)int j, last;if (left = right) /* 若数组包含的元素个数少于两个 */return; /* 则不执行任何操作 */swap(v, left, (left + right)/2); /* 将划分子集的元素移动到V0 */last=left; /* 用last记录中比关键字小间的最右位置*/for (j = left+1; j = right; j+) /* 划分子集 */if (vj vleft)swap(v, last+, j); /*小小。关键字大大大大*/qsort(v, left, last-1);qsort(v, last+1, right);void main()int j;qsort(arr, 0, 19);for(j=0; j=19; j+)printf(%d , arrj);printf(n);(八)消除递归的快速排序传统的快速排序是递归的,这就会受到递归栈深度的限制。比如在一台普通的PC上,当待排序元素达到106以上时,传统的递归快排会导致栈溢出异常,或者一个莫名其妙的错误结果。所以,对于巨大的数据规模,将快速排序消除递归是十分必要的。而消除递归,又将带来巨大的性能提升,把系统级的消耗降到最低。消除递归的方法,就是模拟栈操作。但是从代码可以看出,这种模拟的消耗几乎可以忽略不计。因此消除递归的快排的效率是有保障的。(虽然下面的代码没有使用随机化,但经过测试,它是目前所有快排编写方法中,效率最高,速度最快的!)/#define MAXARRAY 10000#define PUSH(A,B) slsp=A;srsp=B;sp+;#define POP(A,B) sp-;A=slsp;B=srsp;void quicksort(int a,int l,int r)static int slMAXARRAY, srMAXARRAY, sp;int i,j,p,t;sp=0;PUSH(l,r);while(sp)POP(l,r);i=l;j=r;p=a(i+j)/2;while(i=j) while(aip)j-;if(i=j) t=ai;ai=aj;aj=t; i+;j-; if(lj)PUSH(l,j);if(ir)PUSH(i,r);/ (十二)C语言随机化快排模块化代码#include stdio.h#include stdlib.h#include time.hLocation(int *a,int low,int high)int key,temp,x;srand(unsigned)time(0);x=rand()%(high-low+1)+low;key=ax;while(lowhigh)while(xhigh&key=ahigh)high-;temp=ahigh;ahigh=key;ax=temp;x=high;while(low=alow)low+;temp=alow;alow=key;ax=temp;x=low;return low;Qsort(int *a,int low,int high)int locat,i;if(low=high)return 0;locat=Location(a,low,high);Qsort(a,low,locat-1);Qsort(a,locat+1,high);(十三)快速排序的JAVA实现import java.util.Arrays;public class QuickSort public static void quickSort(int array) quickSort(array, 0, array.length - 1);private static void quickSort(int array, int low, int high) if (low high) int p = partition(array, low, high);quickSort(array, low, p - 1);quickSort(array, p + 1, high);private static int partition(int array, int low, int high) int s = arrayhigh;int i = low - 1;for (int j = low; j high; j+) if (arrayj s) i+;swap(array, i, j);swap(array, +i, high);return i;private static void swap(int array

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论