数据结构排序.ppt
《数据结构排序.ppt》由会员分享,可在线阅读,更多相关《数据结构排序.ppt(52页珍藏版)》请在三一办公上搜索。
1、第九章 排序,本章讨论数据结构中另一个重要的运算排序(或分类),包括排序的定义、各种排序的方法、算法实现及时间复杂度的分析等内容。9.1 概述排序(Sort)是将无序的记录序列(或称文件)调整成有序的序列。对文件(File)进行排序有重要的意义。如果文件按key有序,可对其折半查找,使查找效率提高;在数据库(Data Base)和知识库(Knowledge Base)等系统中,一般要建立若干索引文件,就牵涉到排序问题;在一些计算机的应用系统中,要按不同的数据段作出若干统计,也涉及到排序。排序效率的高低,直接影响到计算机的工作效率。另外,研究排序方法和算法,目的不单纯是完成排序的功能和提高效率,
2、其中对软件人员的程序设计能力会有一定的提高,也是对以前数据结构内容的复习、巩固和提高。,1.排序定义,设含有n个记录的文件f=(R1 R2Rn),相应记录关键字(key)集合k=k1 k2kn。若对1、2n的一种排列:P(1)P(2)P(n)(1P(i)n,ij时,P(i)P(j))有:kP(1)kP(2)kP(n)递增关系或 kP(1)kP(2)kP(n)递减关系则使f 按key线性有序:(RP(1)RP(2)RP(n)),称这种运算为排序(或分类)。关系符“”或“”并不一定是数学意义上的“小于等于”或“大于等于”,而是一种次序关系。但为讨论问题方便,取整型数作为key,故“”或“”可看作通
3、常意义上的符号。2.稳定排序和非稳定排序 设文件f=(R1RiRjRn)中记录Ri、Rj(ij,i、j=1n)的key相等,即Ki=Kj。若在排序前Ri领先于Rj,排序后Ri仍领先于Rj,则称这种排序是稳定的,其含义是它没有破坏原本已有序的次序。反之,若排序后Ri与Rj的次序有可能颠倒,则这种排序是非稳定的,即它有可能破坏了原本已有序记录的次序。,3.内排序和外排序,若待排文件f在计算机的内存储器中,且排序过程也在内存中进行,称这种排序为内排序。内排序速度快,但由于内存容量一般很小,文件的长度(记录个数)n受到一定限制。若排序中的文件存入外存储器,排序过程借助于内外存数据交换(或归并)来完成,
4、则称这种排序为外排序。我们重点讨论内排序的一些方法、算法以及时间复杂度的分析。4.内排序方法 截止目前,各种内排序方法可归纳为以下五类:(1)插入排序;(2)交换排序;(3)选择排序;(4)归并排序;(5)基数排序。5.文件存储结构(1)顺序结构类似线性表的顺序存储,将文件f=(R1 R2Rn)存于一片连续的存储空间,逻辑上相邻的记录在存储器中的物理位置也是相邻的,如图9.1:在这种结构上对文件排序,一般要作记录的移动。当发生成片记录移动时,是一个很耗时的工作。,(2)链表结构,类似于线性表的链式存储,文件中记录用节点来表示,其物理位置任意,节点之间用指针相连,如图9.2:链表结构的优点在于排
5、序时无须移动记录,只需修改相应记录的指针即可。(3)地址映象结构 该结构是另设一地址向量,存储文件中各记录的地址(或序号),如图9.3:,(数据文件),i j(地址向量),排序可在地址向量上进行,一定程度上免去了排序时记录的移动。,9.2 插入排序,插入排序(Insert Sort)可分为:直接插入排序、折半插入排序、链表插入排序以及Shell(希尔)排序等。每种排序按照排序方法、举例说明、算法描述以及算法分析等几个步骤讨论。9.2.1 直接插入排序 设待排文件f=(R1 R2Rn)相应的key集合为k=k1 k2kn,文件f对应的结构可以是9.1节中讨论的三种文件结构之一。1.排序方法 先将
6、文件中的(R1)看成只含一个记录的有序子文件,然后从R2起,逐个将R2至Rn按key插入到当前有序子文件中,最后得到一个有序的文件。插入的过程上是一个key的比较过程,即每插入一个记录时,将其key与当前有序子表中的key进行比较,找到待插入记录的位置后,将其插入即可。另外,假定排序后的文件按递增次序排列(以下同)。例9-1 设文件记录的key集合k=50,36,66,76,95,12,25,36(考虑到对记录次key排序的情况,允许多个key相同。如此例中有2个key为36,后一个表示成36,以示区别),按直接插入排序方法对k的排序过程如下:,直接插入排序,k=50,36,66,76,95,
7、12,25,36,50 36,36,50 66,36,50,66 76,36,50,66,76 95,36,50,66,76,95 12,12,36,50,66,76,95 25,12,25,36,50,66,76,95 36,12,25,36,36,50,66,76,95,一般,插入ki(2in),当kjkikj+1ki-1时:,直接插入排序,文件结构说明:#define maxsize 1024 文件最大长度typedef int keytype;设key为整型typedef struct 记录类型 keytype key;记录关键字 记录其它域Retype;typedef struct
8、文件或表的类型 Retype Rmaxsize+1;文件存储空间 int len;当前记录数sqfile;若说明sqfile F;则:(F.R1,F.R2F.RF.len)为待排文件,它是一种顺序结构;文件长度n=F.len;F.R0为工作单元,起到“监视哨”作用;记录的关键字ki写作F.Ri.key。,直接插入排序,2.算法描述void Insort(sqfile F)对顺序文件F直接插入排序的算法 int i,j;for(i=2;i=F.len;i+)插入n1个记录 F.R0=F.Ri;待插入记录先存于监视哨 j=i-1;while(F.R0.keyF.Rj.key);key比较 F.Rj
9、+1=F.Rj;记录顺序后移 j-;F.Rj+1=F.R0;原Ri插入j+1位置 3.算法分析 排序算法一般包括key的比较和记录的移动两种操作,所以算法分析应求出这两种操作的时耗作为算法的时间复杂度T(n)。当然算法分析还应包括算法中存储空间的耗费,但当辅助空间占用不太多时,不作讨论。,直接插入排序,设排序中key比较次数为C,C最小时记为Cmin,最大时记为Cmax。(1)当文件原来就有序(正序)时,每插入一个Ri只需比较key一次,即:(2)当文件原本逆序(key从大到小)时,每插入一个Ri要和子表中i1个key比较,加上同自身R0的比较,此时比较次数最多,即:(3)求记录总的移动次数m
10、(m最小时记为mmin,最大时记为mmax)算法中,Ri=R0,R0=Rj+1移动两次;插入Ri时,Ri-1Rj+1各移动一次。文件正序时,子表中记录的移动免去,即:逆序时,插入Ri牵涉移动整个子表。移动次数为2+(i1)=i+1,此时表的移动次数最大,即:排序的时间复杂度取耗时最高的量级,故直接插入排序的T(n)=O(n2)。,9.2.2 折半插入排序,排序算法的T(n)=O(n2),是内排序时耗最高的时间复杂度。随着文件记录数n的增大,效率降低较快。下面的一些插入排序的方法,都是围绕着改善算法的时间复杂度而展开的。另外,直接插入排序是稳定排序。为减少插入排序过程中key的比较次数,可采用折
11、半插入排序。1.排序方法 同直接插入排序,先将(R1)看成一个子文件,然后依次插入R2Rn。但在插入Ri时,子表R1Ri-1已是有序的,查找Ri在子表中的位置可按折半查找方法进行,从而降低key的比较次数。例9-2 设当前子表key序列及插入的ki=28如下:序号:1 2 3 4 5 6 15 20 25 3 0 35 40 28 low high 令:,28R3.key=25,low=3+1=4;28high,所以“28”应插在low=4所指示的位置。,折半插入排序,2.算法描述void Binsort(sqfile F)对文件F折半插入排序的算法 int i,j,low,high,mid;
12、for(i=2;i=F.Rmid.key)low=mid+1;调整下界 else high=mid-1;调整上界 for(j=i-1;j=low;j-)F.Rj+1=F.Rj;记录顺移 F.Rlow=F.R0;原Ri插入low位置,折半插入排序,3.算法分析 插入Ri(2in)时,子表记录数为i1。同第八章中的折半查找算法的讨论,查找Ri的key比较次数为,故总的key比较次数C为:显然优于O(n2)。但折半插入排序的记录移动次数并未减少,仍为O(n2)。故算法的时间复杂度T(n)仍为O(n2)。9.2.3 链表插入排序设待排序文件f=(R1 R2Rn),对应的存储结构为单链表结构,如图9.4
13、:1.排序方法 链表插入排序实际上是一个对链表遍历的过程。先将表置为空表,然后依次扫描链表中每个节点,设其指针为p,搜索到p节点在当前子表的适当位置,将其插入。,链表插入排序,例9-3 设含4个记录的链表如图9.5:,插入50:,初始化:,插入36:,插入66:,插入12:,2.算法描述,typedef struct node 存放记录的节点 keytype key;记录关键字 记录其它域 struct node*next;链指针Lnode,*linklist;void Linsertsort(linklist L)链表插入排序算法 linklist p,q,r,u;p=L-next;p为待插
14、入节点指针 L-next=NULL;置子表为空 while(p)若待排序节点存在 r=L;q=L-next;r为q的前驱指针 while(q,3.算法分析,(1)当链表L逆序时,每插入一个节点时,key的比较次数最多为1,总的key比较次数C达到最小,即:(2)当链表L正序时,每插入第i号(1in)节点都要搜索到当前子表的表尾,key的比较次数为i-1,故总的key比较次数C达到最大,即:所以链表插入排序的时间复杂度T(n)=O(n2)。但排序过程中不牵涉到记录的移动,只是修改相应指针,这一点优于其它的插入排序方法。9.2.4 Shell排序 Shell(希尔)排序又称“缩小增量”排序,195
15、9年由D.L.Shell提出。希尔发现:直接插入排序中,key比较次数及记录移动次数会比较大,若将待排序文件按某种次序分隔成若干个子文件,对各子文件“跳跃”式的排序,然后调整子文件个数,逐步对原文件排序,这样总的key比较次数尤其是记录移动次数也许会大大降低。,1.Shell排序方法,设待排文件f=(R1 R2Rn),先将f中相隔增量d(如令d=n/2)的记录组成一个个子文件,对各子文件插入排序;然后缩小增量d(如令d=d/2),再将相隔新增量的记录组成一个个子文件,对诸子文件排序,直到增量d=1为止,排序完毕。这是一种跳跃式的排序方法,它使得文件逐步有序,从而克服了一次排序时记录成片移动现象
16、。例9-4 设文件的记录key集合k=50,36,66,76,95,12,25,36,24,08(n=10),选取增量序列为10/2=5、5/2=2、2/2=1。排序过程如下:序号:1 2 3 4 5 6 7 8 9 10 50 36 66 76 95 12 25 36 24 08,令:d=5,令:d=2,令:d=1,08 12 24 25 36 36 50 66 76 95(完毕)显然,Shell排序是非稳定排序。,Shell排序,2.算法描述void Shellsort(sqfile F)对顺序文件F按Shell方法排序的算法 int i,j,d=F.len/2;第一次增量 while(d
17、=1)for(i=d+1;i0)形成新的增量 从算法中看出,若将其中的d 改为1,基本上同直接插入排序算法。,Shell排序,Shell排序的算法分析目前还是一道数学难题,如何选择增量序列使得排序效率最高还无定论。选取增量序列的经验公式之一为:ds=2s-1,1s如n=100时,增量序列为:d6=63,d5=31,d4=15,d3=7,d2=3,d1=1此时算法的时间复杂度T(n)可达O(n1.5),强于O(n2)。9.3 交换排序 本节讨论借助记录“交换”进行的排序方法(Exchange Sort),即“起泡”排序(Bubble Sort)和“快速”排序(Quick Sort)。9.3.1
18、起泡排序设待排文件f=(R1 R2Rn),相应key集合k=k1 k2kn。1.排序方法 从k1起,两两key比较,逆序时交换,即:k1k2,若k1k2,则R1 R2;k2k3,若k2k3,则R2 R3;kn-1kn,若kn-1kn,则Rn-1 Rn。经过一趟比较之后,最大key的记录沉底,类似水泡。接着对前n1个记录重复上述过程,直到排序完毕。,起泡排序,注意:在某趟排序的比较中,若发现两两比较无一记录交换,则说明文件已经有序,不必进行到最后两个记录的比较。例9-5 设记录key集合k=50,36,66,76,95,12,25,36,排序过程如下:,排序完毕,K503666769512253
19、6,从此例可以看出,起泡排序属于稳定排序。,起泡排序,2.算法描述void Bubsort(sqfile F)对顺序文件起泡排序的算法 int i,flag;flag为记录交换的标记 Retype temp;for(i=F.len;i=2;i-)最多n1趟排序 flag=0;for(j=1;jF.Rj+1.key)两两比较 temp=F.Rj;Rj Rj+1 F.Rj=F.Rj+1;F.Rj+1=temp;flag=1;if(flag=0)break;无记录交换时排序完毕,起泡排序,3.算法分析 设待排文件长度为n,算法中总的key比较次数为C。若文件正序,第一趟就无记录交换,退出循环,Cmi
20、n=n1=O(n);若文件逆序,则需n1趟排序,每趟key的比较次数为i1(2in),故:同理,记录的最大移动次数为:故起泡排序的时间复杂度T(n)=O(n2)。,9.3.2 快速排序,快速排序是对起泡排序的一种改进,目的是提高排序的效率。1.排序方法 经过key的一趟比较后,确定某个记录在排序后的最终位置。设待排文件的key集合k=k1 k2kikjkn-1 kn,对k中的k1,称作枢轴(Pivot)或基准。(1)逆序比较:k1kn,若k1kn,则k1不可能在kn位置,k1kn-1,直到有个kj,使得k1kj,则k1有可能落在kj位置,将kjk1位置,即key比基准(k1)小的记录向左移。(
21、2)正序比较:k1k2,若k1k2,则k1不可能在k2位置,k1k3,直到有个ki,使得k1ki,则k1有可能落在ki位置,将ki kj位置(原kj已送走),即key比基准大的记录向右移。反复逆序、正序比较,当i=j时,i位置就是基准k1的最终落脚点(因为比基准小的key统统在其“左部”,比基准大的统统在其“右部”,作为基准的key自然落在排序后的最终位置上),并且k1将原文件分成了两部分:对k和k”,套用上述排序过程(可递归),直到每个子表只含有一项时,排序完毕。,快速排序,例9-6 设记录的key集合k=50,36,66,76,36,12,25,95,每次以集合中第一个key为基准的快速排
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 排序
链接地址:https://www.31ppt.com/p-3787958.html