《数据结构第9章排序.pptx》由会员分享,可在线阅读,更多相关《数据结构第9章排序.pptx(103页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、19.1 概述9.2 插入排序9.3 交换排序9.4 选择排序9.5 归并排序9.6 基数排序第第9 9章章 内部排序内部排序第1页/共103页29.1 9.1 概述1.什么是排序?将一组杂乱无章的数据按一定的规律顺次排列起来。2.排序的目的是什么?存放在数据表中按关键字排序3.排序算法的好坏如何衡量?时间效率排序速度(即排序所花费的全部比较次数)空间效率占内存辅助空间的大小稳定性若两个记录A和B的关键字值相等,但排序后A、B的先后次序保持不变,则称这种排序算法是稳定的。便于查找!第2页/共103页34.什么叫内部排序?什么叫外部排序?什么叫内部排序?什么叫外部排序?若待排序记录都在内存中,称
2、为内部排序;若待排序记录一部分在内存,一部分在外存,则称为外部排序。注:外部排序时,要将数据分批调入内存来排序,中间结果还要及时放入外存,显然外部排序要复杂得多。5.待排序记录在内存中怎样存储和处理?顺序排序排序时直接移动记录;链表排序排序时只移动指针;地址排序排序时先移动地址,最后再移动记录。注:地址排序中可以增设一维数组来专门存放记录的地址。第3页/共103页4注:大多数排序算法都是针对顺序表结构的(便于直接移动元素)6.6.顺序存储(顺序表)的抽象数据类型如何表顺序存储(顺序表)的抽象数据类型如何表示?示?Typedef struct /定义每个记录(数据元素)的结构 KeyType k
3、ey;/关键字 InfoType otherinfo;/其它数据项RecordType;Typedef struct /定义顺序表的结构 RecordType r MAXSIZE+1;/存储顺序表的向量 /r0一般作哨兵或缓冲区 int length;/顺序表的长度SqList;#define MAXSIZE 20 /设记录不超过20个typedef int KeyType;/设关键字为整型量(int型)第4页/共103页57.内部排序的算法有哪些?内部排序的算法有哪些?按排序的规则不同,可分为5类:插入排序交换排序(重点是快速排序)选择排序归并排序基数排序d关键字的位数(长度)按排序算法的时
4、间复杂度不同,可分为3类:简单的排序算法:时间效率低,O(n2)先进的排序算法:时间效率高,O(nlog2n)基数排序算算法:时间效率高,O(dn)第5页/共103页69.2 9.2 插入排序插入排序的基本思想是:插入排序的基本思想是:插入排序有多种具体实现算法:1)直接插入排序 2)折半插入排序 3)2-路插入排序 4)表插入排序 5)希尔排序 每步将一个待排序的对象,每步将一个待排序的对象,按其关键码大小,按其关键码大小,插入到前面插入到前面已经排好序的一组对象已经排好序的一组对象的的适当位置适当位置上上,直到对象全部插入为止。,直到对象全部插入为止。简言之,边插入边排序,保证子序列中随时
5、都是排好序的。简言之,边插入边排序,保证子序列中随时都是排好序的。第6页/共103页71)1)直接插入排序直接插入排序直接插入排序直接插入排序新元素插入到哪里?例1:关键字序列T=(13,6,3,31,9,27,5,11),请写出直接插入排序的中间过程序列。【13】,6,3,31,9,27,5,11【6,13】,3,31,9,27,5,11【3,6,13】,31,9,27,5,11【3,6,13,31】,9,27,5,11【3,6,9,13,31】,27,5,11【3,6,9,13,27,31】,5,11【3,5,6,9,13,27,31】,11【3,5,6,9,11,13,27,31】在已形
6、成的有序表中线性查找,并在适当位置插入,把原来位置上的元素向后顺移。最简单的排序法!最简单的排序法!第7页/共103页8例例2 2:关键字序列T=(21,25,49,25*,16,08),请写出直接插入排序的具体实现过程。*表示后一个25i i=1 121212525494925*25*161608080 1 2 3 4 5 6暂暂存存2121i i=2 2i i=3 3i i=5 5i i=4 4i i=6 62525252525494949494925*25*25*494916161625*25*0808084949解:假设该序列已存入一维数组V7中,将V0作为缓冲或暂存单元(Temp)。
7、则程序执行过程为:21212525494925*25*2121初态:1616494925*25*2525212116160808完成!时间效率:O(nO(n2 2)因为在最坏情况下,所有元素的比较次数总和为(01n-1)O(n2)。其他情况下还要加上移动元素的次数。空间效率:OO(1 1)因为仅占用1个缓冲单元算法的稳定性:稳定稳定因为25*排序后仍然在25的后面。对应程序参见教材P265。第8页/共103页9n n若设待排序的对象个数为若设待排序的对象个数为n n,则算法需要进行,则算法需要进行n n-1-1次插入。次插入。n n最好情况下,排序前对象已经按关键码大小从最好情况下,排序前对象
8、已经按关键码大小从小到大有序,每趟只需与前面的有序对象序列小到大有序,每趟只需与前面的有序对象序列的的最后一个对象最后一个对象的关键码比较的关键码比较 1 1 次,移动次,移动 2 2 次对象。因此,总的关键码比较次数为次对象。因此,总的关键码比较次数为n n-1-1,对象移动次数为对象移动次数为 2(2(n n-1)-1)。直接插入排序的算法分析直接插入排序的算法分析直接插入排序的算法分析直接插入排序的算法分析第9页/共103页10最坏情况下,第最坏情况下,第i i趟插入时,第趟插入时,第i i个对象必须与个对象必须与前面前面i-1i-1个对象都做关键码比较,并且每做个对象都做关键码比较,并
9、且每做 1 1 次比较就要做次比较就要做 1 1 次数据移动。则总的关键码次数据移动。则总的关键码比较次数比较次数KCNKCN和对象移动次数和对象移动次数RMNRMN分别为分别为第10页/共103页11若待排序对象序列中出现各种可能排列的概率相同,若待排序对象序列中出现各种可能排列的概率相同,则可取上述最好情况和最坏情况的平均情况。在平均则可取上述最好情况和最坏情况的平均情况。在平均情况下的关键码比较次数和对象移动次数约为情况下的关键码比较次数和对象移动次数约为 n n2 2/4/4。因此,直接插入排序的时间复杂度为因此,直接插入排序的时间复杂度为 o(o(n n2 2)。直接插入排序是一种稳
10、定的排序方法。直接插入排序是一种稳定的排序方法。第11页/共103页122 2)折半插入排序折半插入排序折半插入排序折半插入排序优点:比较的次数大大减少,全部元素比较次数仅为O(nlog2n)。时间效率:虽然比较次数大大减少,可惜移动次数并未减少,所以排序效率仍为O(n2)。空间效率:O(1)稳定性:稳定 对应程序见教材对应程序见教材P267P267(仅用于顺序表)(仅用于顺序表)新元素插入到哪里?讨论:若记录是链表结构,用直接插入排序行否?折半插入排序呢?答:直接插入不仅可行,而且还无需移动元素,时间效率更高!自测卷上有对应的程序设计题。折半插入排序的改进折半插入排序的改进2-2-路插入排序
11、见教材路插入排序见教材P267P267。在已形成的有序表中折半查找,并在适当位置插入,把原来位置上的元素向后顺移。但链表无法但链表无法“折半折半”!第12页/共103页13折半插入排序的算法分析折半插入排序的算法分析折半插入排序的算法分析折半插入排序的算法分析折半查找比顺序查找快,所以折半插入排序折半查找比顺序查找快,所以折半插入排序就平均性能来说比直接插入排序要快。就平均性能来说比直接插入排序要快。在插入第在插入第 i i 个对象时,需要经过个对象时,需要经过 loglog2 2i i +1+1 次关键码比较,才能确定它应插入的位置。次关键码比较,才能确定它应插入的位置。因此,将因此,将 n
12、 n 个对象用折半插入排序所进行的个对象用折半插入排序所进行的关键码比较次数为:关键码比较次数为:n*logn*log2 2n n折半插入排序是一个稳定的排序方法。折半插入排序是一个稳定的排序方法。第13页/共103页144 4)表插入排序)表插入排序)表插入排序)表插入排序基本思想基本思想:在顺序存储结构中,给每个记录增开一个指针分:在顺序存储结构中,给每个记录增开一个指针分量,在排序过程中将指针内容逐个修改为已经整理(排序)量,在排序过程中将指针内容逐个修改为已经整理(排序)过的后继记录地址。过的后继记录地址。优点:优点:在排序过程中不移动元素,只修改指针。在排序过程中不移动元素,只修改指
13、针。回忆:链表排序排序时只移动指针;地址排序排序时先移动地址,最后再移动记录。此方法具有链表排序和地址排序的特点。此方法具有链表排序和地址排序的特点。第14页/共103页151例:例:关键字序列 T=(21,25,49,25*,16,08),请写出表插入排序的具体实现过程。解:假设该序列(结构类型)已存入一维数组V7中,将V0作为表头结点。则算法执行过程为:i 关键字关键字 Vi.key指针指针 Vi.link0 MaxNum1212253494 25*516608指向第1个元素指向头结点初态初态i=1i=1i=2i=2i=3i=3i=4i=4i=5i=5i=6i=6034 45 5 6 65
14、 503 31 102*表示后一个25第15页/共103页16int LinkInsertSort(staticlinklis&list)list.v0.Key=MaxNum;list.v0.Link=1;list.v1.Link=0;/形成循环链表表插入排序的算法表插入排序的算法表插入排序的算法表插入排序的算法for(int i=2;i=list.length;i+)int current=list.v0.Link;/current=当前记录指针 int pre=0;/pre=当前记录current的前驱指针 while(list.vcurrent.Key link)list.vi.Link
15、=current;/新记录vi找到合适序位开始插入 list.vpre.Link=i;/在pre与current之间链入 第16页/共103页17表插入排序算法分析:表插入排序算法分析:无需移动记录,只需修改2n次指针值。但由于比较次数没有减少,故时间效率仍为O(n2)。空间效率肯定低,因为增开了指针分量(但在运算过程中没有用到更多的辅助单元)。稳定性:25和25*排序前后次序未变,稳定。讨论:此算法得到的只是一个有序链表,查找记录时只能满足顺序查找方式。改进:可以根据表中指针线索,很快对所有记录重排,形成真正的有序表(顺序存储方式),从而能满足折半查找方式。具体实现见教材P269。第17页/
16、共103页185 5)希尔()希尔()希尔()希尔(shellshell)排序)排序)排序)排序(又称缩小增量排序(又称缩小增量排序(又称缩小增量排序(又称缩小增量排序)基本思想基本思想:先将整个待排记录序列分割成若干子序列:先将整个待排记录序列分割成若干子序列,分分别进行直接插入排序,待整个序列中的记录别进行直接插入排序,待整个序列中的记录“基本有序基本有序”时,再对全体记录进行一次直接插入排序。时,再对全体记录进行一次直接插入排序。技巧:技巧:子序列的构成不是简单地子序列的构成不是简单地“逐段分割逐段分割”,而是将,而是将相隔某个增量相隔某个增量dkdk的记录组成一个子序列的记录组成一个子
17、序列,让增量让增量dkdk逐趟缩逐趟缩短(例如依次取短(例如依次取5,3,15,3,1),直到),直到dkdk1 1为止。为止。优点:优点:让关键字值小的元素能很快前移,且序列若基本让关键字值小的元素能很快前移,且序列若基本有序时,再用直接插入排序处理,时间效率会高很多。有序时,再用直接插入排序处理,时间效率会高很多。第18页/共103页1938例:关键字序列 T=(49,38,65,97,76,13,27,49*,55,04),请写出希尔排序的具体实现过程。0123456789104938659776132749*5504初态:第1趟(dk=5)第2趟(dk=3)第3趟(dk=1)49131
18、34938276549*975576042738 65 49*9755135576045513270427044949*4949*763876 65 65 9797551327044949*3876 65 9713 27 0449*76 97 算法分析:开始时dk 的值较大,子序列中的对象较少,排序速度较快;随着排序进展,dk 值逐渐变小,子序列中对象个数逐渐变多,由于前面工作的基础,大多数对象已基本有序,所以排序速度仍然很快。riri第19页/共103页20void ShellSort(SqList&L,int dlta,int t)/按增量序列dlta0t-1对顺序表L作Shell排序 f
19、or(k=0;kt;+k)ShellSort(L,dltak);/增量为dltak的一趟插入排序 /ShellSort时间效率:时间效率:空间效率:OO(1 1)因为仅占用1个缓冲单元算法的稳定性:不稳定不稳定因为49*排序后却到了49的前面希尔排序算法希尔排序算法(主程序)(主程序)参见教材P272O(O(n n1.251.25)OO(1.61.6n n1.251.25)经验公式dk值依次装在dltat中第20页/共103页21附:希尔排序附:希尔排序附:希尔排序附:希尔排序算法分析算法分析算法分析算法分析对对特特定定的的待待排排序序对对象象序序列列,可可以以准准确确地地估估算算关关键键码码
20、的的比比较较次次数数和和对对象象移移动动次次数数。但但想想要要弄弄清清关关键键码码比比较较次次数数和和对对象象移移动动次次数数与与增增量量选选择择之之间间的的依依赖赖关关系系,并并给给出出完完整整的的数数学学分分析析,还还没没有人能够做到。有人能够做到。KnuthKnuth利利用用大大量量的的实实验验统统计计资资料料得得出出,当当n n很很大大时时,关关键键码码平平均均比比较较次次数数和和对对象象平平均均移移动动次次数数大大约约在在 n n1.251.25 到到 1.61.6n n1.251.25 的的范范围围内内。这这是是在在利利用用直直接接插插入入排排序序作作为为子子序序列列排排序序方方法
21、法的的情情况况下下得得到到的。的。第21页/共103页22void ShellInsert(SqList&L,int dk)for(i=dk+1;i=L.length;+i)if(ri.key 0&(r0.keyrj.key);j=j-dk)rj+dk=rj;rj+dk=r0;希尔排序算法希尔排序算法希尔排序算法希尔排序算法(其中某一趟的排序操作)(其中某一趟的排序操作)(其中某一趟的排序操作)(其中某一趟的排序操作)参见教材P272/对顺序表L进行一趟增量为dk的Shell排序,dk为步长因子/开始将ri 插入有序增量子表/暂存在r0/关键字较大的记录在子表中后移/在本趟结束时将ri插入到正
22、确位置第22页/共103页23课堂练习:1.欲将序列(Q,H,C,Y,P,A,M,S,R,D,F,X)中的关键码按字母升序重排,则初始步长为4的希尔排序一趟的结果是?答:原始序列:Q,H,C,Y,P,A,M,S,R,D,F,X shell一趟后:2.以关键字序列(256,301,751,129,937,863,742,694,076,438)为例,分别写出执行以下算法的各趟排序结束时,关键字序列的状态,并说明这些排序方法中,哪些易于在链表(包括各种单、双、循环链表)上实现?直接插入排序 希尔排序(取dk=5,3,1)P,Q,R,A,D,H,C,F,M,S,X,Y答:显然,直接插入排序方法易于在
23、链表上实现;但希尔排序方法因为是按增量选择记录,不易于在链表上实现。两种排序方法的中间状态分别描述如后:第23页/共103页24原始序列:原始序列:256256,301301,751751,129129,937937,863863,742742,694694,076076,438438256,301,751,129,937,863,742,694,076,438256,301,751,129,937,863,742,694,076,438129,256,301,751,937,863,742,694,076,438129,256,301,751,937,863,742,694,076,4381
24、29,256,301,751,863,937,742,694,076,438129,256,301,742,751,863,937,694,076,438129,256,301,694,742,751,863,937,076,438076,129,256,301,694,742,751,863,937,438076,129,256,301,438,694,742,751,863,937第1趟第2趟第3趟第4趟第5趟第6趟第7趟第8趟第9趟第24页/共103页25原始序列:原始序列:256256,301301,751751,129129,937937,863863,742742,694694,0
25、76076,438438(取取dk=5,3,1)dk=5,3,1)256,301,751,129,937,863,742,694,076,438256,301,751,129,937,863,742,694,076,438256,301,694,129,937,863,742,751,076,438256,301,694,076,937,863,742,751,129,438256,301,694,076,438,863,742,751,129,937第1趟dk=5第2趟dk=3第3趟dk=1256,301,694,076,438,863,742,751,129,937256,301,694,
26、076,438,863,742,751,129,937076,301,694,256,438,863,742,751,129,937076,301,694,256,438,863,742,751,129,937076,301,694,256,438,863,742,751,129,937076,301,129,256,438,694,742,751,863,937076,301,129,256,438,694,742,751,863,937076,301,129,256,438,694,742,751,863,937076,129,256,301,438,694,742,751,863,937
27、第25页/共103页269.3 9.3 交换排序 两两比较待排序记录的关键两两比较待排序记录的关键码,如果发生逆序(即排列顺序与排序后的次序正好码,如果发生逆序(即排列顺序与排序后的次序正好相反),则交换之,直到所有记录都排好序为止。相反),则交换之,直到所有记录都排好序为止。交换排序的主要算法有:1)冒泡排序 2)快速排序交换排序的基本思想是:交换排序的基本思想是:第26页/共103页27 1)冒泡排序冒泡排序冒泡排序冒泡排序基本思路:每趟不断将记录两两比较,并按“前小后大”(或“前大后小”)规则交换。优点:每趟结束时,不仅能挤出一个最大值到最后面位置,还能同时部分理顺其他元素;一旦下趟没有
28、交换发生,还可以提前结束排序。前提:顺序存储结构 例:关键字序列 T=(21,25,49,25*,16,08),请写出冒泡排序的具体实现过程。21,25,49,25*,16,0821,25,25*,16,08,4921,25,16,08,25*,4921,16,08,25,25*,4916,08,21,25,25*,4908,16,21,25,25*,49初态:第1趟第2趟第3趟第4趟第5趟第27页/共103页28冒泡排序的算法分析冒泡排序的算法分析时间效率:时间效率:OO(n n2 2)因为要考虑最坏情况因为要考虑最坏情况空间效率:空间效率:OO(1 1)只在交换时用到一个缓冲单元只在交换时
29、用到一个缓冲单元稳稳 定定 性:性:稳定稳定 2525和和2525*在排序前后的次序未改变在排序前后的次序未改变详细分析:最好情况:初始排列已经有序,只执行一趟起泡,做 n-1 次关键码比较,不移动对象。最坏情形:初始排列逆序,算法要执行n-1趟起泡,第i趟(1 i n)做了n-i 次关键码比较,执行了n-i 次对象交换。此时的比较总次数KCN和记录移动次数RMN为:第28页/共103页292 2)快速排序快速排序快速排序快速排序 从待排序列中任取一个元素从待排序列中任取一个元素 (例如取第一个例如取第一个)作为中心,作为中心,所有比它小的元素一律前放,所有比它大的元素一律后放,所有比它小的元
30、素一律前放,所有比它大的元素一律后放,形成左右两个子表;然后再对各子表重新选择中心元素并形成左右两个子表;然后再对各子表重新选择中心元素并依此规则调整,直到每个子表的元素只剩一个。此时便为依此规则调整,直到每个子表的元素只剩一个。此时便为有序序列了。有序序列了。基本思想:基本思想:优点:优点:因为每趟可以确定不止一个元素的位置,而且呈指数增因为每趟可以确定不止一个元素的位置,而且呈指数增加,所以特别快!加,所以特别快!前提:前提:顺序存储结构顺序存储结构 第29页/共103页30(),设以首元素为枢轴中心例1:关键字序列 T=(21,25,49,25*,16,08),请写出快速排序的算法步骤。
31、21,25,49,25*,16,08初态:第1趟:第2趟:第3趟:讨论:讨论:1.1.这种不断划分子表的过程,计算机如何自动实现?这种不断划分子表的过程,计算机如何自动实现?2.2.“快速排序快速排序”是否真的比任何排序算法都快?是否真的比任何排序算法都快?08,16,21,25,25*,(49)2116,08,()25,25*,49(08),16,21,25,(25*,49)第30页/共103页311.1.1.1.这种不断划分子表的过程,计算机如何自动实现这种不断划分子表的过程,计算机如何自动实现这种不断划分子表的过程,计算机如何自动实现这种不断划分子表的过程,计算机如何自动实现?编程时:每
32、一趟的子表的形成是采用从两头向中间交替式逼近法;由于每趟中对各子表的操作都相似,主程序可采用递归算法。见教材P275int PartitionPartition(SqList&L,int low,int high)/一趟快排/交换子表 rlowhigh的记录,使支点(枢轴)记录到位,并返回其位置。返回时,在支点之前的记录均不大于它,支点之后的记录均不小于它。r0=rlow;/以子表的首记录作为支点记录,放入r0单元(续下页)一趟快速排序算法(针对一个子表的操作)第31页/共103页32pivotkey=rlow.key;/取支点的关键码存入pivotkey变量while(low high)/从
33、表的两端交替地向中间扫描while(low=pivotkey)-high;-high;rlow=rhigh;/将比支点小的记录交换到低端;while(lowhigh&rlow.key=pivotkey)+low;+low;rhigh=rlow;/将比支点大的记录交换到高端;rlow=r0;/支点记录到位;return low;/返回支点记录所在位置。/PartitionPartition第32页/共103页33Low=high=Low=high=3 3,本趟停止,将本趟停止,将支点定位并返回位置信息支点定位并返回位置信息例2:关键字序列 T=(21,25,49,25*,16,08),请写出快速
34、排序算法的一趟实现过程。ri0123456初态初态21254925*1608第第1趟趟highlow210825164925*321pivotkey=2108251649(08,16)21 (25*,49,25 )2525*跑到了前面,跑到了前面,不稳定不稳定!第33页/共103页34j从高端扫描寻找小于pivot的元素i从低端扫描寻找大于pivot的元素i=low;j=high;r0=rlow;pivot=rlow.key;i ji=pivot-j;ri=rj;i j&ri.key=pivot-i;rj=ri;ri=r0;return ok;Y YY YY YN NN NN N一趟快速排序算
35、法流程图一趟快速排序算法流程图一趟快速排序算法流程图一趟快速排序算法流程图第34页/共103页35void QSort(SqList&L,int low,int high)if(low 1/对顺序表L中的子序列r lowhigh 作快速排序/一趟快排,将r 一分为二/在左子区间进行递归快排,直到长度为1/在右子区间进行递归快排,直到长度为1/QSort新的lowvoid void Q QuickuickSort Sort(SqList SqList&L)&L)QSort QSort(L,(L,1,L.length););对顺序表对顺序表L L进行快速进行快速排序的操作函数为:排序的操作函数为:
36、第35页/共103页36例3:以关键字序列(256,301,751,129,937,863,742,694,076,438)为例,写出执行快速算法的各趟排序结束时,关键字序列的状态。原始序列:256,301,751,129,937,863,742,694,076,438第1趟第2趟第3趟第4趟256,301,751,129,937,863,742,694,076,438076076,129,256256,751751,937,863,742,694,301,438要求模拟算法实现步骤256256076301129751256256076076,129,256256,438,301,694,74
37、2,694,863,937751751076076,129129,256256,438438,301,694,742,751751,863863,937076076,129129,256256,301,301,694,742,751751,863863,937438438076076,129129,256256,301301,438438,694694,742,751751,863863,937937时间效率:时间效率:O(nlogO(nlog2 2n)n)因为每趟确定的元素呈指数增加因为每趟确定的元素呈指数增加空间效率:空间效率:OO(loglog2 2n n)因为算法的递归性,要用到栈空间
38、因为算法的递归性,要用到栈空间稳稳 定定 性:性:不稳定不稳定 因为可选任一元素为支点。因为可选任一元素为支点。第36页/共103页37快速排序算法详细分析:快速排序算法详细分析:快速排序算法详细分析:快速排序算法详细分析:快速排序是递归的,需要有一个栈存放每层递归调用时的指针和参数(新的low和high)。可以证明,函数quicksort的平均计算时间也是O(nlog2n)。实验结果表明:就平均计算时间而言,快速排序是我们所讨论的所有内排序方法中最好的一个。最大递归调用层次数与递归树的深度一致,理想情况为 log2(n+1)。因此,要求存储开销为 o(log2n)。如果每次划分对一个对象定位
39、后,该对象的左侧子序列与右侧子序列的长度相同,则下一步将是对两个长度减半的子序列进行排序,这是最理想的情况。此时,快速排序的趟数最少。第37页/共103页38在最坏的情况,即待排序对象序列已经按其关键码从小到大排好序的情况下,其递归树成为单支树,每次划分只得到一个比上一次少一个对象的子序列。这样,必须经过 n-1 趟才能把所有对象定位,而且第 i 趟需要经过 n-i 次关键码比较才能找到第 i 个对象的安放位置,总的关键码比较次数将达到n2/2 快速排序是一个不稳定的排序方法第38页/共103页39讨论讨论讨论讨论2.2.2.2.“快速排序快速排序快速排序快速排序”是否真的比任何排序算法都快是
40、否真的比任何排序算法都快是否真的比任何排序算法都快是否真的比任何排序算法都快?设每个子表的支点都在中间(比较均衡),则:第1趟比较,可以确定1个元素的位置;第2趟比较(2个子表),可以再确定2个元素的位置;第3趟比较(4个子表),可以再确定4个元素的位置;第4趟比较(8个子表),可以再确定8个元素的位置;只需log2n 1趟便可排好序。基本上是!因为每趟可以确定的数据元素是呈指数增加的!基本上是!因为每趟可以确定的数据元素是呈指数增加的!而且,每趟需要比较和移动的元素也呈指数下降,加上编程时使用了交替逼近技巧,更进一步减少了移动次数,所以速度特别快。教材P276有证明:快速排序的平均排序效率为
41、O(nlog2n);但最坏情况(例如已经有序)下仍为O(n2),改进措施见P277。第39页/共103页40 基本思想是:每一趟(例如第 i 趟,i=0,1,n-2)在后面 n-i 个待排序对象中选出排序码最小的对象,作为有序对象序列的第 i 个对象。待到第 n-2 趟作完,待排序对象只剩下1个,就不用再选了。9.4 选择排序选择排序第40页/共103页41 若若它它不不是是这这组组对对象象中中的的第第一一个个对对象象,则则将将它它与与这这组组对对象象中中的的第第一一个个对对象象对对调调;在在这这组组对对象象中中剔剔除除这这个个具具有有最最小小排排序序码码 的的 对对 象象。在在 剩剩 下下
42、的的 对对 象象 Vi+1Vn-1中中重重复复执执行行第第、步步,直直到到剩剩余对象只有一个为止。余对象只有一个为止。n n直接选择排序是一种简单的排序方法,它的基本步骤是:在一组对象 ViVn-1 中选择具有最小排序码的对象;直接选择排序(Select Sort)第41页/共103页4221212525494925*25*161608080 1 2 3 4 5212125*25*i=0=04949252516162525161608084949080825*25*49492121i=1=1i=2=20808161625*25*25252121初始初始最小者 0808交换交换21,0821,0
43、8最小者 1616交换交换25,1625,16最小者 2121交换交换49,2149,21第42页/共103页43494925*25*0 1 2 3 4 525*25*i=4=4252516160808494925*25*49492121结果i=3=30808161625252121最小者 25*25*无交换无交换最小者 2525无交换无交换2525212116160808各趟排序后的结果第43页/共103页44 直接选择排序的算法typedef int SortData;void SelectSort(SortData V,int n)for(int i=0;i n-1;i+)int k=i
44、;/选择具有最小排序码的对象 for(int j=i+1;j n;j+)if(Vj Vk)k=j;/当前具最小排序码的对象 if(k!=i)/对换到第 i 个位置 Swap(Vi,Vk);第44页/共103页450 1 2 3 4 549491616080825*25*49492121080825*25*25252121i=1时选择排序的过程i k j 49492525080825*25*16162121i k j 49 49 25 2525*25*25 2516162525i k j 16 2516 25第45页/共103页4649492525080825*25*161621210 1 2
45、3 4 5i k j 21 21 16 16k k 指示当前序列中最小者指示当前序列中最小者n n直接选择排序的排序码比较次数 KCN 与对象的初始排列无关。设整个待排序对象序列有 n 个对象,则第 i 趟选择具有最小排序码对象所需的比较次数总是 n-i-1 次。总的排序码比较次数为第46页/共103页47锦标赛排序锦标赛排序(Tournament Tree Sort)它的思想与体育比赛时的淘汰赛类似。首先取它的思想与体育比赛时的淘汰赛类似。首先取它的思想与体育比赛时的淘汰赛类似。首先取它的思想与体育比赛时的淘汰赛类似。首先取得得得得 n n 个对象的关键码,进行两两比较,得到个对象的关键码,
46、进行两两比较,得到个对象的关键码,进行两两比较,得到个对象的关键码,进行两两比较,得到 n n/2/2 个比较的优胜者个比较的优胜者个比较的优胜者个比较的优胜者(关键码小者关键码小者关键码小者关键码小者),作为第,作为第,作为第,作为第一步比较的结果保留下来。然后对这一步比较的结果保留下来。然后对这一步比较的结果保留下来。然后对这一步比较的结果保留下来。然后对这 n n/2/2 个对象再进行关键码的两两比较,个对象再进行关键码的两两比较,个对象再进行关键码的两两比较,个对象再进行关键码的两两比较,如此重,如此重,如此重,如此重复,直到选出一个关键码最小的对象为止。复,直到选出一个关键码最小的对
47、象为止。复,直到选出一个关键码最小的对象为止。复,直到选出一个关键码最小的对象为止。在图例中,最下面是对象排列的初始状态,相在图例中,最下面是对象排列的初始状态,相在图例中,最下面是对象排列的初始状态,相在图例中,最下面是对象排列的初始状态,相当于一棵满二叉树的叶结点,它存放的是所有当于一棵满二叉树的叶结点,它存放的是所有当于一棵满二叉树的叶结点,它存放的是所有当于一棵满二叉树的叶结点,它存放的是所有参加排序的对象的关键码。参加排序的对象的关键码。参加排序的对象的关键码。参加排序的对象的关键码。第47页/共103页48如如果果 n n 不不是是2 2的的 k k 次次幂幂,则则让让叶叶结结点点
48、数数补补足足到到满满足足 2 2k k-1 1 n n 2 2k k 的的2 2k k个个。叶叶结结点点上上面面一一层层的的非非叶叶结结点点是是叶叶结结点关键码两两比较的结果。最顶层是树的根。点关键码两两比较的结果。最顶层是树的根。0808Winner Winner 212108080808636325*25*212121212525494925*25*161608086363treetree7 7 treetree8 8 treetree9 9 treetree10 10 treetree11 11 treetree12 12 treetree13 13 treetree1414第48页/共
49、103页49胜者树的概念胜者树的概念每每每每次次次次两两两两两两两两比比比比较较较较的的的的结结结结果果果果是是是是把把把把关关关关键键键键码码码码小小小小者者者者作作作作为为为为优优优优胜胜胜胜者者者者上升到双亲结点,称这种比赛树为胜者树。上升到双亲结点,称这种比赛树为胜者树。上升到双亲结点,称这种比赛树为胜者树。上升到双亲结点,称这种比赛树为胜者树。位位位位于于于于最最最最底底底底层层层层的的的的叶叶叶叶结结结结点点点点叫叫叫叫做做做做胜胜胜胜者者者者树树树树的的的的外外外外结结结结点点点点,非非非非叶叶叶叶结结结结点点点点称称称称为为为为胜胜胜胜者者者者树树树树的的的的内内内内结结结结点
50、点点点。每每每每个个个个结结结结点点点点除除除除了了了了存存存存放放放放对对对对象象象象的的的的关关关关键键键键码码码码 data data 外外外外,还还还还存存存存放放放放了了了了此此此此对对对对象象象象是是是是否否否否要要要要参参参参选选选选的的的的标标标标志志志志 Active Active 和和和和此此此此对对对对象象象象在在在在满满满满二二二二叉叉叉叉树树树树中中中中的的的的序序序序号号号号indexindex。胜者树最顶层是树的根,表示最后选择出来的具胜者树最顶层是树的根,表示最后选择出来的具胜者树最顶层是树的根,表示最后选择出来的具胜者树最顶层是树的根,表示最后选择出来的具有最