内部排序(精)
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第十章 内部排序
10.1
10.2
10.3
源自文库
10.4
10.5
10.6
10.7
2018/9/16
排序的基本概念 插入排序 快速排序 选择排序 归并排序 基数排序(略) 各种内部排序方法的比较讨论
第十章 内部排序 1
10.1 排序的基本概念
将一组杂乱无序的数据按一定的规律顺次排列
起来叫做排序(sort)。
对一批记录的排序,应该指定是根据记录中哪
个域的数据进行排列。这个作为排序依据的数 据域我们称之为关键字(key)。
本章讨论的排序均为按递增顺序排序,并假定
要排序的记录均已存储在一个一维数组中。
2018/9/16 第十章 内部排序 2
该一维数组定义如下:
#define MAXITEM 100 struct record { KeyType key; /*关键字*/ ElemType data; /*其他域*/ }sqlist[MAXITEM];
第十章 内部排序
(4) 13 14 15 17 ︹ 42 20 23 28 ︺
(5) 13 14 15 17 20 ︹ 42 23 28 ︺
(6) 13 14 15 17 20 23 ︹ 42 28 ︺
(7) 13 14 15 17 20 23 28 ︹ 42 ︺
12
需扫描的趟数视原始数据最初的排列次
2018/9/16 第十章 内部排序 6
(0)
42 [20 [17 [13 [13 [13 [13 [13
20 42] 20 17 17 14 14 14
17
13
28
14
23
15
直 接 插 入 排 序 图
(1) (2) (3) (4) (5) (6) (7)
42] 20 20 17 17 15 42] 28 20 20 17 42] 28 23 20 42] 28 23 42] 28 42]
2018/9/16 第十章 内部排序 13
冒泡排序算法
void bubblesort(sqlist r, int n) { int i,j,flag; for(i=1;i<=n-1;i++) { flag=1; for( j=i;j<=n-1;j++) if (r[j+1].key < r[j].key)
2018/9/16 第十章 内部排序 9
其他插入排序
折半插入排序:在有序表中进行查找和
插入,从而查找操作可利用折半查找来 实现,由此进行的插入排序称为折半插 入排序。 希尔排序:对直接插入排序进行改进得 到的一种插入排序方法。基本思想是: 先将整个待排记录序列分割成为若干子 序列分别进行直接插入排序,待整个序 列中的记录“基本有序”时,再对全体 记录进行一次直接插入排序。
2018/9/16 第十章 内部排序 10
冒泡排序
冒泡排序是一种简单而且容易理解的排序方
法,它和气泡从水中不断往上冒的情况有些 类似。 其基本思想是对存放原始数据的数组,按从 后往前的方向进行多次扫描,每次扫描称为 一趟(pass)。当发现相邻两个数据的次序 与排序要求的“递增次序”不符合时,即将 这两个数据进行互换。这样,较小的数据就 会逐单元向前移动,好象气泡向上浮起一样。 动画演示
序的不同而不同,最坏的情况要进行 (n-1)趟扫描,一般常常少于(n-1)趟即 可完成。 可以设置一个标志flag用来指示扫描中有 没有进行数据交换,每趟扫描开始前将 其置1。当这趟扫描至少出现一次互换时, 将其置0。如某趟扫描后flag仍为1,说明 此趟扫描已无数据互换,则排序结束, 不必再继续扫描了。
2018/9/16 第十章 内部排序 5
10.2 直接插入排序
直接插入排序的基本思想是:从数组的
第二个单元开始,依次从原始数据中取 出数据,并将其插入到数组中该单元之 前的已排好序的序列中合适的位置处。 直接插入算法需要经过(n-1)趟插入过 程。如果数据恰好应插入到序列的最后 端,则不需移动数据,可节省时间,所 以若原始数据大体有序,此算法可以有 较快的运算速度。动画演示
7
2018/9/16
第十章 内部排序
直接插入排序算法
void insertsort (sqlist r, int n) { int i,j; for( i=2; i<=n; i++) { r[0]=r[i]; /* r[0]用于暂时存放待插入的元素*/ j= i-1; /* j为待比较元素下标,初始时指 向待插入元素前一个单元*/
2018/9/16 第十章 内部排序 11
冒 泡 排 序 过 程 图
2018/9/16
(0) ︹ 42 20 17 13 28 14 23 15 ︺
(1) 13 ︹ 42 20 17 14 28 15 23 ︺
(2) 13 14 ︹ 42 20 17 15 28 23 ︺
(3) 13 14 15 ︹ 42 20 17 23 28 ︺
2018/9/16 第十章 内部排序 8
直接插入排序算法续
while (r[0].key<r[j].key) { r[j+1]=r[j]; j--; } r[j+1]=r[0]; /* 在j+1位置插入r[0]*/ }
}
简单插入排序的时间复杂性是O(n2)(平均约为n2 /4)。 对于有相同关键字记录的情况,此算法是稳定的。
2018/9/16 第十章 内部排序 4
内部排序方法分类
按所用策略不同,可分五类:插入排序、
交换排序、选择排序、归并排序和基数 排序。 按所需工作量,可分为三类:简单排序 O(n2)、先进排序O(nlogn)、基数排序 O(d*n)。 内部排序两种基本操作:1. 比较两个关 键字的大小;2 .将记录从一个位置移动 到另一个位置。
2018/9/16
第十章 内部排序
3
大多数的排序方法数据是存储在内存中,并
在内存中加以处理的,这种排序方法叫内部 排序。 如果在排序过程中,数据的主要部分存放在 外存储器中(如软盘、硬盘、磁带),借助 内存进行内、外存数据交换,逐步排列记录 之间的顺序,则称之为外部排序。 一种排序方法,如果排序后具有相同关键字 的记录仍维持排序之前的相对次序,则称之 为稳定的,否则称为不稳定的。
10.1
10.2
10.3
源自文库
10.4
10.5
10.6
10.7
2018/9/16
排序的基本概念 插入排序 快速排序 选择排序 归并排序 基数排序(略) 各种内部排序方法的比较讨论
第十章 内部排序 1
10.1 排序的基本概念
将一组杂乱无序的数据按一定的规律顺次排列
起来叫做排序(sort)。
对一批记录的排序,应该指定是根据记录中哪
个域的数据进行排列。这个作为排序依据的数 据域我们称之为关键字(key)。
本章讨论的排序均为按递增顺序排序,并假定
要排序的记录均已存储在一个一维数组中。
2018/9/16 第十章 内部排序 2
该一维数组定义如下:
#define MAXITEM 100 struct record { KeyType key; /*关键字*/ ElemType data; /*其他域*/ }sqlist[MAXITEM];
第十章 内部排序
(4) 13 14 15 17 ︹ 42 20 23 28 ︺
(5) 13 14 15 17 20 ︹ 42 23 28 ︺
(6) 13 14 15 17 20 23 ︹ 42 28 ︺
(7) 13 14 15 17 20 23 28 ︹ 42 ︺
12
需扫描的趟数视原始数据最初的排列次
2018/9/16 第十章 内部排序 6
(0)
42 [20 [17 [13 [13 [13 [13 [13
20 42] 20 17 17 14 14 14
17
13
28
14
23
15
直 接 插 入 排 序 图
(1) (2) (3) (4) (5) (6) (7)
42] 20 20 17 17 15 42] 28 20 20 17 42] 28 23 20 42] 28 23 42] 28 42]
2018/9/16 第十章 内部排序 13
冒泡排序算法
void bubblesort(sqlist r, int n) { int i,j,flag; for(i=1;i<=n-1;i++) { flag=1; for( j=i;j<=n-1;j++) if (r[j+1].key < r[j].key)
2018/9/16 第十章 内部排序 9
其他插入排序
折半插入排序:在有序表中进行查找和
插入,从而查找操作可利用折半查找来 实现,由此进行的插入排序称为折半插 入排序。 希尔排序:对直接插入排序进行改进得 到的一种插入排序方法。基本思想是: 先将整个待排记录序列分割成为若干子 序列分别进行直接插入排序,待整个序 列中的记录“基本有序”时,再对全体 记录进行一次直接插入排序。
2018/9/16 第十章 内部排序 10
冒泡排序
冒泡排序是一种简单而且容易理解的排序方
法,它和气泡从水中不断往上冒的情况有些 类似。 其基本思想是对存放原始数据的数组,按从 后往前的方向进行多次扫描,每次扫描称为 一趟(pass)。当发现相邻两个数据的次序 与排序要求的“递增次序”不符合时,即将 这两个数据进行互换。这样,较小的数据就 会逐单元向前移动,好象气泡向上浮起一样。 动画演示
序的不同而不同,最坏的情况要进行 (n-1)趟扫描,一般常常少于(n-1)趟即 可完成。 可以设置一个标志flag用来指示扫描中有 没有进行数据交换,每趟扫描开始前将 其置1。当这趟扫描至少出现一次互换时, 将其置0。如某趟扫描后flag仍为1,说明 此趟扫描已无数据互换,则排序结束, 不必再继续扫描了。
2018/9/16 第十章 内部排序 5
10.2 直接插入排序
直接插入排序的基本思想是:从数组的
第二个单元开始,依次从原始数据中取 出数据,并将其插入到数组中该单元之 前的已排好序的序列中合适的位置处。 直接插入算法需要经过(n-1)趟插入过 程。如果数据恰好应插入到序列的最后 端,则不需移动数据,可节省时间,所 以若原始数据大体有序,此算法可以有 较快的运算速度。动画演示
7
2018/9/16
第十章 内部排序
直接插入排序算法
void insertsort (sqlist r, int n) { int i,j; for( i=2; i<=n; i++) { r[0]=r[i]; /* r[0]用于暂时存放待插入的元素*/ j= i-1; /* j为待比较元素下标,初始时指 向待插入元素前一个单元*/
2018/9/16 第十章 内部排序 11
冒 泡 排 序 过 程 图
2018/9/16
(0) ︹ 42 20 17 13 28 14 23 15 ︺
(1) 13 ︹ 42 20 17 14 28 15 23 ︺
(2) 13 14 ︹ 42 20 17 15 28 23 ︺
(3) 13 14 15 ︹ 42 20 17 23 28 ︺
2018/9/16 第十章 内部排序 8
直接插入排序算法续
while (r[0].key<r[j].key) { r[j+1]=r[j]; j--; } r[j+1]=r[0]; /* 在j+1位置插入r[0]*/ }
}
简单插入排序的时间复杂性是O(n2)(平均约为n2 /4)。 对于有相同关键字记录的情况,此算法是稳定的。
2018/9/16 第十章 内部排序 4
内部排序方法分类
按所用策略不同,可分五类:插入排序、
交换排序、选择排序、归并排序和基数 排序。 按所需工作量,可分为三类:简单排序 O(n2)、先进排序O(nlogn)、基数排序 O(d*n)。 内部排序两种基本操作:1. 比较两个关 键字的大小;2 .将记录从一个位置移动 到另一个位置。
2018/9/16
第十章 内部排序
3
大多数的排序方法数据是存储在内存中,并
在内存中加以处理的,这种排序方法叫内部 排序。 如果在排序过程中,数据的主要部分存放在 外存储器中(如软盘、硬盘、磁带),借助 内存进行内、外存数据交换,逐步排列记录 之间的顺序,则称之为外部排序。 一种排序方法,如果排序后具有相同关键字 的记录仍维持排序之前的相对次序,则称之 为稳定的,否则称为不稳定的。