数据结构课件-排序.
(1)趟数为n-1;
22
(2)直到在某趟排序过程中没有进行过交换记录的操作为止。
例:有一组待排序的记录的关键字初始排列如下: (49,38,65,97,76,13,27,49`)
第一趟: 49 38 65 97 76 13 27 49` 38 49 65 97 76 13 27 49` 38 49 65 97 76 13 27 49` 38 49 65 97 76 13 27 49` 38 49 65 76 97 13 27 49` 38 49 65 76 13 97 27 49` 38 49 65 76 13 27 97 49` 38 49 65 76 13 27 49` 97
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) L.r[j+1]= L.r[j]; L.r[j+1]= L.r[0]; } }
38
38 38
↑final ↑first
13
27
16
2-路插入排序的性能分析: (1)空间: (2)时间: 基本运算:比较和移动记录; 2-路插入排序算法的时间复杂度为O(n×n)
17
10.2.3希尔排序
从直接插入排序 希尔排序的基本思想:
待排序序列基本有序可提高效率
待排序序列的记录数n很小时可提高效率
L.r[1].key..L.r[8].key 是 7 递增有序的
直接插入排序的过程:
r[0] r[1] r[2] r[3] r[4] r[5] r[6] r[7] r[8] [初始关键字] 49 38 65 97 76 13 27 49`
第一趟插入 i=2 第二趟插入 i=3 第三趟插入 i=4 第四趟插入 i=5 第五趟插入 i=6 第六趟插入 i=7
Void Binsertsort(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) L.r[j+1]= L.r[j]; L.r[j+1]= L.r[0]; } }
76
97
直接插入排序算法分析:
有n个记录待排序,需进行2..n共n-1趟插入;
第i趟插入完成的功能:在含有i-1个记录的有序序列r[1..i-1] 中插入一个记录r[i],插入后变成含
有i个记录的有序序列r[1..i]。
一级算法: Void insertsort(sqlist &L) {
for (i=2;i<=L.length; ++i)
38 38 38 38
49 49 49 49
65 65 65 65
97
76
13 13 13
27 27 27 27
49` 49` 49` 49`
97 76 97 76 76
97 13
13
13
38
27
49
38
65
49
76 97
65 76
27
97
49`
49`
8
第七趟插入 i=8
13
27
38
49 49` 65
姓名
4张强 3七明 5陈华 2王天 1李由
年龄 24 24 24
体重 72 75 53
54 57
76 62
内部排序—— 待排序记录存放在计算机随机存储器中进 行的排序过程; 外部排序—— 待排序记录的数量很大,以致内存一次不 能容纳全部记录,在排序过程中尚需对外 存进行访问的排序过程;
4
按排序过程中依据的不同原则对内排方法分类:
21
10.3快速排序
起泡排序的基本思想: 首先将第一个记录的关键字和第二个记录的关键字进 行比较,若为逆序,则将两个记录交换之,然后比较第二 个记录和第三个记录的关键字。直至第n-1个记录和第n个 记录的关键字进行过比较为止。 ……
然后进行第二趟起泡排序,对前n-1个记录进行同样操作。 结束的条件:
5
待排序的记录序列可有三种存储方式: (1)待排序的记录存放在地址连续的一组存储单元上。 (2)待排序的记录存放在静态链表中。
(3)待排序的记录本身存储在一组地址连续的存储单元 待排序记录的数据类型设为:
内,同时另设一个指示各个记录存储位置的地址向量。
P264
6
10.2插入排序 插入排序
直接插入排序 折半插入排序 2-路插入排序 表插入排序 希尔排序
例:有一组待排序的记录的关键字初始排列如下: (49,38,65,97,76,13,27,49`)
15
[初始关键字] 49
i=1:
first↑ ↑final
38 65 97 76 13 d[1] d[2] d[3] d[4] d[5] d[6] 49
27 d[7]
49` d[8]
i=2:
i=3:
49
体重 62 76 75 72 53
姓名 按某种稳定 3七明 方法对年龄 4张强 关键字进行 5陈华 排序 2王天 1李由
年龄 24
体重 75
24
24 54 57
72
53 76 62
3
姓名 1李由 2王天 3七明 4张强 5陈华
年龄 57 54 24 24 24
体重 62 76 75 72 53
按某种不稳 定方法对年 龄关键字进 行排序
10
三级算法:
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) L.r[j+1]= L.r[j]; L.r[j+1]= L.r[0]; }
第10章 内部排序
10.1 概述 10.2 插入排序 10.3 快速排序 10.4 选择排序 10.5 归并排序 10.6 基数排序 10.7 各种内部排序方法的比较讨论
1
10.1概述
排序—— 是将数据元素的一个任意序列,重新排列成一 个按关键字有序的序列。 排序的一个确切定义:
假设含n个记录的序列为 {R1,R2,R3,…,Rn} 其相应的关键字序列为{K1,K2,…,Kn}
23
第一趟进行7次比较
整 个 排 序 过 程
49 38 65 97 76 13 27 49`
(1)插入排序 (2)交换排序 (3)选择排序 按内排过程中所需的工作量分类: (4)归并排序 (5)基数排序
(1)简单的排序方法,其时间复杂度为O(n×n)
(2)先进的排序方法,其时间复杂度为O(nlogn); (3)基数排序,其时间复杂度为O(d×n) 排序算法的两种基本操作: (1)比较两个关键字的大小; (2)将记录从一个位置移至另一个位置;
先将整个待排记录序列分割成为若干子序列分别进行
直接插入排序,待整个序列中的记录“基本有序”时,再对 全 体记录进行一次直接插入排序. 例:有一组待排序的记录的关键字初始排列如下: (49,38,65,97,76,13,27,49`)
18
r[0] r[1] r[2] r[3] r[4] r[5] r[6] r[7] r[8] [初始关键字] 49 38 65 97 76 13 27 49`
第一趟排序后: (d1=3)
27
38
13
49
49`
65
97
76
第二趟排序后: (d2=2)
第三趟排序后: (d3=1)
13
ห้องสมุดไป่ตู้
38
27
49
49` 65
97
76
13
27
38
49
49`
65
76
19
97
希尔排序算法的实现:
Void shellsort(sqlist &L,int dlta[ ],int t){ for (i=0;i<t; ++i) 以dlta[i]为增量的一趟排序; } Shellinsert(sqlist &L,dlta[i]);
列中Ri领先于Rj,若在排序后的序列中Ri仍 领先Rj,则称所用的排序方法是稳定的。
不稳定排序方法—— 假设Ki=Kj(1<=i,j<=n,i<>j),且在排序前的序列
中Ri领先于Rj,若在排序后的序列中Rj领先 Ri,则称所用的排序方法是不稳定的。
例:
姓名
1李由 2王天 3七明 4张强 5陈华
年龄 57 54 24 24 24
第i趟插入;
}
9
二级算法:第i趟插入的算法 例:第i=7趟插入: 1 2 3 4 5 13 38 49 65 76
6 97
7 27
8 49`
if (LT(L.r[i].key,L.r[i-1].key)) { L.r[i]插入到 L.r[1].. L.r[i-1]中 } 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) L.r[j+1]= L.r[j]; L.r[j+1]= L.r[0];