- 1、本文档共58页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
注意: 本章在讨论各种内排序算法时,假定n个待排序记录存于一维数组a 中,记录类型为ELEMTYPE,而且我们也假设比较关键字的运算符已经有了定义。另外我们认为对于任何一种记录都可以找到一个取得它的关键字函数,记为key。算法中所用到函数swap用于交换两个记录的内容。 直接插入排序由两个嵌套的循环组成。for循环总共执行n-1 次。while循环执行次数依赖于在第i个记录前的i-1个记录中有多少个记录的关键字值大于第i个记录的关键字值。最差的情况是如果数组中记录是逆序的,每个记录都必须移动到数组的顶端。这时while循环共做i-1次比较。 算法9.2 void binsort(ELEMTYPE a[],int n) { int i,j,l,h,m,temp; for (i=1;in;i++) { temp = a[i]; l = 0; h=i-1; while(l=h) { m = (l+h)/2; if (key(a[m])key(temp)) l = m+1; else h = m-1; } for (j = i;jl;j--) a[j] = a[j-1]; a[j] = temp; } } 9.4.1简单选择排序 当基准值不能很好地分割数组,即基准值将数组分割成一个子数组中有一个记录,而另一个子数组有n-1个记录时,下一次处理的子数组只比原来数组小1,这是快速排序的最差情况。如果这种情况发生在每一次划分过程中,那么快速排序算法的时间复杂性为: = O(n2) 当每个基准值都将数组分成相等的两部分,出现快速排序的最佳情况。在这种情况下,我们还要对每个大小约为n/2的两个子数组进行排序。在一个大小为n的记录中确定一个记录的位置所需要的时间为O(n)。若T(n)为对n个记录进行排序所需要的时间,则每当一个记录得到其正确位置,数组大致分成两个相等的部分时,我们得到快速排序算法的最佳时间复杂性 T(n) ? cn + 2T(n/2) ? cn + 2(cn/2 + 2T(n/4)) ? 2cn + 4T(n/4)) ... ? cnlogn + nT(1) = O(nlogn) 其中cn是一次划分所用的时间,c是一个常数。 快速排序的平均情况介于最佳与最差情况之间。假设,在每一次分割时,基准值处于最终排好序的位置的概率是一样的,基准值将数组分成长度为0和n-1,1和n-2,…的概率都是1/n。在这种假设下,快速排序算法的平均时间复杂性为: T(n) = cn + 1/n (T(k) + T(n-1-k)) T(0) = c , T(1) = c 这是一个递归公式。T(k)和T(n-k-1)是指处理长度为k和n-k-1数组时快速排序算法所花费的时间。根据公式所推算出来的时间为O(nlogn)。因此,快速排序平均时间复杂性为O(nlogn)。 快速排序需要栈空间来实现递归,如果像上述分析所说,数组按均等方式被分割时,则最大递归深度为logn,需要的栈空间为O(logn)。最坏的情况是,在递归的每一级上,数组分割成长度为0的左子数组和长度为n-1的右子数组。在这种情况下,递归的深度就成为n,需要的栈空间为O(n) 9.3.2 快速排序 9.4 选择排序 9.4.1简单选择排序 9.4.2堆排序 堆排序是借助于堆数据结构的一种排序方法。堆由两个性质来定义。首先,它是一个完全二叉树,所以往往如第6.2.3节用数组表示完全二叉树那样用数组来实现。其次,结点的值与其子结点存储的值之间存在某种关系。父结点与子结点存储的值关系的定义不同,导致有两种不同的堆:最大值堆和最小值堆。 最大值堆的性质是堆中任意一结点的值都大于或者等于其任意一个子结点存储的值。由于根结点包含大于等于其子结点的值,而其子结点又依次大于或者等于各自子结点的值,所以根结点存储着所有结点的最大值。 9.4.1简单选择排序 最小值堆是堆中每一个结点存储的值都小于或者等于其任意一个子结点存储的值。由于根结点包含小于等于其子结点的值,而其子结点又依次小于或者等于各自子结点的值,所以根结点存储了所有结点的最小值。 基于最大值堆排序算法的思想是首先将待排序记录建成堆。然后将堆顶的关键字值最大的记录输出,再对剩下的记录重新建堆,再取出堆顶记录,…,如此下去,便得到一个有序序列。由此,实现堆排序需要解决两个问题:(1)如何由一个无序记录序列建成一个堆?(2)如何在输出堆顶记录之后,调整剩余记录成为一个新的堆?: 下面首先讨论第一个问题。可以采用两种方法建立堆。一种方法是从根结点开始把记录一个接
文档评论(0)