数据结构课件第十章 内部排序
合集下载
数据结构第10章-内部排序

现将关键字 40 记录插入上述序列中 12,33,40,45,57,76
11
直接插入排序
• 算法的基本思路 设有n个待排记录存放在r[1..n]中,将第i (2≤i ≤n)个记录
插入到已排好序的有序表r[1..i-1]中的过程为:从r[i-1] 起往 前搜索,若r[i]< r[j] (1≤j ≤i-1),则将r[j] 向后移动,直至找 到第i个记录的位置。
次数为 n-1,对象移动次数为 0。
最坏情况下,排序前对象已经按关键字大小从大 到小有序(逆序),需比较和移动次数为多少?
15
直接插入排序
•时间复杂性分析
若待排序对象序列中出现各种可能排列的概率 相同,则可取上述最好情况和最坏情况的平均情 况。在平均情况下的关键字比较次数和对象移 动次数约为 n2/4。因此,直接插入排序的时间 复杂度为 o(n2)。
12
直接插入排序
• 算法10.1
void InsertSort(SqList &L){
for(i=2;i<=L.Length;++i)
if LT (L. r[i].key, L. r[i-1].key {
L. r[0]=L. r[i];
L. r[i]=L. r[i-1];
for (j=i-2; LT (L. r[0].key, L. r[j].key);- -j)
9
5. 排序方法分析
排序的时间开销: 排序的时间开销是衡量算法好坏的 最重要的标志。排序的时间开销可用算法执行中的数 据比较次数与数据移动次数来衡量。
一般都按平均情况进行估算。对于那些受对象关键字 序列初始排列及对象个数影响较大的,需要按最好情况 和最坏情况进行估算。
11
直接插入排序
• 算法的基本思路 设有n个待排记录存放在r[1..n]中,将第i (2≤i ≤n)个记录
插入到已排好序的有序表r[1..i-1]中的过程为:从r[i-1] 起往 前搜索,若r[i]< r[j] (1≤j ≤i-1),则将r[j] 向后移动,直至找 到第i个记录的位置。
次数为 n-1,对象移动次数为 0。
最坏情况下,排序前对象已经按关键字大小从大 到小有序(逆序),需比较和移动次数为多少?
15
直接插入排序
•时间复杂性分析
若待排序对象序列中出现各种可能排列的概率 相同,则可取上述最好情况和最坏情况的平均情 况。在平均情况下的关键字比较次数和对象移 动次数约为 n2/4。因此,直接插入排序的时间 复杂度为 o(n2)。
12
直接插入排序
• 算法10.1
void InsertSort(SqList &L){
for(i=2;i<=L.Length;++i)
if LT (L. r[i].key, L. r[i-1].key {
L. r[0]=L. r[i];
L. r[i]=L. r[i-1];
for (j=i-2; LT (L. r[0].key, L. r[j].key);- -j)
9
5. 排序方法分析
排序的时间开销: 排序的时间开销是衡量算法好坏的 最重要的标志。排序的时间开销可用算法执行中的数 据比较次数与数据移动次数来衡量。
一般都按平均情况进行估算。对于那些受对象关键字 序列初始排列及对象个数影响较大的,需要按最好情况 和最坏情况进行估算。
数据结构-内部排序

{a[j]
a[j+1]; change=TRUE;}
}
}
时间复杂度:O(n2)
冒泡排序的算法分析
•最好情况:初始排列已经有序,只执行一趟起泡,做 n-1
次关键码比较,不移动对象。
•最坏情形:初始排列逆序,算法要执行n-1趟起泡,第i趟 (1 i n) 做了n- i 次关键码比较,执行了n-i 次对象 交换。此时的比较总次12,89,73排序
第一趟 28,14,12,39,73,89 第二趟 14,12,28,39,73,89 第三趟 12,14,28,39,73,89 第四趟 12,14,28,39,73,89
起泡排序(冒泡排序)(2)
第二趟:对前n-1个记录进行上述同样操作, 其结果使关键字次大的记录安置到第n-1个 记录位置上;
❖ 例:
Dk=3
初始值 28,39,14,12,89,73
第一趟结果 12,39,14,28,89,73
Dk=2
第二趟结果 12,28,14,39,89,73
Dk=1
第三趟结果 12,14,28,39,73,89
希尔排序算法
Void ShellSort(SqList &L,int dlta[ ],int t) //希尔排序. t 为排序趟数,dlta[ ] 为增量序列 { for (k=0;k<t;++k) ShellInsert(L,dlta[k]); }
…… 最后一趟:在该趟排序过程中没有进行过记
录交换的操作
起泡排序(3)
❖ 算法
Void bubble-Sort(int a[ ], int n)
{ for (i=n-1,change=TRUE;i≥1&&change;--i)
数据结构ppt 第10章 内部排序

量,在排序过程中将指针内容逐个修改为已经整理(排序)
过的后继记录地址。 优点:在排序过程中不移动元素,只修改指针。 本方法具有链表排序和地址排序的特点。
链表排序——排序时只移动指针; 地址排序——排序时先移动地址,最后再移动记录。
13
10.2 插入排序---表插入排序
例:关键字序列 T=(21,25,49,25*,16,08), 请写出表插入排序的具体实现过程。 *表示后一个25 解:假设该序列(结构类型)已存入一维数组V[7]中,将V[0] 作为表头结点。则算法执行过程为: i 关键字 V[i].key 指针 V[i].link MaxNum 5 6 0 1 2 0 1 21 4 3 2 25 0
97
final 76 76 76 65 97
38
first 38
final
97 final 97 final 76 97 final 13 first 13 first 27 13 first 27
first
38 38 38
10.2 插入排序---表插入排序
基本思想:在顺序存储结构中,给每个记录增开排序
冒泡排序的算法分析 时间效率:O(n2) — 因为要考虑最坏情况 空间效率:O(1)— 只在交换时用到一个缓冲单元 稳 定 性:稳定 — 25和25*在排序前后的次序未改变 详细分析: • 最好情况:初始排列已经有序,只执行一趟起泡,做 n-1 次关键码比较,不移动对象。 • 最坏情形:初始排列逆序,算法要执行n-1趟起泡,第i趟 (1 i n) 做了n- i 次关键码比较,执行了n-i 次对象交换。 此时的比较总次数KCN和记录移动次数RMN为:
3
10.2 插入排序---希尔(shell)排序(又称缩小增量排序) 基本思想:先将整个待排记录序列分割成若干子序列,分别
数据结构中的内部排序

i=1
7
16 41
36
28
41 16
j=4 j=2 j=3
k=4 k=3 k=2 k=1
L[k]与L[j]比较
10.2.2 选择排序法
L[k]与L[i]交换 i=2
7
16
28 36
36 28
41
L[k]与L[j]比较 j=4 j=3 k=3 k=2 i==k,L[k]与L[i]不交换
i=3
7
16
28
一趟排序开始 无序序列 R[1..i] i 有序序列 R[i+1..n]
一趟排序后 无序序列 R[1..i-1] 有序序列 R[i..n]
10.2.1 起泡排序
37 8 96 54 96 8 54 96
37 8
8 37
54
96
8
37
54
96
8
37
54
96
10.2.1 起泡排序
一趟排序算法:
void BubblePass(SqList &L,int i) { RcdType W; // j指示无序序列中第一个记录的位置 for(j=1;j<i;j++) { if(L.r[j+1].key<L.r[j].key) { //逆序交换位置 W=L.r[j]; L.r[j]=L.r[j+1]; L.r[j+1]= W; } // if } //for } //BubblePass
typedef struct{
RcdType r[MAXSIZE+1];//r[0]闲置或作为“哨兵” int length; //顺序表的真正长度
}SqList;
数据结构课件_第10章 内部排序

4.什么叫内部排序和外部排序?
内部排序—待排序记录都在内存中 外部排序—待排序记录一部分在内存,一部分在外存
5.排序的分类?
交换排序、插入排序、选择排序、归并排序、基数排序
6.待排序记录数据类型的定义
#define MAXSIZE 1000 // 待排顺序表最大长度 typedef int KeyType; // 关键字类型为整数类型
象移动次数约为 n2/4。因此,直接插入排序
的时间复杂度为 o(n2)。
•直接插入排序是一种稳定的排序方法。
2) 折半插入排序
新元素插入到哪里? 在已形成的有序表中折半查找,并在适 当位置插入,把原来位置上的元素向后顺移。 插入位置 hight+1 i 例如: L.r 14 36 49 52 80 58 61 23 97 75
是否可以考虑 设计一个“黄 金分割”插入 算法
// 折半
if (L.r[0].key < L.r[m].key)
high = m-1; // 插入点在低半区
else low = m+1; // 插入点在高半区
}
3)希尔(shell)排序(又称缩小增量排序)
基本思想:先将整个待排记录序列分割成若干子序列,分 别进行直接插入排序,待整个序列中的记录“基本有序” 时,再对全体记录进行一次直接插入排序。 技巧:子序列的构成不是简单地“逐段分割”,而是将 相隔某个增量dk的记录组成一个子序列,让增量dk逐趟缩
{张三,男,16} 、 {赵六,女,17} 、{王五,男,17}、{李四,女,18}
R3 R2
不稳 定
大多数排序算法都有两个基本的操作: (1)比较两个关键字的大小
(2)将记录从一个位置移动到另一个位置
西安电子科技大学_数据结构_第十章内部排序_课件PPT

初始关键字序列:
12345678 49 38 65 97 76 13 27 49*
第一趟排序后:
38 49 65 76 13 27 49* 97
第二趟排序后:
38 49 65 13 27 49* 76 97
第三趟排序后:
38 49 13 27 49* 65 76 97
第四趟排序后:
38 13 27 49 49* 65 76 97
10.2 希尔排序算法
void ShellInsert(SqList &L,int dk) {//对顺序表L作一+i 1<i=<L=.eLn.getnhg;tih+;+i+) +)
iiff((LL..rr[[ii]]..kkeeyy<<LL..rr[[ii--d1k]]..kkeeyy)){{//需将L.r[i]插入有序增量子表
10.1 排序的基本概念(续)
正序与逆序
➢ 若有序表是按排序码升序排列的,则称为升序表或正序 表,否则称为降序表或逆序表。不失普遍性,我们一般 只讨论正序表。
排序方法度量
➢ 排序过程主要是比较记录的关键字和移动记录。因此排 序的时间复杂性可以算法执行中的数据比较次数及数据 移动次数来衡量。当一种排序方法使排序过程在最坏或 平均情况下所进行的比较和移动次数越少,则认为该方 法的时间复杂性就越好。
L.r[j+1] = L.r[j];
L.r[j+1] = L.r[0]; }//if
最好情况} 下// (I正ns序er)tSort
最坏情况下(逆序)
元素的❖ 比分较析次直数接为插: 入n 排- 1序算法中关键元字素的的比比较较次次数数和: 记(录n+移2动)(次n-数1)/2
数据结构-第10章 内部排序

for ( i = 2; i <= L.length; ++ i) if LT(L.r[i].key,L.r[i-1].key){ L.r[0]=L.r[i];
for ( j = i-1; LT(L.r[0].key,L.r[j].key); --j )
L.r[j+1]=L.r[j]; L.r[j+1]=L.r[0];
08
08 08
i=4
25*
21 21
0
1
21 16
2
25 21
3
25* 25
4
49
5
16
6
08 08
i=5
16
25* 49
i=6
08
16 08
21 16
25 21
25* 49 25
08
25* 49
直接插入排序的算法
void InsertSort ( SqList &L ) {
//按非递减顺序对表进行排序,从后向前顺序比较
希尔排序过程
0 21 1 25
2 16 16 16 16 16
2 49
3 08 08 21 21 21
3 4 25* 16
4 5 25* 25 25* 25 25* 25 25* 25 25* 25
5 08
6 49 49 49 49 49
Gap = 3
1 21 21
Gap = 2
08 08
Gap = 1
起泡排序的过程
21 25 49 21 25 25 21 25 16 21 16 08 16 08
08
21 25 25 49
16
21 25 25 49
数据结构(C语言版)第10章 内部排序

10.3 交换排序 — 冒泡排序算法分析
改进的算法的时间复杂度:受数据表初始状态影响
正序
比较元素的次数为n-1次,而交换次数为0 逆序 比较和交换次数为n(n-1)/2
一般情况
O (n) O (n2)
P203
取平均值,
O (n2)
稳定性:
稳定排序
空间性能:1个辅助空间。
10.3 交换排序 — 快速排序
判断数据表 A=(5,23,16,68,64,72,71,73,45,79,90,81,75,94,97) 是否是堆。 1
10.4 选择排序 — 直接选择排序算法分析
稳定性:
不稳定排序 O(n2)
时间复杂度:
空间性能:1个辅助空间;
10.4 选择排序 — 堆排序
定义:n个元素的序列(a1,a2,…,an)当且仅当满足下面 关系时,称之为堆。(其中ki是元素ai的关键字) (1) ki≤k2i ; ki≤k2i+1 (2) ki≥k2i ; ki≥k2i+1 ( 2i≤n;2i+1≤n)
10.3 交换排序 — 快速排序算法分析
稳定性:不稳定排序 时间复杂度:
一般情况(每次等分子表): 最坏情况(初始序列有序):
O(nlog2n) O(n2)
平均: O(knlog2n)
空间性能:1个辅助空间。
10.4 选择排序
直接选择排序 堆排序
基本思想:
每一趟排序中,在待排序子表中 选出关键字最小(大)的元素放在其最 终位置上。
9 9 16 20
100 100 20 16
105 105 50 78
数据结构Chap10 内部排序.ppt

85 ) 20 h 85 ) 20
85 ) 20
85 ) 20
13 20 30 39 42 70 85 )
算法描述
void BInsertSort (SqList &L)
{ // 对顺序表L作折半插入排序
for ( i=2; i<=L.length; ++i )
{ L.r[0] = L.r[i];
——少
排序过程中所需的辅助空间的大小 ——小
算法本身的复杂程度
10.2 插入排序
插入排序的准则:在有序序列中插入新的记录以 达到扩大有序区的长度的目的。 直接插入排序
排序过程:整个排序过程为n-1趟插入,即先 将序列中第1个记录看成是一个有序子序列, 然后从第2个记录开始,逐个进行插入,直至 整个序列有序。
增量序列取法
无除1以外的公因子 采用缩小增量法 最后一个增量值必须为1
11.3 交换排序
基本思想:两两比较待排序记录的关键字,发现 两个记录的次序相反时即进行交换,直到没有反序 的记录为止。
两种交换排序: (1)冒泡排序 (2)快速排序
冒泡排序
最简单的一种交换排序方法 排序过程
将第一个记录的关键字与第二个记录的关键字进行比较, 若逆序则交换;然后比较第二个记录与第三个记录;依次类 推,直至第n-1个记录和第n个记录比较为止——第一趟冒泡 排序,结果关键字最大的记录被安置在最后一个记录上。
void ShellSort(RecType R[],int n) /*希尔排序算法*/
{ int i,j,d;RecType temp;
d=n/2;
/*d取初值n/2*/
while (d>0) {
for (i=d;i<n;i++) /*将R[d..n-1]分别插入各组当前有序区*/
数据结构课件第10章_内排序

按排序过程中使用到的存储介质来分,可以将排 序分成两大类 内排序和外排序。 序分成两大类:内排序和外排序。 两大类: 内排序是指在排序过程中所有数据均放在内存中 内排序是指在排序过程中所有数据均放在内存中 处理,不需要使用外存的排序方法。而对于数据量很 大的文件,在内存不足的情况下,则还需要使用外存, 这种排序方法称为外排序 这种排序方法称为外排序。 外排序。 排序码相同的记录,若经过排序后,这些记录 仍保持原来的相对次序不变,称这个排序算法是稳 仍保持原来的相对次序不变,称这个排序算法是稳 不稳定的排序算法。 定的。否则,称为不稳定的排序算法 定的。否则,称为不稳定的排序算法。
为了方便, 为了方便,r[0]一般不用 一般不用 于存放排序码, 于存放排序码,在一些排序 /*此处还可以定义记录中除排序码外的其它域* /*此处还可以定义记录中除排序码外的其它域*/ 算法中它可以用来作为中间 }recordtype; }recordtype; /*记录类型的定义*/ /*记录类型的定义* 单元存放临时数据。 单元存放临时数据。length 域是待排序的记录个数, 域是待排序的记录个数,它 typedef struct{ 必须不大于MAXSIZE,这样, 必须不大于 ,这样, recordtype r[MAXSIZE+1]; r[MAXSIZE+1 第1~length个记录的排序码 个记录的排序码 int length; length; /*待排序文件中记录的个数*/ /*待排序文件中记录的个数* 分别存于 r[1].key~r[length].key中 中 }table; /*待排序文件类型* /*待排序文件类型*/
最坏情况 : 即初始排序码开始是逆序的情况下,因为当插入 第i个排序码时,该算法内循环while要执行i次条件判 个排序码时,该算法内循环while要执行i 断,循环体要执行i 次,每次要移动1 断,循环体要执行i-l次,每次要移动1个记录,外循 环共执行n 环共执行n-1次,其循环体内不含内循环每次循环要 进行2 进行2次移动操作,所以在最坏情况下,比较次数为 (1+2+…+n)*(n-1),移动次数为 (1+2+…+n)*(n-1),移动次数为 (1+2+2+2+…+n+2)*(n-1)。假设待排序文件中的记录 (1+2+2+2+…+n+2)*(n-1)。假设待排序文件中的记录 以各种排列出现的概率相同,因为当插入第i 以各种排列出现的概率相同,因为当插入第i个排序码 时,该算法内循环while平均约要执行i/2次条件判断, 时,该算法内循环while平均约要执行i/2次条件判断, 循环体要执行(i 循环体要执行(i-l)/2次,外循环共执行n-1次,所以 /2次,外循环共执行n 平均比较次数约为(2+3+…+n)/2*(n-1),平均移动次 平均比较次数约为(2+3+…+n)/2*(n-1),平均移动次 数为(n-1)*(2+1+3+1+…+n+1)/2,也即直接插入排序 数为(n-1)*(2+1+3+1+…+n+1)/2,也即直接插入排序 算法的时间复杂度为O(n 算法的时间复杂度为O(n2)。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
.
7
10.2 插入排序
一趟直接插入排序的基本思想:
有序序列R[1..i-1]
无序序列 R[i..n]
R[i]
不同的具体实现方法导致不同的算法描述:
• 直接插入排序(基于顺序查找)
有序序列R[•1..i折] 半插入排无序序(序基于列折R半[查i+找1)..n]
• 表插入排序 (基于链表存储)
• 希尔排序 (基于逐趟缩小增量)
否则r[0]放for在(jr=[ij-+21;]L处T,(L.ir=[i0+]1.k,ey转,L1.r)[[j].key); j--)
L.r[j+1] = L.r[j];
[算法描述]
ቤተ መጻሕፍቲ ባይዱ
L.r[j+1] = L.r[0]; }
}//InsertSort
.
10
[哨兵/监视哨的作用] 简化边界条件的测试,提高算法时间效率。
Mavg n2/4
辅助空间复杂度O(1)
.
11
[改进措施]
• 折半插入排序
算法思想:将循环中每一次在区间 [1,i-1] 上为确定插 入位置的顺序查找操作改为折半查找操作。
r[1]
效果:减少关键字间的比较次数。
• 2-路插入排序
d
算法思想:设置与r同样大小的辅助空间d,将r[1]赋 值给d[1],将d看作循环向量。对于r[i] (2in),若 r[i]d[1],则插入d[1]之后的有序序列中,反之则插入d[1] 之前的有序序列中。(避免r[1]关键字最小/最大)
效果:减少记录的移动次数。
• 表插入排序
算法思想:构造静态链表,用改变指针来代替移动记 录操作
效果:减少记录的移动次数。
.
12
10.2.2 希尔排序(渐减/缩小增量排序)
对待排记录序列先作“宏观”调整,再作“微观”调 整。
[算法思想的出发点]
• 直接插入排序在待排序列的关键字基本有序时,效率 较高
[根据内部排序的方法]
插入排序
交换排序
选择排序
归并排序
基数排序
[根据排序算法所需的辅助空间] 就地排序: O(1) 非就地排序: O(n)或与n有关
.
4
内部排序的过程是一个逐步扩大记录的有序序列长度 的过程。
有序序列区 无 序 序 列 区
经过一趟排序
有序序列区 无 序 序 列 区
内部排序方法基于不同的“扩大” 有序序列长度
[性能分析]
• 最好情况(原始数据按正序即非递减序排列)
n
Cmin= 1 n 1
Mmin= 0
i2
• 最坏情况(原始数据按逆序即非递增序排列)
C = max
n i (n2)(n1)
i2
2
• 随机情况
Mmax=
n (i1)(n4)(n1)
i2
2
Cavg=(Cmin+ Cmax)/2n2/4 • 时间复杂度O(n2)
[根据排序前后相同关键字记录的相对次序] 稳定排序:设文件中任意两个记录的关键字值相同,
即Ki=Kj(ij),若排序之前记录Ri领先于记录Rj ,排序 后这种关系不变(对所有输入实例而言)。
不稳定排序:只要有一个实例使排序算法不满足稳 定性要求。
.
3
key ptr
[根据文件的存储结构划分排序的种类] 顺序存储 链式存储 地址存储: 待排记录顺序存储,排序时只对辅助 表(关键字+指针)的表目进行物理重排。
KeyType key; InfoType otherinfo; } RedType; typedef struct{ RedType r[MAXSIZE+1]; //r[0]闲置或作哨兵 int length; }SqList;
SqList L;
012 …
L.r
L.length … MAXSIZE
i=3 [ -4 0 8 ] 1 -4 -6
排
i=4 [ -4 0 1 8 ] -4 -6
序
i=5 [ -4 -4 0 1 8 ] -6
i=6 [ -6 -4 -4 0 1 8 ]
[算法思想] 每次使有序区增加一个记录
.
9
[算法步骤]
01
i-1 i i+1
n
r[0..n]
r[i] (有序区) j (无序区)
第十章 内部排序
10.1 概述 10.2 插入排序 10.3 交换排序 10.4 选择排序 10.5 归并排序 10.6 基数排序 10.7 各种内部排序方法比较 本章学习要点 习题与上机作业
.
1
10.1 概述
10.1.1 什么是排序 其目的是将一组“无序”的记录序列调整为“有
序”的记录序列,是根据记录关键字的值的非递减或 者非递增(递增或者递减)的关系将文件记录的次序 重新排列。
[例] 将下列关键字序列:
52, 49, 80, 36, 14, 58, 61, 23, 97, 75
调整为:
14, 23, 36, 49, 52, 58, 61 ,75, 80, 97
.
2
10.1.2 排序的分类
[根据排序时文件记录的存放位置] 内部排序:排序过程中将全部记录放在内存中处理。 外部排序:排序过程中需在内外存之间交换信息。
循环(n-1)次,v初oi值d Iin=s2ertSort (SqList &L) 1) 若r[i]<r[i-1]{,则fo把r i(fi第=(L2iT个; (i<L记L.r.录[lie]n.取kget出yh,;L保i.+r存[+[)i-在1]r.[k0e]y中)),{ j=i-1 2 )若r[0]< r[j],则r[j]后移L.r一[0位] =,Lj.=r[ji-]1;,L.转r[i]2)=;L.r[i-1];
的方法。
.
5
10.1.3 评价排序算法的主要标准
[时间开销] 考察算法的两个基本操作的次数:
– 比较关键字 – 移动记录 算法时间还与输入实例的初始状态有关时,分情况: – 最好 – 最坏 – 平均 [空间开销] 所需的辅助空间
.
6
讨论约定
(1)顺序存储
(2)按记录关键字非递减,关键字为整数
#define MAXSIZE 20 typedef int KeyType; typedef struct {
.
8
10.2.1 直接插入排序(增量法) 利用 “顺序查找”实现“在R[1..i-1]中查找R[i]的插
入位置”
[ 示例 ] { R(0) R(-4) R(8) R(1) R(-4) R(-6) } n=6
i=1 [ 0 ] -4 8 1 -4 -6
i=2 [ -4 0 ] 8 1 -4 -6
稳 定
• 在待排序的记录个数较少时,效率较高
[算法思想]
先选定一个记录下标的增量d,将整个记录序列按 增量d从第一个记录开始划分为若干组,对每组使用直 接插入排序的方法;然后减小增量d,不断重复上述过 程,如此下去,直到d=1(此时整个序列是一组)。