数据结构 罗吴蔓 电子科大 PPT 考研chapt10'
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
10.2
1 d ……
插入排序
n ……
final
first
10.2
排序过程中d的状态如下: i=1 i=2 i=3 i=4 . . 49 first final 49
插入排序
例如:49,38,65,97,76,13,27,49
38
final
49 65 final 49 65 97 final
first
10.2
先回顾一下折半查找的过程
插入排序
(5, 13, 19, 21, 37, 56, 64,75, 80, 88, 92)
•设k=25 •设k=70
第一次:low=1,high=11,mid=6
第二次:low=1,high=5,mid=3 第三次:low=4,high=5,mid=4 第四次:low=5,high=5,mid=5 下一次:low=5,high=4
04 13 27 38 49' 49 55 65 76 97
10.2
4.希尔排序的特点
插入排序
⑴ 子文件(子序列)的构成不是简单地“逐段分割”, 而是将相隔某个“增量”的记录组成一个子文件。 ⑵ 增量序列应是递减,且最后一个必须为1。 ⑶ 希尔排序法是不稳定的。
5. 希尔排序算法的实现
PROC shellsort(VAR r:ARRAY[-d[1]:n] OF rcdtype; d:ARRAY[1..t] OF integer);
13 04 49‘ 38 27 49 55 65 97 76 04 13 27 38 49‘ 49 55 65 76 97
10.3
快速排序
快速排序是目前内部排序中最快的方法。
⒈ 基本思想:选取某个记录,(通常选文件的第一个记
录),将Fra Baidu bibliotek有关键字不大于它的记录放在它的前面,将所
有关键字不小于它的记录放在它的后面,这样遍历一趟文
10.1
基本概念
内部排序 :待排序文件的全部记录存放在内存
进行的排序,称为内部排序。
外部排序:待排序记录的数量很大, 以致内存一
次不能容纳全部记录, 排序过程中需要进行内外存 数据交换的排序,称为外部排序。
10.1
内排序分类
基本概念
按排序过程依据的原则分为:插入排序 交换排序
选择排序
归并排序 计数排序 按排序过程所需的工作量分:简单排序 O(n2) 先进排序 O(nlog n)
38 first 38 first
.
10.2
插入排序
PROC twowaysort(VAR r:listtype); d[1].key:=r[1].key;first:=final:=1; FOR i:=2 TO n DO [ IF r[i].key<d[1].key THEN IF first=1 THEN [ first:=n;d[n].key:=r[i].key ] ELSE [j:=first; WHILE j≤n CAND r[i].key≥d[j].key DO j:=j+1; FOR k:=first TO j-1 DO d[k-1].key:= d[k].key ; d[j-1].key:= r[i].key ;first:=first-1 ] ELSE [j:=1; WHILE j≤final CAND r[i].key≥d[j].key DO j:=j+1; FOR k=final DOWNTO j DO d[k+1].key:= d[k].key; d[j].key:= r[i].key;final:=final+1 ]; j:=first; FOR i:=1 TO n DO [ r[i]:=d[j]; j:=j+1; IF j>n THEN j:=1 ] ENDP; {twowaysort}
第一次:low=1,high=11,mid=6
第二次:low=7,high=11,mid=9 第三次:low=7,high=10,mid=8 第四次:low=7,high=7,mid=7 下一次:low=8,high=7
结论:查找不成功时,low>high,且low=high+1
10.2
PROC binsort(VAR r:listtype );
基数排序 O(d.n)
10.1
基本概念
待排记录的数据类型
TYPE rcdtype=RECORD
key: integer;
otheritem: anytype
END;
listtype=ARRAY[0..n] OF rcdtype;
10.2
插入排序
一. 直接插入排序 (最简单的排序方法)
⒈ 基本思想:依次将每个待排序的记录插入到一个有
序子文件的合适位置(有序子文件记录数增1)
例如:已有待排序文件为:38,65,49,76,97 首先将文件的第一个记录,视为有序文件,然后 从第二个记录开始,直到最后一个记录,依次将它 们插入到有序文件的合适位置。
10.2
若:假设r[1..i-1]有序,
插入排序
将r[i]插入其中,使r[1..i]有序, 即,找j使其满足 r[j].key<=r[i].key<r[j+1].key 于是,关键问题——找j——查找问题
n
进行了∑1=n-1次比较(最少); i=2 b.每个记录都要进行r[i]移到r[0]和r[0]移到r[j+1]两次移动, 因此共移动2(n-1)次(最少)。
10.2
插入排序
2/. 当待排序文件按关键字非递增有序(逆序)时 a. 记录r[i](i=2,3,...n)均要和前i-1个记录及r[0]进行比较,整个排 序过程共进行了
第十章 内部排序
• • • • • • 基本概念 插入排序 快速排序 选择排序 归并排序 基数排序
10.1
基本概念
将一个数据元素(或记录)的任意序列,重新排 列成一个按关键字有序的序列,称为排序。
设含有n个记录的文件{R1,R2,...,Rn},其相应的 关键字为{K1,K2,...,Kn},需确定1,2, „, n的一种排 列p1,p2, „, pn,使其相应的关键字满足如下的非递 减(或非递增)关系Kp1<=Kp2<=„<=Kpn, 从而使序列 {Rp1,Rp2,...,Rpn}按关键字有序, 该过程称为排序。
则文件中大多数记录都不需要进行插入。 ⑵基本有序时,直接插入排序效率可以提高,接近于O(n)。
10.2
插入排序
⒊ 例:设初始关键字为:49 38 65 97 76 13 27 49' 55 04
第 一 趟 以 步 长 为 5 分 割 为 5 个 子 文 件 : (R1,R6) (R2,R7) (R3,R8) (R4,R6) (R5,R10),对每个子文件进行直接插入排序结果为: 13 27 49' 55 04 49 38 65 97 76 第二趟以步长为3对第一趟排序结果分割为3 个子文件: (R1,R4,R7,R10) (R2,R5,R8) (R3,R6,R9) 对每个子文件进行直接插入排序,结果为: 13 04 49' 38 27 49 55 65 97 76 第三趟以步长为1对第二趟排序结果进行直接插入排序,结果为:
注意r[0]的作用
10.2
⒊ 算法分析
插入排序
⑴ 空间上,只需i,j两个整型变量和一个记录的辅助空间r[0], r[0]作为"监视哨",控制待插入元素相对于有序子文件为最小时 WHILE循环的结束,同时也用于暂存待插入元素。
⑵ 时间上,只包含比较关键字和移动记录两种操作。
1/. 当待排序初始文件按关键字非递减有序(正序)时: a. 对每个记录只进行一次比较,整个排序过程共
r[j+1]:=r[0] ]
ENDP;{binsort} { 移动次数未变,故时间复杂度仍为O(n2) }
10.2
三. 2-路插入排序
插入排序
目的:减少移动记录次数(约为n2/8) 使用DS:辅助向量:d[1..n], 指针:first 和final(当前最小和最大值位置) 思想:将d[1]视为有序文件的中间记录,并将待插入记录 r[i].key与d[1] .key进行比较 若r[i].key<d[1] .key:则将r[i]插入到d[first]~d[n]之间。 若r[i].key≥d[1] .key:则将r[i]插入到d[1]~d[final]之间。
10.2
插入排序
四. 希尔排序(Shell`s Method)(又称为缩小增量排序)
⒈ 基本思想:分割成若干个较小的子文件,对各个子文件分别 进行直接插入排序,当文件达到基本有序时,再对整个文件进行一 次直接插入排序。 ⒉ 依据:⑴若待排序文件"基本有序",即文件中具有特性: r[i].key< Max {r[j ] .key} ( 1≤j<i) 的记录数较少,
10.1
基本概念
对所有的Ki=Kj (i≠j), 若排序前Ri领先于Rj, 排 序后Ri仍领先于Rj, 则称该排序方法是 稳定的;反 之,若可能使排序后的序列中Rj领先于Ri, 则称所 用的排序方法为不稳定的。 稳定性是对序列中的两个相同关键字的记录在 初始序列和最终有序序列中相对位置(即领先关系) 是否变化的描述。
当查找方法不同时,形成了不同的排序方法
10.2
⒉ 直接插入排序算法
插入排序
PROC strainsort(VAR r:listtype); FOR i:=2 TO n DO [ r[0]:=r[i]; j:=i-1; {r[1]~r[i-1]为有序子文件} WHILE r[0].key<r[j].key DO [ r[j+1]:=r[j]; j:=j-1 ]; {确定插入位置并移动} r[j+1]:=r[0] ] ENDP; {strainsort}
{d[1]...d[t]为增量序列,r[-d[1]..n]中,-d[1]..0为各趟监视哨位, 1..n为记录} k:=1; REPEAT [ dh:=d[k]; s:=-dh+1; {s为哨兵位,dh为增量值} FOR i:=dh+1 TO n DO [ r[s]:=r[i]; j:=i-dh; WHILE r[s].key<r[j].key DO [ r[j+dh]:=r[j]; j:=j-dh ]; r[j+dh]:=r[s]; s:=s+1; IF s>0 THEN s:=-dh+1 ]; k:=k+1 ] UNTIL dh=1 ENDP; {shellsort}
i=2 n
10.2
插入排序
⑶ 结论
1/. 直接插入排序的效率与待排文件的关键字排列有关;
2/. 直接插入排序的时间复杂度为O(n2);
3/. 直接插入排序是稳定的(这一点由过程中WHILE语句 的条件“<”保证的)。
10.2
二. 折半插入排序
插入排序
由于是在有序子文件中确定插入的位置,因此 可用折半查找来代替直接插入排序法中的顺序查找, 从而可减少比较次数。
∑ i=(n+2)(n-1)/2次比较(最多);
i=2
n
b. 移动记录次数:每个记录都要进行r[i]移动到r[0]和r[0]移动到 r[j+1]两次移动,另外当r[i].key<r[j].key时,还将r[j]移动
到r[j+1],所以,当初始文件为逆序时移动记录次数最多, 为
∑ (i-1)+2(n-1)=(n+4)(n-1)/2次(最多)。
初始关键字:
49 38 65 97 76 13 27 49‘ 55 04 49 13
38 27
65
97 76 一趟排序结果:
49‘
55 04
dh=5
13 27 49‘ 55 04 49 38 65 97 76 13 55 38 76 27 49‘ 04 49 65 97 dh=1 dh=3
二趟排序结果: 三趟排序结果:
件后,将文件以该记录为界分为两部分,然后对各部分重
复上述过程,直到每一部分仅剩一个记录为止。
10.3
⒉ 具体步骤
快速排序
(1) 置变量i,j初值分别为文件的首、尾记录位置;
选取文件首记录r[i],并将其关键字赋给变量x; (2) 从j 位置开始向前搜索,
(3) 直到遇到第一个关键字小于x的记录,
(4) 并将r[j]移至r[i]; (5) 从i 位置开始向后搜索, (6) 直到遇到第一个关键字大于x的记录, (7) 并将r[i]移至r[j]; (8) 重复(2) (9) 直到i=j, (10) 并将x移至r[i],以r[i]为中枢将文件分为r[1..i-1]和r[i+1..n]两 部分,完成一趟排序; (11) 重复(1)至(10),直到每一部分只剩上一个记录,整个文件已 有序,快速排序算法结束。
插入排序
FOR i:=2 TO n DO
[ s:=1; j:=i-1 ; r[0]:=r[i]; WHILE s≤j DO
[ m:=(s+j)/2 ;
IF r[i].key<r[m].key {<确保稳定,若改为≤,则不稳定} THEN j:=m-1 ELSE s:=m+1;]
FOR k:=i-1 DOWNTO j+1 DO r[k+1]:=r[k];