第9章内部排序A_第1页
第9章内部排序A_第2页
第9章内部排序A_第3页
第9章内部排序A_第4页
第9章内部排序A_第5页
已阅读5页,还剩35页未读 继续免费阅读

下载本文档

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

文档简介

1、1数据结构课程的内容数据结构课程的内容29.1 9.1 概述概述9.2 9.2 插入排序插入排序9.3 9.3 交换排序交换排序9.4 9.4 选择排序选择排序9.5 9.5 归并排序归并排序9.6 9.6 基数排序基数排序39.1 9.1 概述概述1. 什么是排序?什么是排序? 将一组杂乱无章的将一组杂乱无章的数据数据按一定的按一定的规律规律顺次排列起来。顺次排列起来。2. 排序的目的是什么?排序的目的是什么?存放在数据表中存放在数据表中按关键字排序按关键字排序3.3.排序算法的好坏如何衡量?排序算法的好坏如何衡量? 时间效率时间效率排序速度(即排序所花费的全部比较次数)排序速度(即排序所花

2、费的全部比较次数) 空间效率空间效率占内存辅助空间的大小占内存辅助空间的大小 稳定性稳定性若两个记录若两个记录A A和和B B的关键字值相等,但排序后的关键字值相等,但排序后A A、B B的先后次序保持不变,则称这种排序算法是稳定的。的先后次序保持不变,则称这种排序算法是稳定的。 便于查找!便于查找!44. 什么叫内部排序?什么叫外部排序?什么叫内部排序?什么叫外部排序? 若待排序记录都在内存中,称为内部排序;若待排序记录都在内存中,称为内部排序;若待排序记录一部分在内存,一部分在外存,则若待排序记录一部分在内存,一部分在外存,则称为外部排序。称为外部排序。注:注:外部排序时,要将数据分批调入

3、内存来排序,中间外部排序时,要将数据分批调入内存来排序,中间结果还要及时放入外存,显然外部排序要复杂得多。结果还要及时放入外存,显然外部排序要复杂得多。 5.5.待排序记录在内存中怎样存储和处理?待排序记录在内存中怎样存储和处理? 顺序顺序排序排序排序时直接移动记录;排序时直接移动记录; 链表链表排序排序排序时只移动指针;排序时只移动指针; 地址地址排序排序排序时先移动地址,最后再移动记录。排序时先移动地址,最后再移动记录。注:注:地址排序地址排序中可以增设一维数组来专门存放记录的地址。中可以增设一维数组来专门存放记录的地址。5注:注:大多数排序算法都是针对顺序表结构的大多数排序算法都是针对顺

4、序表结构的( (便于直接移动元素便于直接移动元素) )6. 6. 顺序存储(顺序表)的抽象数据类型如何表示?顺序存储(顺序表)的抽象数据类型如何表示?Typedef struct /定义每个记录(数据元素)的结构定义每个记录(数据元素)的结构 KeyType key ; /关键字关键字 InfoType otherinfo; /其它数据项其它数据项RecordType ;Typedef struct /定义顺序表的结构定义顺序表的结构 RecordType r MAXSIZE +1 ; /存储顺序表的向量存储顺序表的向量 /r0/r0一般作哨兵或缓冲区一般作哨兵或缓冲区 int length

5、; /顺序表的长度顺序表的长度SqList ;# define MAXSIZE 20 /设记录不超过设记录不超过2020个个typedef int KeyType ; /设关键字为整型量(设关键字为整型量(intint型)型)67. 内部排序的算法有哪些?内部排序的算法有哪些?按排序的规则不同,可分为按排序的规则不同,可分为5类:类:插入排序插入排序交换排序(重点是快速排序)交换排序(重点是快速排序)选择排序选择排序归并排序归并排序基数排序基数排序d关键字的位数关键字的位数(长度长度)按排序算法的时间复杂度不同,可分为按排序算法的时间复杂度不同,可分为3类:类:简单的排序算法:时间效率低,简单

