《数据结构》课件第9章(内排序).ppt
- 【下载声明】
1. 本站全部试题类文档,若标题没写含答案,则无答案;标题注明含答案的文档,主观题也可能无答案。请谨慎下单,一旦售出,不予退换。
2. 本站全部PPT文档均不含视频和音频,PPT中出现的音频或视频标识(或文字)仅表示流程,实际无音频或视频文件。请谨慎下单,一旦售出,不予退换。
3. 本页资料《《数据结构》课件第9章(内排序).ppt》由用户(momomo)主动上传,其收益全归该用户。163文库仅提供信息存储空间,仅对该用户上传内容的表现方式做保护处理,对上传内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(点击联系客服),我们立即给予删除!
4. 请根据预览情况,自愿下载本文。本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
5. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007及以上版本和PDF阅读器,压缩文件请下载最新的WinRAR软件解压。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 课件 排序
- 资源描述:
-
1、 排序:排序:设含有设含有n个记录的文件个记录的文件R1,R2,,Rn,其其 相应的关键字为相应的关键字为K1,K2,,Kn,需确定,需确定 一种排列一种排列P(1),P(2),P(n),使其相应的关键使其相应的关键 字满足如下的递增字满足如下的递增(或递减或递减)关系:关系:KP(1)KP(2)KP(3)KP(n)即,使上述文件成为一个按其关键字线性即,使上述文件成为一个按其关键字线性 有序的文件有序的文件RP(1),RP(2),,RP(n),这样一这样一 种运算称为排序。种运算称为排序。基本概念基本概念排序的稳定性:排序的稳定性:如果在排序期间具有相同关键字如果在排序期间具有相同关键字的记
2、录的相对位置不变,则称此方法是稳定的。的记录的相对位置不变,则称此方法是稳定的。即,即,1)K(i)K(i+1)(1 i n-1)i n-1)2)2)若在输入文件中若在输入文件中ij,irj.key then ri.count:=ri.count+1;else rj.count:=rj.count+1;For i:=1 to n-1 Do j:=i;while rj.counti Do j:=j+1;if i j then call exchange(ri,rj);End;算法性能分析:算法性能分析:设文件有设文件有n个记录,则外循环:个记录,则外循环:i=1时,内循环要做时,内循环要做n-1
3、次比较;次比较;i=2时,内循环要做时,内循环要做n-2次比较;次比较;i=n-1时,内循环要做时,内循环要做1次比较;次比较;总的比较次数为总的比较次数为(n-1)+(n-2)+1=n(n-1)/2所以,算法所需时间为所以,算法所需时间为O(n2),由于不需要记录移动和额外空间,由于不需要记录移动和额外空间,同时算法简单,当同时算法简单,当n较小时,可采用本算法。较小时,可采用本算法。直接插入排序直接插入排序假设在排序过程中,记录序列假设在排序过程中,记录序列R1.nR1.n的状态为:的状态为:则一趟插入排序的基本思想为:将记录则一趟插入排序的基本思想为:将记录RiRi插入到有插入到有序子序
4、列序子序列R1.i-1R1.i-1中,使记录的有序序列从中,使记录的有序序列从R1.i-R1.i-11变为变为R1.iR1.i。显然,完成这个显然,完成这个“插入插入”需分三步进行:需分三步进行:1 1查找查找RiRi的插入位置的插入位置j+1j+1;2 2将将Rj+1.i-1Rj+1.i-1中的记录后移一个位置;中的记录后移一个位置;3 3将将RiRi复制到复制到Rj+1Rj+1的位置上。的位置上。直接插入排序直接插入排序:利用顺序查找实现利用顺序查找实现“在在R1.i-1中查找中查找Ri的插入位置的插入位置”的插入排序。的插入排序。注意直接插入排序算法的三个要点:注意直接插入排序算法的三个
5、要点:1.1.从从Ri-1起向前进行顺序查找,监视哨设置在起向前进行顺序查找,监视哨设置在R0R0;R0:=Ri;设置设置“哨兵哨兵”j:=i-1;while(R0.keyRj.key)Do j:=j-1;/从后往前找从后往前找 Return(j+1);返回返回Ri的插入位置为的插入位置为j+12.2.对于在查找过程中找到的那些关键字不小于对于在查找过程中找到的那些关键字不小于Ri.key的记录,并的记录,并 在查找的同时实现记录向后移动;在查找的同时实现记录向后移动;while(R0.keyRj.key)Do Rj+1:=Rj;j:=j-1;3.i=23.i=2,3 3,,n,n,实现整个序
6、列的排序。实现整个序列的排序。排序算法如下:排序算法如下:Procedure insort(var r:List;n:Integer);Begin For i:=2 to n Do r0:=ri;j:=i-1;while r0.keyrj.key Do rj+1:=rj;j:=j-1;rj+1:=r0;End;排序的时间分析:排序的时间分析:实现排序的基本操作有两个:实现排序的基本操作有两个:(1 1)“比较比较”序列中两个关键字的大小;序列中两个关键字的大小;(2 2)“移动移动”记录。记录。对于直接插入排序:对于直接插入排序:最好的情况(关键字在记录序列中顺序有序):最好的情况(关键字在记
7、录序列中顺序有序):“比较比较”的次数:的次数:“移动移动”的次数:的次数:最坏的情况(关键字在记录序列中逆序有序):最坏的情况(关键字在记录序列中逆序有序):“比较比较”的次数:的次数:“移动移动”的次数:的次数:总的说来,直接插入排序所需进行关键字间的比较次数和记录移总的说来,直接插入排序所需进行关键字间的比较次数和记录移动的次数均为动的次数均为n n2 2/4/4,所以直接插入排序的时间复杂度为,所以直接插入排序的时间复杂度为O(nO(n2 2)。2(n-1)折半插入排序折半插入排序排序算法的思想:排序算法的思想:由于直接插入排序的内循环由于直接插入排序的内循环(从从1到到i-1)的查找
8、的查找(或说是比较或说是比较)是在是在(部分部分)有序表的环境下进行的,有序表的环境下进行的,所以内循环用所以内循环用“折半查找法折半查找法”,比用顺序查找法快。,比用顺序查找法快。算法描述如下:算法描述如下:Procedure binsort(var r:List;n:Integer);Begin For i:=2 to n Do r0:=ri;l:=1;h:=i-1;while l=h Do m:=(l+high)div 2;if r0.keyrm.key then h:=m-1 else l:=m+1;For j:=i-1 DownTo l Do rj+1:=rj;rl:=r0;End;
9、表插入排序表插入排序 为了减少在排序过程中进行的为了减少在排序过程中进行的“移动移动”记录的操作记录的操作,必须改变排序过程中采用的存储结构。利用静态链,必须改变排序过程中采用的存储结构。利用静态链表进行排序,并在排序完成之后,一次性地调整各个表进行排序,并在排序完成之后,一次性地调整各个记录相互之间的位置,即将每个记录都调整到它们所记录相互之间的位置,即将每个记录都调整到它们所应该在的位置上。应该在的位置上。例如例如:算法描述如下:算法描述如下:Procedure Linsertion_Sort(r:List;n:Integer);Begin r0.key=MAXINT;r0.next=1;
10、r1.next=0;For i:=2 to n Do j:=0;k:=r0.next;while(rk.key=ri.key)and(k0)Do j:=k;k:=rk.next;rj.next=i;ri.next=k;结点结点i插入在结点插入在结点j和结点和结点k之间之间 End;从表插入排序的过程可以看出,它的基本操作仍是将一个记从表插入排序的过程可以看出,它的基本操作仍是将一个记录插入到已排序好的有序表中。和直接插入排序相比,不同之处录插入到已排序好的有序表中。和直接插入排序相比,不同之处仅是以修改仅是以修改2n次指针值代替移动记录,排序的过程中所需进行的次指针值代替移动记录,排序的过程中
11、所需进行的关键字间的比较次数相同。因此,表插入排序的时间复杂性仍是关键字间的比较次数相同。因此,表插入排序的时间复杂性仍是O(n2)。另一方面,表插入排序的结果只是求得了一个有序链表,则只另一方面,表插入排序的结果只是求得了一个有序链表,则只能对它进行顺序查找,不能进行随机查找,为了能应用有序表的能对它进行顺序查找,不能进行随机查找,为了能应用有序表的折半查找,需对记录进行重新排列。折半查找,需对记录进行重新排列。重排记录的做法是:顺序扫描有序链表,将链表中第重排记录的做法是:顺序扫描有序链表,将链表中第i个结点个结点移动至数组的第移动至数组的第i个分量中。它的做法是:若第个分量中。它的做法是
12、:若第i个最小关键字的结个最小关键字的结点是数组中下标为点是数组中下标为p且且pi的分量,则互换的分量,则互换ri和和rp,且令,且令ri中指中指针域的值改为针域的值改为p;由于此时数组中所有小于由于此时数组中所有小于i的分量已是到位的记录,的分量已是到位的记录,则当则当p=i时为止。时为止。算法描述如下:算法描述如下:Procedure Arrange(var r:stlisttp);本算法根据本算法根据r0.n中个分量指针域的值调整中个分量指针域的值调整r1.n中记录,使数中记录,使数 组中各分量中的记录按关键字非递减有序顺序排列组中各分量中的记录按关键字非递减有序顺序排列Begin i:
13、=1;p:=r0.next;while i=n-1 Do while pi Do p:=ri.next;p指示第指示第i个结点在当前数组中的位置个结点在当前数组中的位置 q:=rp.next;if pi then t:=rp;rp:=ri;ri:=t;ri.next:=p;交换记录并保持指向交换记录并保持指向rp中记录的指针中记录的指针 i:=i+1;p:=q;End;冒泡排序冒泡排序排序算法的思想:排序算法的思想:比较比较k k1 1和和k k2 2,如果这些关键字的值不符合排序顺如果这些关键字的值不符合排序顺序序,就交换就交换k k1 1和和k k2 2;然后对记录;然后对记录k k2 2
14、和和k k3 3,k,k3 3和和k k4 4等等进行相同的工等等进行相同的工作。作。直到直到k kn-1n-1和和k kn n为止为止,到此得到一个最大到此得到一个最大(或最小或最小)关键字值存关键字值存在在k kn n的位置上的位置上(通常将此过程叫做一趟通常将此过程叫做一趟)。重复这个过程。重复这个过程,就得到在就得到在位置位置kn-1,kn-2kn-1,kn-2等处的适当记录等处的适当记录,使得所有记录最终被排好序。使得所有记录最终被排好序。7 4 4 3 34 7 3 4 4 8 3 7 7 73 8 8 8 89 9 9 9 9 例如例如:将将5 5个记录的关键字个记录的关键字7,
15、4,8,3,97,4,8,3,9进行冒泡排序。排序后进行冒泡排序。排序后k1k2k1k2kn(n=5)kn(n=5)。因为到第四趟就没有交因为到第四趟就没有交换的偶对了换的偶对了,所以整个排序所以整个排序结束。结束。算法描述如下算法描述如下Procedure Bubble_sort(var r:List;n:Integer);Begin For m:=1 to n Do read(rm);k:=n;Repeat all:=True;For m:=1 to k-1 Do i:=m+1;if rmri then max:=rm;rm:=ri;ri:=max;all:=false k:=k-1;Un
16、til(all=True)or(k=1);End;冒泡排序的结束条件为:最后一趟没有进行冒泡排序的结束条件为:最后一趟没有进行“交换交换”。冒泡排。冒泡排序是一种稳定的排序算法。序是一种稳定的排序算法。时间分析时间分析:最好的情况(关键字在记录序列中顺序有序):只需进行最好的情况(关键字在记录序列中顺序有序):只需进行一趟起泡一趟起泡“比较比较”的次数:的次数:“移动移动”的次数:的次数:n-10 最坏的情况(关键字在记录序列中逆序有序):需进行最坏的情况(关键字在记录序列中逆序有序):需进行 n-1n-1趟起泡趟起泡“比较比较”的次数:的次数:“移动移动”的次数:的次数:希尔排序希尔排序基本
17、思想:对待排记录序列先作基本思想:对待排记录序列先作“宏观宏观”调整,再作调整,再作“微微观观”调整。所谓调整。所谓“宏观宏观”调整,指的是,调整,指的是,“跳跃式跳跃式”的插的插入排序。即:将记录序列分成若干子序列,每个子序列分入排序。即:将记录序列分成若干子序列,每个子序列分别进行插入排序别进行插入排序,待整个序列中的记录待整个序列中的记录“基本有序基本有序”时,时,再对全体记录进行一次直接插入排序。假设将再对全体记录进行一次直接插入排序。假设将n n个记录分个记录分成成d d个子序列,则这个子序列,则这d d个子序列分别为:个子序列分别为:R1 R1,R1+dR1+d,R1+2dR1+2
18、d,R1+kd R1+kd R2 R2,R2+dR2+d,R2+2dR2+2d,R2+kd R2+kd Rd Rd,R2dR2d,R3dR3d,RkdRkd,R(k+1)d R(k+1)d 其中,其中,d d称为增量,它的值在排序过程中从大到小逐渐缩称为增量,它的值在排序过程中从大到小逐渐缩小,直至最后一趟排序减为小,直至最后一趟排序减为1 1。例如:例如:第二趟希尔排序,设增量d=3 第三趟希尔排序,设增量d=1希尔排序的算法描述如下希尔排序的算法描述如下:Procedure ShellInsert(r:List;d:Integer);本算法对直接插入算法作了以下本算法对直接插入算法作了以下
19、 修改:修改:1.1.前后记录位置的增量是前后记录位置的增量是d d,而不是,而不是1 1;2.r02.r0只是暂存单元只是暂存单元,不是哨兵。当不是哨兵。当j=0j=0时时,插入位置已找到。插入位置已找到。Begin For i:=d+1 to n Do If(ri.key0)and(r0.key rj.key)Do rj+d=rj;记录后移,查找插入位置记录后移,查找插入位置 j:=j-d;rj+d=r0;插入插入 End;Procedure Shell_sort(r:List,dlta:Array of Integer;t:Integer);Begin 按增量序列按增量序列dlta0.t
20、-1dlta0.t-1对顺序表对顺序表L L作希尔排序。作希尔排序。For k=0 to t Do ShellInsert(r,dltak);End;先取定一个两项之间的距离先取定一个两项之间的距离d d1 1(n,(n,其中其中n n为整个表的长度为整个表的长度),),反复比较每两个相距反复比较每两个相距d d1 1的项的项,直到以直到以d d1 1为距离划分的组排序好为止为距离划分的组排序好为止(至此一趟排序完成至此一趟排序完成),),然后取然后取d d2 2dd1 1,再继续以再继续以d d2 2为距离反复比较每为距离反复比较每两个相距为两个相距为d d2 2的项的项,依此类推依此类推.
21、取每个取每个d di+1i+1 d1 Do d:=d div2;Repeat all:=True;For i:=1 to n-d do j:=i+d;if rirj then max:=ri;ri:=rj;rj:=max;all:=false;Until all For i:=1 to n Do Write(ri);End;选择排序选择排序基本思想:首先在基本思想:首先在n n个记录中选择一个具有最小或最大个记录中选择一个具有最小或最大关键字的记录,将选出的记录与记录集合中的第一个记关键字的记录,将选出的记录与记录集合中的第一个记录交换位置。然后在录交换位置。然后在r2r2至至rnrn中选择一
22、个最小或最大中选择一个最小或最大的值与的值与r2r2交换位置,交换位置,依此类推,直至,依此类推,直至rn-1rn-1和和rnrn比较完毕。比较完毕。Procedure Select_sort(var r:List;n:Integer);Begin For i:=1 to n-1 Do m:=i;For j:=i+1 to n Do If rj.keyrm.key then m:=j;If m i then x:=ri;ri:=rm;rm:=x;End;算法的复杂性分析:算法的复杂性分析:当选则第一个最小值时需进行当选则第一个最小值时需进行n-1n-1次比较,选第二个最小值时需次比较,选第二个
23、最小值时需进行进行n-2n-2次比较,次比较,选,选n-1n-1个最小值时需进行个最小值时需进行n-(n-1)n-(n-1)次比较,次比较,所以总的比较次数为所以总的比较次数为(n-1)+(n-2)+(n-1)+(n-2)+2+1=n(n-1)/2+2+1=n(n-1)/2故排序故排序n n个记录需要时间为个记录需要时间为O(nO(n2 2)。由于执行一次交换,需三次移动记录,最多交换由于执行一次交换,需三次移动记录,最多交换n-1次,故最多移次,故最多移动次数为动次数为3(n-1)堆排序堆排序堆是满足下列性质的数列堆是满足下列性质的数列RR1 1,R,R2 2,,R Rn n:或或若将此数列
24、看成是一棵完全二叉树,则堆或是空树或是满足下若将此数列看成是一棵完全二叉树,则堆或是空树或是满足下列特性的完全二叉树:其左、右子树分别是堆,并且当左、右列特性的完全二叉树:其左、右子树分别是堆,并且当左、右子树不空时,根结点的值小于子树不空时,根结点的值小于(或大于或大于)左、右子树根结点的值。左、右子树根结点的值。9683273811 09下列两个序列为堆,对应的完全二叉树如下图下列两个序列为堆,对应的完全二叉树如下图96,83,27,38,11,09 12,36,24,85,47,30,53,911236248547305391建堆的过程:建堆的过程:1.首先将一个关键字集合用完全二叉树的
25、形式排列首先将一个关键字集合用完全二叉树的形式排列;如给定关键字集合为如给定关键字集合为46,55,13,42,94,17,05,70组成的完全二叉组成的完全二叉 树如下:树如下:4655134294 1705702.开始建堆:采用筛选法,逐步将大的关键字筛到堆底。筛选法开始建堆:采用筛选法,逐步将大的关键字筛到堆底。筛选法 的思想是这样的:假设集合的思想是这样的:假设集合r有有m个结点,从某个结点个结点,从某个结点i(第一次第一次 i=m/2)开始筛选,先看第开始筛选,先看第i个结点的左右子树,设第个结点的左右子树,设第i个结点的个结点的 左子树为左子树为k j,右子树为,右子树为kj+1,
展开阅读全文