8排序

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数据结构
16
【时间效率】
确定插入位置所进行的折半查找,定位一个关键码的位 置需要比较次数至多为 间复杂度为O (nlog2n)。
log 2 (n 1)次,所以比较次数时
相对直接插入排序,折半插入排序只能减少关键字间的 比较次数,而移动记录的次数和直接插入排序相同,故时间 复杂度仍为O(n2)。 折半插入排序是一个稳定的排序方法。
2019/2/7
数据结构
6
8.2.1 直接插入排序
直接插入排序是一种简单的插入排序方法,基本 思想为:在 R[1] 至 R[i-1] 长度为 i-1 的子表已经有序 的情况下,将R[i]插入,得到R[1]至R[i]长度为i 的 子表有序,这样通过 n-1 趟( i=2..n )之后, R[1] 至 R[n]有序。
65 5
97 0
76 4
49 8
38 1
49 3
6
2019/2/7
数据结构
25
0
i=4 j=(1)、 6 i=5 j=8 i=6 j=(3)、 7
MAXINT
1
13 (6) 13
6
2
27 (7) 27
3
38 (7) 38
4
97
0
5
76
4
6
49 8 97
7
65 5 65
8
49
3
MAXINT
49
76
49
j 1 1 2) n(n 1) 2n n 2 2 4 4
(
j 1
n 1
由此,直接插入排序的时间复杂度为O(n2)。
直接插入排序是一个稳定的排序方法。
直接插入排序也可以在链式结构上实现。
2019/2/7 数据结构 14
8.2.2 折半插入排序
直接插入排序的基本操作是向有序表中插入一个记录,在 直接插入排序中,插入位置的确定是通过对有序表中关键码 的顺序比较得到的。
2019/2/7 数据结构 18
设排序表用静态链表作为存储结构,定义如下: #define MAXNUM … /*足够大的数*/ typedef struct {datatype data; /*元素类型*/ int next; /*指针项*/ }SNodeType; /*表结点类型*/ SNodeType R[MAXNUM]; /*R是静态链表存储的排序表*/ 设数据元素已存储在静态链表中,且0号单元作为头结 点,根据链表的特点可以通过不移动记录而只是改变链接 指针,将记录按关键码组织成一个有序静态链表。
2019/2/7
数据结构
7
例如,对于以下序列(为简便起见,每一个记录只列出其排 序码,用排序码代表记录): [ 10 18 20 36 60 ] 25 30 18 12 56 其中,前5个记录组成的子序列是有序的,这时要将第6 个记录插入到前5个记录组成的有序子序列中去,得到一个含 有6个记录的新有序序列。完成这个插入首先需要找到插入位 置:20<25<36,因此25应插入到记录20和记录36之间,从而 得到以下新序列: [ 10 18 20 25 36 60] 30 18 12 56 这就是一趟直接插入排序的过程。
0
MAXINT
1 49 8 13
2 38 1 38
3 65 5 65
4 97 0 97
5 76 4 76
6 13 7 49
7 27 2 27
8 49 3 49
6
MAXINT
6
7
1
5
0
4
8
2
3
2019/2/7
数据结构
24
表排序之后的重排示意图-----i:第几次,j:当前元素的位置 13--->27--->38--->49--->49---> 65--->76--->97
7 27 2
8 49 3
(a)
6
MAXINT
13 2
27 3
38 4
49 5
49 6
65 7
76 8
97 0
(b)
1
2019/2/7
数据结构
23
重排记录方法:按链表顺序扫描各结点,将逻辑上的第i 个数据元素调整到数组的第i个分量上。
问题:调整前的第 i个纪录可能在数组的第 j 个分量上, 因此需要将两个分量进行交换,但交换后会破坏指向i分量的 链。 解决方法:为了保持原有的链,需要将第i个结点的指针 域改变为j,起一个引导的作用。
⑴领会排序的基本思想和基本概念; ⑵理解并掌握各种排序方法的基本思想、步骤、算法及时 空效率分析; ⑶了解外排序的定义和基本方法。
3.教学重点:
常用排序方法的基本思想、基本步骤和算法。
4.教学难点:(1)快速排序 (2)堆排序 5.学时安排:10学时
2019/2/7 数据结构
(3)基数排序
2
8.1 基本概念
数据结构
12
(1)
最好情况下: 即待排序列已按关键码有序,每趟操作只需1次比较,0 次移动。即: 总比较次数= n-1次 总移动次数= 0次 (2) 最坏情况下: 即第j趟操作,插入记录需要同前面的j个记录进行j次 关键码比较,移动记录的次数为j+2次。 总比较次数


j 1
n 1
j
1 n( n 1) 2
1.记录、关键码和排序表:
记录: 数据元素 关键码:作为排序依据的数据项称为数据元素的关键码。
排序表:若干个(n个)排序纪录组成的集合。
排序表也称成为文件,主要操作是排序。
2.非递减序列、递减序列、非递增序列、递增有序 3.稳定排序和非稳定排序
2019/2/7
数据结构
3
4.内部排序和外部排序
5.对排序方法的评价
2019/2/7 数据结构 19
【例8-2】设排序表为:49, 38, 65, 97, 76, 13, 27, 49。表插 入排序过程如图 8-2所示。
2019/2/7
数据结构
20
2019/2/7
数据结构
21
性能分析: 表插入排序的基本操作是将一个记录插入到已排好序的 有序链表中。设有序表长度为i,则需要比较至多i+1次,修 改指针2次。因此,总比较次数与直接插入排序相同。所以, 时间复杂度仍为O(n2)。 没有移动数据。
6
MAXINT
(6)
13 (6) 13 (6)
(7)
27 (7) 27 (7)
2019/2/7
数据结构
22
2、重排:表插入排序得到一个逻辑上有序的链表,物理上
无序,查找则只能进行顺序查找。 有时还需要关键码按物理存储有序,这是需要将逻辑上 有序的链表进行重排,使得关键码按物理存储有序。如下图:
0
MAXINT
1 49 8
2 38 1
3 65 5
4 97 0
5 76 4
6 13 7
2019/2/7 数据结构 8
直接插入排序:仅有一个记录的表总是有序的,因此,
对n个记录的表,可从第二个记录开始直到第n个记录,逐个 向有序表中进行插入操作,从而得到n个记录按关键码有序的 表。
2019/2/7
数据结构
9
R[0] R[1] 初始序列: i=2 : (20) i=3 : (18) i=4 : (10) …… 36 20 18 10
第8章
排序
排序是指将一组数据元素按某个数据项值的大小排列成 一个有序序列的过程。 排序是计算机程序设计中经常使用的一种重要操作,是 组织数据和处理数据的最基本最重要的运算之一。 排序被广泛应用于数据处理、情报检索、商业金融等许 多领域。
2019/2/7
数据结构
1
1.教学内容:排序的概念、5类排序(10种方法) 2.教学目的:
总移动次数
2019/2/7
1 ( j 2) n(n 1) 2n 2 j 1
数据结构 13
n 1
(3)平均情况下:
即第j趟操作,插入记录大约同前面的j/2个记录进行关键 码比较,移动记录的次数为j/2+2次。
总比较次数
总移动次数

j 1
n 1
j 1 1 n(n 1) n 2 2 4 4
2019/2/7
数据结构
11
【性能分析:】 空间性能:仅用了一个辅助单元R[0]作为监视哨,空间 复杂度为O(1)。 时间性能:向有序表中逐个插入记录的操作,进行了n1 趟,每趟操作分为比较关键码和移动记录,而比较的次数和 移动记录的次数取决于初始序列的排列情况 。分三种情况讨 论:
2019/2/7
2019/2/7
数据结构
10
【算法8-1】直接插入排序 void D_InsertSort(datatype R[ ], int n) { /*对排序表R[1]..R[n]进行直接插入排序,n是记录的个数*/ for(i=2; i<=n; i++) if (R[i].key<R[i-1].key) {R[0]=R[i]; /*将R[i]插入R[1].. R[i-1]中,R[0]为监测哨*/ for(j=i-1; R[0].key<R[j].key; j--) R[j+1]=R[j]; /*后移记录*/ R[j+1]=R[0]; /*插入到合适位置*/ } }
既然是在有序表中确定插入位置,因此在寻找R[i]的插入 位置时,就可以采用折半查找的方法,用折半查找方法查找 R[i]的插入位置,再将 R[i] 插入进去,使得R[i] 到R[i] 有序, 这种方法就是折半插入排序。
2019/2/7
数据结构
15
【算法8-2】折半插入排序算法 void B_InsertSort(datatype R[ ], int n) { /* 对排序表R[1]..R[n]作折半插入排序, n是记录的个数*/ for(i=2; i<=n; i++) { R[0]=R[i]; /* 保存待插入元素 */ low=1; high=i1; /* 设置初始区间 */ while(low<=high) /* 该循环语句完成确定插入位置 */ { mid=(low+high)/2; if(R[0].key>R[mid].key) low=mid+1; /* 插入位置在高半区中 */ else high=mid-1; /* 插入位置在低半区中 */ } for(j=i-1;j>=high+1;j--) /* high+1为插入位置 */ R[j+1]=R[j]; /* 后移元素,留出插入空位 */ R[high+1]=R[0]; /* 将元素插入 */ } } 2019/2/7
0
初始 状态
MAXINT
1 49 8 13 (6)
2 38 1 38 1
3 65 5 65 5
4 97 0 97 0
5 76 4 76 4
6 13 7 49 8
7 27 2 27 2
8 49 3 49 3
i=1 j=6 i=2 j=7
6
MAXINT
6
i=3 j=(2)、 7
MAXINT
13 (6)
27 (7)
R[2] R[3] R[4] R[5] R[6] R[7] R[8] R[9] R[10] 20 36 20 18 18 18 36 20 10 10 10 36 60 60 60 60 25 25 25 25 30 30 30 30 18 18 18 18 12 12 12 12 56 56 56 56
2019/2/7 数据结构 5
8.2 插入排序
插入排序的基本思想是:每次将一个待排序的记录, 按其关键字大小插入到前面已经排好序的子表的适当位 置,直到全部记录插入完成,整个表有序为止。
8.2.1 8.2.2 8.2.3 8.2.4
直接插入排序 折半插入排序 表插入排序(重排算法* ) 希尔排序(Shell’s Sort)!
折半插入排序只适合于顺序存储的排序表。
2019/2/7
数据结构
17
8.2.3表插入排序及重排
1、表插入排序:表插入排序就是直接插入排序应用于 用链表存储的排序表。
直接插入排序、折半插入排序均要大量移动记录,时间开 销大。若不移动记录完成排序,需要改变存储结构,将排序表 按链表存储。 表插入排序:用单链表做排序表的存储结构,通过改变链 接指针,实现关键码有序的过程。 与顺序存储的排序表所不同的是:直接插入排序要移动记 录,而表插入排序是修改链接指针。
空间性能:除排序表以外的内存占用情况。 时间性能:比较关键码的次数,数据移动的次数。
它们往往是排序表规模(n)的函数
2019/2/7
数据结构
4
6. 记录和排序表的数据结构
在本章的讨论中,除特殊声明外,一般采用顺序结构 存储排序表。 记录和排序表的类型定义如下: #define MAXNUM … /* MAXNUM 为足够大的数*/ typedef struct { keytype key; /*关键码字段*/ …… /*其它信息*/ } datatype; /*记录类型*/ datatype R[MAXNUM]; /*定义排序表的存储*/ 如不加特别说明,排序表中的记录R1…Rn存放在 R[1]…R[n]分量中,R[0]分量闲置或做监视哨(n是排序 表中记录的个数)。
相关文档
最新文档