6、的排序算法:时间效率低,O(n2)先进的排序算法先进的排序算法: 时间效率高,时间效率高,O( nlog2n )基数排序算算法:时间效率高,基数排序算算法:时间效率高,O( dn)79.2 9.2 插入排序插入排序插入排序有多种具体实现算法:插入排序有多种具体实现算法: 1) 直接插入排序直接插入排序 2) 折半插入排序折半插入排序 3) 表插入排序表插入排序 4) 希尔排序希尔排序8新元素插入到哪里?新元素插入到哪里?例例1 1:关键字序列关键字序列T=(13,6,3,31,9,27,5,11),), 请写出直接插入排序的中间过程序列。请写出直接插入排序的中间过程序列。【13】, 6, 3,

7、 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】 在已形成的在已形成的有序表中有序表中线性查找线性查找,并在,并在适当位置插入,把原来位置上的元素向后适当位置插入,把原来位置上的元素向后顺移顺移。9例例2 2:关键字序列关键字序列T=

8、 (21,25,49,25*,16,08),),请写出直接插入排序的具体实现过程。请写出直接插入排序的具体实现过程。* *表示后一个表示后一个25250 1 2 3 4 5 6254925*1608解:解:假设该序列已存入一维数组假设该序列已存入一维数组V7V7中,将中,将V0V0作为缓冲或作为缓冲或暂存单元(暂存单元(TempTemp)。则程序执行过程为:)。则程序执行过程为:初态:初态:时间效率:时间效率: 因为在最坏情况下,所有元素的比较因为在最坏情况下,所有元素的比较次数总和为(次数总和为(0 01 1n-1)O(nn-1)O(n2 2) )。其他情况。其他情况下还要加上移动元素的次数

9、。下还要加上移动元素的次数。 空间效率:空间效率:因为仅占用因为仅占用1 1个缓冲单元个缓冲单元算法的稳定性:算法的稳定性:因为因为2525* *排序后仍然在排序后仍然在2525的后面。的后面。 对应程序参见教材对应程序参见教材P265P265。1011111122142221nininnniRMNnnniKCN/)()( ,/)(221213优点:优点:比较的次数大大减少,全部元素比较次数仅为比较的次数大大减少,全部元素比较次数仅为O(nlogO(nlog2 2n)n)。时间效率:时间效率:虽然比较次数大大减少,可惜移动次数并未减少,虽然比较次数大大减少,可惜移动次数并未减少,所以排序效率仍

10、为所以排序效率仍为O(nO(n2 2) ) 。空间效率:空间效率: O O(1 1)稳定性:稳定性:稳定稳定新元素插入到哪里?新元素插入到哪里?讨论:讨论:若记录是链表结构,用直接插入排序行否?折半插入若记录是链表结构,用直接插入排序行否?折半插入排序呢?排序呢?答:答:直接插入不仅可行,而且还无需移动元素,时间效率更直接插入不仅可行,而且还无需移动元素,时间效率更高!高!自测卷上有对应的程序设计题。自测卷上有对应的程序设计题。 在已形成的在已形成的有序表中有序表中折半查找折半查找,并在适,并在适当位置插入,把原来位置上的元素向后当位置插入,把原来位置上的元素向后顺移顺移。1415回忆:回忆:

11、 链表排序链表排序排序时只移动指针;排序时只移动指针; 地址排序地址排序排序时先移动地址,最后再移动记录。排序时先移动地址,最后再移动记录。161例:例:关键字序列关键字序列 T=(21,25,49,25*,16,08),), 请写出表插入排序的具体实现过程。请写出表插入排序的具体实现过程。解:解:假设该序列(结构类型假设该序列(结构类型) )已存入一维数组已存入一维数组V7V7中,将中,将V0V0作为表头结点。则作为表头结点。则算法执行过程算法执行过程为:为:i 关键字关键字 Vi.key指针指针 Vi.link0 MaxNum1212253494 25*516608指向第指向第1 1个元素

12、个元素指向头结点指向头结点03002* *表示后一个表示后一个252517int 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=/current=当前记录指针当前记录指针 int pre = 0; /pre=/pre=当前记录当前记录current的前驱指针的

