数据结构第10章排序

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

例如,n=6,数组R的六个排序码分别为:17,3,25, 14,20,9。它的直接插入排序的执行过程如图1所示。
初始状态
R[0] (17 )
R[1] 3
R[2] 25
R[3] 14
R[4] 20
R[5] 9
第一次插入
(3
第二次插入
(3
第三次插入
(3
第四次插入
(3
17 ) 17 14 14
25
14
20
10.2 插入排序
❖ 直接插入排序 ❖ 折半插入排序 ❖ 2-路插入排序 ❖ 表插入排序 ❖ 希尔排序
4.表插入排序
1)基本思想
通过改变排序过程中采用的存储结构,减少在 排序过程中进行“移动”记录的操作。利用静态 链表进行排序,并在排序完成之后,一次性地调 整各个记录相互之间的位置,即将每个记录都调 整到它们所应该在的位置上。
for( j=i-1;L.r[0].key < L.r[j].key; j-- ) L.r[j+1] = L.r[j]; // 记录后移
L.r[j+1] = L.r[0]; // 插入到正确位置 } } // InsertSort
3)直接插入排序性能分析
实现排序的基本操作有: (1)“比较” 关键字的大小 (2)“移动”记录
if (L.r[0].key< L.r[mid].key) high=mid-1; else low=mid+1; } for( j=i-1; j>=low; j ) L.r[j+1]=L.r[j]; L.r[low]=L.r[0]; } }
3)折半插入排序性能分析
折半插入排序减少了关键字的比较次数, 但记录的移动次数不变,其时间复杂度与直 接插入排序相同,时间复杂度为 O(n2) 。
(13 27 38)
final
first
(49 49 65 76 97) (13 27 38)
final
first
3) 2-路插入排序性能分析
2-路插入排序只能减少移动记录的次数, 而不能绝对避免移动记录。 2-路插入排序 中,移动记录的次数约为n2/8 。
当L.r[1]是待排序记录中关键字最小或最 大的记录时,2-路插入排序就完全失去了它 的优越性。
在整个排序过程中,不会通过比较而相互交换。
2.折半插入排序
1)基本思想 考虑到 L.r[1..i-1] 是按关键字有序的有序序列,
则可以利用折半查找实现“ L.r[1…i-1]中查找 L.r[i] 的插入位置”如此实现的插入排序为折半插 入排序。
例:有6个记录,前5个已排序的基础上,对第6个记录排序 。 [ 1 5low 27 36 mi5d 3 69 ] 42high
方法及算法 教学重点:排序方法的掌握 教学难点:性能分析 教学方法:讲授,投影
课题21:排序概念 插入排序
教学过程:
内容: 10.1概述 排序概念 排序的分类:内部排序和外部排序;稳定排序和不
稳定排序 10.2插入排序 10.2.1直接插入排序 算法介绍 监视哨 时间和空间性能分析
10.1 排序的基本概念
序序列从L.r[1..i-1]变为L.r[1..i]。 完成这个“插入”分三步进行: 1.查找L.r[i]在有序子序列L.r [1..i-1]中的插入位置j; 2.将L.r [j..i-1]中的记录后移一个位置; 3.将L.r [i]复制到L.r [j]的位置上。
整个排序过程进行n–1趟插入,即:先将序列中的第1个记 录着成一个有序的子序列,然后从第2个记录起逐个插入, 直至整个序列变成接关键字非递减有序序列为止。
内部排序的方法很多,每种方法都有各 自的优缺点,适合在不同的环境(如记录的 初始排列状态等)下使用。
按内部排序过程中所需的工作量来区分: 简单排序方法,其时间复杂度为O(n2)
排序 先进排序方法,其时间复杂度为O(nlogn) 基数排序,其时间复杂度为O(d·n)
按排序过程中依据的原则分
插入类(直插排序、二分排序、希尔排序) 交换类(冒泡排序、快速排序) 排序 选择类(直选排序、树型排序、堆排序) 归并类(二路归并排序、多路归并排序) 分配类(多关键字排序、基数排序)
(38)
final i=3: (49 65)
final
first
(38)
first
i=4: (49 65 97)
(38)
final i=5: (49 65 76 97)
first
(38)
final
first
i=6: (49 65 76 97)
(13 38)
i=7: i=8:
final
first
(49 65 76 97)
#define MAXSIZE 20 //一个顺序表的最大长度
typedef int KeyType; //定义关键字为整数类型
typedef struct{
KeyType key;
//关键字项
InfoType otherinfo; //其他数据项
}RedType; //记录类型
typedef struct{
49
38 65 97 76 13 27 49 key域
1
0 - - - - - - - next域
0
1 2345678
i=2 MAXINT 49 388 65 97 76 13 27 49
21
0 1- - - - - - -
0
1 2345678
i=3 MAXINT 49 38 65 97 76 13 27 49
3.内部排序与外部排序
内部排序 指当文件的数据量不太大时,全部信息放
内存中处理的排序方法。 外部排序
当文件的数据量较大时,排序过程中需要 在内、外存之间不断地进行数据交换才能达 到排序的目的,这种排序称为外排序。
4.内部排序的方法
内部排序的过程是一个逐步扩大记录的 有序区长度的过程。在排序的过程中,参 与排序的记录序列中存在两个区域:有序 区和无序区。使有序区中记录的数目增加 一个或几个的操作称为一趟排序。
( 42>36源自文库)
[ 15 27 36 53 69low] 42high
( 42<53 ) mid
[ 15 27 36 hig5h3 69low] 42
(high<low ,查找结束,插入位置为low 或high+1 )
[ 15 27 36 42 53 69 ]
折半插入排序在寻找插入位置时,不是逐个比较 而是利用折半查找的原理寻找插入位置。待排序元 素越多,改进效果越明显。
第十章 排序
第十章 排序
教学时间:6学时 教学目的: 1、 理解排序的基本概念; 2、 掌握几种基本排序的方法及其比较; 3、 了解外部排序 教学内容:
什么是排序及其基本术语、插入排序、交换排 序、选择排序、归并排序、分配排序的方法和比 较、外部排序的简单介绍。
课题21:排序概念 插入排序
教学时间:2学时 教学目的: 1、 理解排序的基本概念; 2、 掌握插入排序 教学内容:什么是排序及其基本术语、插入排序的
i=6 MAXINT 49 38 65 97 76 1133 27 49
62
3 1 5 0 4 2- - -
0
1 2345678
i=7 MAXINT 49 38 65 97 76 13 277 49
6
3 1 5 0 4 72 2- -
0
1 2345678
i=8 MAXINT 49 38 65 97 76 13 27 4499
9
25 )
14
20
9
17
25 )
20
9
17 20
25 )
9
第五次插入
(3 9
14
17
20
25)
图 1 直接插入排序示例
2)直接插入排序算法描述 void InsertionSort ( SqList &L ) {// 对记录序列R[1..L.length]作直接插入排序。
for ( i=2; i<=L.length; ++i ) { L.r[0] = L.r[i]; // 复制为监视哨
2)待排记录序列的存储结构
#define MAXSIZE 100 //静态链表容量
typedef struct{
RcdType rc; //记录项
int next;
//指针项
} SLNode; //表结点类型
typedef struct{
SLNode r[MAXSIZE+1]; //0号单元为表头结点
int length; //链表当前长度
} SLinkListType; //静态链表类型
3)具体做法 首先将静态链表中数组下标为“1” 的分量
(结点)和表头结点构成一个循环链表,然后 依次将下标为“2”至“n”的分量(结点)按 记录关键字非递减有序插入到循环链表中。
初始
0
1 2345678
MAXINT 状态
2
03 1 0- - - - - -
0
1 2345678
i=4 MAXINT 49 38 65 9977 76 13 27 49
2
3 1 40 0- - - - -
0
1 234 5678
i=5 MAXINT 49 38 65 97 76 13 27 49
2
3 1 54 0 4- - - -
0
1 2345678
1.排序
设含有n个记录的文件{R1,R2,…Rn},相应的关键 字为{K1,K2,…Kn},需确定一种排列P(1),P(2)…P(n) 使其相应的关键字满足递增(或递减)关系:
KP(1)≤KP(2)≤…KP(n) 或 KP(1)≥KP(2)≥…KP(n) 使上述文件成为一个按其关键字线性有序的文件{RP(1), RP(2) ,…RP(n)},这种运算就称为排序。
折半插入排序是“稳定的”
3. 2-路插入排序
1)基本思想 2-路插入排序是在折半插入排序的基础上改进
的,目的是减少排序过程中移动记录的次数,但 为此需要n个记录的辅助空间。
2)具体做法 另设一个和 L.r 同类型的数组d,首先将 L.r[1]
赋值给 d[1] ,并将 d[1] 看成是在排好序的序列 中处于中间位置的记录,然后从 L.r 中第 2 个记 录起依次插入到d[1] 之前或之后的有序序列中。 先将待插入记录的关键字和 d[1] 的关键字进行比 较。
若 L.r[i]<d[1].key,则将 L.r[i] 插入到 d[1] 之前的有序表中。反之,插入到 d[1] 之后的有序 表中。
2-路插入排序过程示例:
【初始关键字】 49 38 65 97 76 13 27 49
排序过程中d 的状态如下:
i=1: (49)
first final
i=2: (49)
将数据元素的无序序列调整为有序序列的过程。
2.排序算法的稳定性
排序码(Key) 作为排序依据的记录中的一个属性。它可以是
任何一种可比的有序数据类型,它可以是记录的关 键字,也可以是任何非关键字。
如果待排序的序列中,存在多个具有相同排序 码的数据元素,若经过排序这些数据元素的相对次 序保持不变,则称这种排序算法是稳定的,若经过 排序,这些数据元素的相对次序发生了改变,则称 这种排序算法是不稳定的。
对于直接插入排序: 最好情况“比较”次数:n-1;“移动”次数:2(n-1) 最坏的情况“比较”和“移动”的次数均达到最大值,
分别为:(n+2)(n-1)/2;(n+4)(n-1)/2 由于待排记录序列是随机的,取上述二值的平均值。所
以直接插入排序的时间复杂度为 O(n2)。 直接插入排序是“稳定的”:关键码相同的两个记录,
待排元素序列: [53] 27 36 15 69 42 第一次排序:(27) [27 53] 36 15 69 42 第二次排序:(36) [27 36 53] 15 69 42 第三次排序:(53) [15 27 36 53] 69 42 第四次排序:(69) [15 27 36 53 69] 42 第五次排序: (42) [15 27 36 42 53 69] 直接插入排序示例(插入操作要进行n-1次)
2)折半插入排序算法
void BinsertSort(SqList &L) { int i,low,high,mid;
for(i=2; i<= L.length; ++i) { L.r[0]=L.r[i];
low=1; high=i-1; While(low<=high) { mid=(low+high)/2;
RedType r[MAXSIZE+1]; //r[0]用作哨兵单元
int length;
//顺序表长度
}SqList; //顺序表类型
10.2 插入排序
❖ 直接插入排序 ❖ 折半插入排序 ❖ 2-路插入排序 ❖ 表插入排序 ❖ 希尔排序
1.直接插入排序
1)一趟直接插入排序的基本思想 将记录L.r[i]插入到有序子序列L.r[1..i-1]中,使记录的有
相关文档
最新文档