- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
第十章 排序
10.1 概述
一、基本概念
关键字项及关键字(Key):记录由若干个数据项(或域)组成,其中有一项可用来标识一个记录,称为关键字项,该数据项的值称为关键字。
排序(Sorting):又称分类,假设含 n 个记录的序列为{R1,R2,…,Rn}其相应的关键字序列为{K1,K2,…,Kn} 需确定1,2,…,n的一种排列p1,p2,…,pn,使其相应的关键字满足如下的非递减(或非递增)关系 Kp1≤Kp2≤…≤Kpn 。即使初始的的序列成为一个按关键字有序的序列{Rp1,Rp2,…,Rpn}这样一种操作称为排序。
如果待排序的文件中,存在有多个关键字相同的记录,经过排序后这些具有相同关键字的记录之间的相对次序保持不变,则称这些排序方法是稳定的;反之,则称这种排序方法是不稳定的。
排序算法的稳定性是针对所有输入实例而言的,即在所有可能的输入实例中,只要有一个实例使得算法不满足稳定性要求,则该排序算法就是不稳定的。
二、排序方法
①内部排序
内部排序(Internal Sorting):在排序过程中,若整个文件都是放在内存中处理,排序时不涉及数据的内、外存交换,则称之为内排序。
按所用的策略不同,内部排序方法可以分为五类:插入排序、选择排序、交换排序、归并排序、分配排序。
②外部排序
外部排序(External Sorting):若排序过程中要进行数据的内、外存交换,则称之为外部排序。
三、排序过程的基本操作
比较两个关键字的大小
改变指向记录的指针或移动记录本身
评价排序算法好坏的标准:执行时间和所需的辅助空间
就地排序(In-Place Sort):若排序算法所需的辅助空间并不依赖于规模n,也就是说辅助空间是O(1),则称之为就地排序。
四、顺序表类型说明
五、几种基本的排序方法
10.2 插入排序
插入排序(Insertion Sort)的基本思想是:每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子文件中的适当位置,直到全部记录插入完成为止。
直接插入排序
直接插入排序(Straight Insertion Sort):将一个记录插入到排好序的有序表中,从而得到一个新的、记录数增1的有序表。
直接插入排序算法
哨兵(监视哨)有两个作用:
一是作为临变量存放R[i](当前要进行比较的关键字)的副本;
二是在查找循环中用来监视下标变量j是否越界。
当文件的初始状态不同时,直接插入排序所耗费的时间是有很大差异的。最好情况是文件初态为正序,此时算法的时间复杂度为O(n),最坏情况是文件初态为反序,相应的时间复杂度为O(n2),算法的平均时间复杂度是O(n2)。算法的辅助空间复杂度是O(1),是一个就地排序。
直接插入排序是稳定的排序方法。
二分(折半)插入排序
二分插入排序:“查找”操作利用“二分查找”来实现,由此进行的插入排序称为二分插入排序。
二分插入排序算法
用二分插入排序所要进行的总比较次数为O(lgn),当n较大时,比直接插入排序的最大比较次数小得多,但大于最小比较次数。
二分插入排序方法是稳定的。
Shell排序
希尔排序(Shell Sort):先取定一个正整数d1(<n),把全部记录分成d1个组,所有距离为d1倍数的记录放在一组中,在各组内进行插入排序;然后取d2<d1,重复上述分组和排序工作,直至取di=1,即所有记录放在一个组中排序为止。
void ShellPass(SeqList R,int d)
{ //希尔排序中的一趟排序,d为当前增量
int i,j;
for(i=d+1;i=n;i++) //将R[d+1..n]分别插入各组当前的有序区
if(R[i].keyR[i-d].key) {
R[0]=R[i];j=i-d; //R[0]只是暂存单元,不是哨兵
do { //查找R[i]的插入位置
R[j+d]=R[j]; //后移记录
j=j-d; //查找前一记录
} while(j0R[0].keyR[j].key);
R[j+d]=R[0]; //插入R[i]到正确的位置上
}
}
void ShellSort(SeqList R)
{
int increment=n; //增量初值,不妨设n0
do {
increment=increment/3+1; //求下一增量
ShellPass(R,increment); //一趟增量为increment的Shell插入排序
} while(increment1);
}
希尔排序特点:每次以不同的增量分组进行插入排序,在最后一次作插入排序时,所有记录“几乎”有序了。由于前面几次排序中增量
文档评论(0)