13、前驱指针 while ( list.vcurrent. Key linkp=p-link) )list.vi. Link = current; /新记录新记录vi找到合适序位开始插入找到合适序位开始插入 list.vpre. Link = i; /在在prepre与与currentcurrent之间链入之间链入 18表插入排序算法分析:表插入排序算法分析: 无需移动记录,只需修改无需移动记录,只需修改2n次指针值。但由于比较次指针值。但由于比较次数没有减少,故次数没有减少,故时间效率仍为时间效率仍为O(n2) 。 空间效率肯定低空间效率肯定低,因为增开了指针分量(但在运算,因为增开了指针分量(

14、但在运算过程中没有用到更多的辅助单元)。过程中没有用到更多的辅助单元)。 稳定性:稳定性:25和和25*排序前后次序未变,排序前后次序未变,稳定稳定。讨论:讨论:此算法得到的只是一个有序链表,查找记录时只此算法得到的只是一个有序链表,查找记录时只能满足顺序查找方式。能满足顺序查找方式。改进:改进:可以根据表中指针线索,很快对所有记录重排,可以根据表中指针线索,很快对所有记录重排,形成形成真正的有序表(顺序存储方式),从而能满足真正的有序表(顺序存储方式),从而能满足折半查找方式。折半查找方式。具体实现见教材具体实现见教材P269。19)2038例:例:关键字序列关键字序列 T=(49,38,6

15、5,97, 76, 13, 27, 49*,55, 04),),请写出希尔排序的具体实现过程。请写出希尔排序的具体实现过程。0123456789104938659776132749*5504初态:初态:第第1趟趟 (dk=5)第第2趟趟 (dk=3)第第3趟趟 (dk=1)4913134938276549*975576042738 65 49*9755135576045513270427044949*4949*763876 65 65 9797551327044949*3876 65 9713 27 0449* 76 97 算法分析:算法分析:开始时开始时dk 的值较大,子序列中的对象较少,排

16、序速度的值较大,子序列中的对象较少,排序速度较快;随着排序进展,较快;随着排序进展,dk 值逐渐变小,子序列中对象个数值逐渐变小,子序列中对象个数逐渐变多,由于前面工作的基础,大多数对象已基本有序,逐渐变多,由于前面工作的基础,大多数对象已基本有序,所以排序速度仍然很快。所以排序速度仍然很快。21void ShellSort(SqList &L,int dlta ,int t) /按增量序列按增量序列dlta0t-1对顺序表对顺序表L作作Shell排序排序 for(k=0;kt;+k) ShellSort(L,dltak); /增量为增量为dltak的一趟插入排序的一趟插入排序 / S

17、hellSort时间效率:时间效率:空间效率:空间效率:因为仅占用因为仅占用1 1个缓冲单元个缓冲单元算法的稳定性:算法的稳定性:因为因为4949* *排序后却到了排序后却到了4949的前面的前面参见教材参见教材P272P272经验公式经验公式dkdk值依次装在值依次装在dltadltat t 中中2223void 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; 参见教材参见教材P272P272/对

18、顺序表对顺序表L进行一趟增量为进行一趟增量为dk的的Shell排序,排序,dk为步长因子为步长因子/开始将开始将ri 插入有序增量子表插入有序增量子表/暂存在暂存在r0/关键字较大的记录在子表中后移关键字较大的记录在子表中后移/在本趟结束时将在本趟结束时将ri插入到正确位置插入到正确位置24课堂练习:课堂练习:1. 欲将序列(欲将序列(Q, H, C, Y, P, A, M, S, R, D, F, X)中的关键码按)中的关键码按字母升序重排,则初始步长为字母升序重排,则初始步长为4的希尔排序一趟的结果是?的希尔排序一趟的结果是?答:答:原始序列:原始序列: Q, H, C, Y, P, A,

19、 M, S, R, D, F, X shellshell一趟后:一趟后: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答:答:显然,直接插入排序

20、方法易于在链表上实现;但希尔排显然,直接插入排序方法易于在链表上实现;但希尔排序方法因为是按增量选择记录,不易于在链表上实现。序方法因为是按增量选择记录,不易于在链表上实现。 两种排序方法的中间状态分别描述如后:两种排序方法的中间状态分别描述如后:25原始序列:原始序列: 256256,301301,751751,129129,937937,863863,742742,694694,076076,438438 256256,301301 ,751751,129129,937937,863863,742742,694694,076076,438438 256256,301301,751751 ,

21、129129,937937,863863,742742,694694,076076,438438 129129,256256,301301,751751 ,937937,863863,742742,694694,076076,438438 129129,256256,301301,751751,937937 ,863863,742742,694694,076076,438438 129129,256256,301301,751751,863863,937937 ,742742,694694,076076,438438 129129,256256,301301,742742,751751,863

22、863,937937 ,694694,076076,438438 129129,256256,301301,694694,742742,751751,863863,937937 ,076076,438438 076076,129129,256256,301301,694694,742742,751751,863863,937937 ,438438 076076,129129,256256,301301,438438,694694,742742,751751,863863,937937 第第1趟趟第第2趟趟第第3趟趟第第4趟趟第第5趟趟第第6趟趟第第7趟趟第第8趟趟第第9趟趟26原始序列:原始序

23、列: 256256,301301,751751,129129,937937,863863,742742,694694,076076,438438256256,301301,751751,129129,937937,863863,742742,694694,076076,438438256256,301301,751751,129129,937937,863863,742742,694694,076076,438438256256,301301,694694,129129,937937,863863,742742,751751,076076,438438256256,301301,694694,

24、076076,937937,863863,742742,751751,129129,438438256256,301301,694694,076076,438438,863863,742742,751751,129129,937937第第1趟趟dk=5dk=5第第2趟趟dk=3dk=3第第3趟趟dk=1dk=1256256,301301,694694,076076,438438,863863,742742,751751,129129,937937256256,301301,694694,076076,438438,863863,742742,751751,129129,937937076076

25、,301301,694694,256256,438438,863863,742742,751751,129129,937937076076,301301,694694,256256,438438,863863,742742,751751,129129,937937076076,301301,694694,256256,438438,863863,742742,751751,129129,937937076076,301301,129129,256256,438438,694694,742742,751751,863863,937937076076,301301,129129,256256,43

26、8438,694694,742742,751751,863863,937937076076,301301,129129,256256,438438,694694,742742,751751,863863,937937076076,129129,256256,301301,438438,694694,742742,751751,863863,937937279.3 9.3 交换排序交换排序交换排序的主要算法有:交换排序的主要算法有: 1) 冒泡排序冒泡排序 2) 快速排序快速排序28 1) 基本思路:基本思路:每趟不断将记录两两比较,并按每趟不断将记录两两比较,并按“前小后大前小后大”(或(或“

27、前大后小前大后小”)规则交换。)规则交换。优点:优点:每趟结束时,不仅能挤出一个最大值到最后面位置,每趟结束时,不仅能挤出一个最大值到最后面位置,还能同时部分理顺其他元素;一旦下趟没有交换发还能同时部分理顺其他元素;一旦下趟没有交换发生,还可以提前结束排序。生,还可以提前结束排序。前提:前提:顺序存储结构顺序存储结构 例:例:关键字序列关键字序列 T=(21,25,49,25*,16,08),请写出),请写出冒泡排序的具体实现过程。冒泡排序的具体实现过程。21,25,49, 25*,16, 0821,25,25*,16, 08 , 4921,25, 16, 08 ,25*,4921,16, 0

28、8 ,25, 25*,4916,08 ,21, 25, 25*,4908,16, 21, 25, 25*,49初态:初态:第第1趟趟第第2趟趟第第3趟趟第第4趟趟第第5趟趟29冒泡排序的算法分析冒泡排序的算法分析详细分析:详细分析:最好情况:最好情况:初始排列已经有序,只执行一趟起泡,做初始排列已经有序,只执行一趟起泡,做 n- -1 次关键码比较,不移动对象。次关键码比较,不移动对象。最坏情形:最坏情形:初始排列逆序,初始排列逆序,算法要执行算法要执行n-1 1趟起泡,第趟起泡,第i趟趟(1 i n) 做了做了n- i 次关键码比较,执行了次关键码比较,执行了n-i 次对象交换。次对象交换。

29、此时的比较总次数此时的比较总次数KCN和记录移动次数和记录移动次数RMN为:为:11111233121nininninRMNnninKCN)()()()(3031( ),设以首元素为枢轴中心设以首元素为枢轴中心例例1:关键字序列关键字序列 T=(21,25,49,25*,16,08),),请写出快速排序的算法步骤。请写出快速排序的算法步骤。21, 25, 49, 25*,16, 08初态:初态:第第1趟:趟:第第2趟:趟:第第3趟:趟:08,16,21,25, 25*,(49)2116,08,( )25,25*,49(08),16,21,25,(25*,49)32编程时:编程时:每一趟的子表的

30、形成是采用从两头向中间交替式逼近法;每一趟的子表的形成是采用从两头向中间交替式逼近法;由于每趟中对各子表的操作都相似,主程序可采用递归算法。由于每趟中对各子表的操作都相似,主程序可采用递归算法。见教材见教材P275int int (SqList &L,(SqList &L,int lowint low, ,int highint high) ) /一趟快排一趟快排/交换子表交换子表 rlowhighrlowhigh的记录,使支点(枢轴)记录到位,并返回其位置。的记录,使支点(枢轴)记录到位,并返回其位置。返回时,在支点之前的记录均不大于它,支点之后的记录均不小于它。返回时,在支

31、点之前的记录均不大于它,支点之后的记录均不小于它。 r0=r0=rlowrlow; ; /以子表的首记录作为支点记录,放入以子表的首记录作为支点记录,放入r0r0单元单元(续下页)(续下页)一趟快速排序算法一趟快速排序算法(针对一个子表的操作)(针对一个子表的操作)33pivotkey=pivotkey=rlow.keyrlow.key; ; /取支点的关键码存入取支点的关键码存入pivotkeypivotkey变量变量while(low high)while(low high) /从表的两端交替地向中间扫描从表的两端交替地向中间扫描while(while(lowhighlow=pivotke

32、yrhigh.key=pivotkey ) ) rlow=rhigh; rlow=rhigh; /将比支点小的记录交换到低端;将比支点小的记录交换到低端;while(while(lowhighlowhigh & & rlow.key=pivotkeyrlow.key=pivotkey) ) rhigh=rlow; rhigh=rlow; /将比支点大的记录交换到高端;将比支点大的记录交换到高端;rlow=r0; rlow=r0; /支点记录到位;支点记录到位;return low; return low; /返回支点记录所在位置。返回支点记录所在位置。 /34例例2:关键字序列

33、关键字序列 T=(21,25,49,25*,16,08),请写),请写出快速排序算法的一趟实现过程。出快速排序算法的一趟实现过程。ri0123456初态初态21254925*1608第第1趟趟highhighlowlow210825164925*321pivotkey=pivotkey=212108251649( 08 ,16 ) 21 ( 25* , 49, 25 )35j从高端从高端扫描扫描寻找小于寻找小于pivot的元素的元素i从低端从低端扫描扫描寻找大于寻找大于pivot的元素的元素i=low; j=high;r0=rlow; pivot=rlow.key;i ji =pivot-j;

34、ri = rj;i j &ri.key=pivot-i;rj = ri;ri = r0;return ok;36void QSort ( SqList &L, int low, int high ) if ( low 1/对顺序表对顺序表L中的子序列中的子序列r lowhigh 作快速排序作快速排序/一趟快排,将一趟快排,将r 一分为二一分为二/在左子区间进行递归快排,直到长度为在左子区间进行递归快排,直到长度为1/在右子区间进行递归快排,直到长度为在右子区间进行递归快排,直到长度为1/QSort新的新的low 1, L.length 37例例3:以关键字序列(以关键字序列(2

35、56,301,751,129,937,863,742,694,076,438)为例,写出执行快速算法的)为例,写出执行快速算法的各趟各趟排序排序结束时,关键字序列的状态。结束时,关键字序列的状态。原始序列:原始序列: 256256,301301,751751,129129,937937,863863,742742,694694,076076,438438第第1趟趟第第2趟趟第第3趟趟第第4趟趟256256,301301,751751,129129,937937,863863,742742,694694,076076,438438,129129,937937,863863,742742,694694,301301,438438要求模拟算法实现步骤要求模拟算法实现步骤076076301301129129751751,129129,438438,301301,694694,742742,694694,863863,937937,301301,694694,742742,937937,301301,301301,694694,742742,937937,742742,38快速排序是递归的,需要有一个栈存放每层递归调用时的指快速排序是递归的,需要有一个栈存放每层递归调用时的指针和参数针和参数(新的(新的lowlow和和highhigh)。可以证明,函数可以证明,函数qui

温馨提示

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

评论

0/150

提交评论