第10章-内部排序PPT课件

合集下载

第10章 排序 PPT课件

第10章 排序 PPT课件

清华大学出版社
概述
数据结构(C++版)
排序算法的存储结构
从操作角度看,排序是线性结构的一种操作,待排序 记录可以用顺序存储结构或链接存储结构存储。
假定1:采用顺序存储结构,关键码为整型,且记录 只有关键码一个数据项。
int r[n+1]; //待排序记录存储在r[1]~r[n],r[0]留做他用
假定2:将待排序的记录序列排序为升序序列。
i = 6 18 10 15 21 25 25* 18
10 15 18 21 25 25*
r[0]的作用? 暂存单元 43;+版)
关键问题(1)如何构造初始的有序序列?
解决方法:
将第1个记录看成是初始有序表,然后从第2个记录起 依次插入到这个有序表中,直到将第n个记录插入。 算法描述:
学号 0001 0002 0003 …
姓名 王军 李明 汤晓影

高数 85 64 85 …
英语 68 72 78 …
思想品德 88 92 86 …
清华大学出版社
概述
数据结构(C++版)
排序的基本概念
单键排序:根据一个关键码进行的排序; 多键排序:根据多个关键码进行的排序。
学号 0001 0002 0003 …
算法描述:
r[0]=r[i]; j=i-1; while (r[0]<r[j]) {
r[j+1]=r[j]; j--; }
r[0]有两个作用:
1. 进入循环之前暂存了r[i] 的值,使得不致于因记录 的后移而丢失r[i]的内容;
2. 在查找插入位置的循环 中充当哨兵。
清华大学出版社
插入排序
姓名 王军 李明 汤晓影

第10章内部排序[1]PPT课件

第10章内部排序[1]PPT课件
13
8.2 交换排序
冒泡排序
排序过程
将第一个记录的关键字与第二个记录的关键字进行 比较,若为逆序r[1].key>r[2].key,则交换;然 后比较第二个记录与第三个记录;依次类推,直至 第n-1个记录和第n个记录比较为止——第一趟冒 泡排序,结果关键字最大的记录被安置在最后一个 记录上 对前n-1个记录进行第二趟冒泡排序,结果使关键 字次大的记录被安置在第n-1个记录位置 重复上述过程,直到“在一趟排序过程中没有进行 过交换记录的操作”为止
7
折半插入排序 排序过程:用折半查找方法确定插入位置的排序叫~
例 i=1
(30) 13 70 85 39 42 6 20
i=2 13 (13 30) 70 85 39 42 6 20
…...
i=7 6 (6 i=8 20 (6
s i=8 20 (6
s i=8 20 (6
i=8 20 (6
i=8 20 (6
时间复杂度:T(n)=O(n²) 空间复杂度:S(n)=O(1)
9
希尔排序(缩小增量法) 排序过程:先取一个正整数d1<n, 把所有相隔d1的记录放一组,组内 进行直接插入排序;然后取d2<d1, 重复上述分组和排序操作;直至 di=1,即所有记录放进一个组中排 序为止
10
例 初始: 49 38 65 97 76 13 27 48 55 4 取d1=5 一趟分组:49 38 65 97 76 13 27 48 55 4
13 30 39 42 70 85 ) 20
13 30 39 m
13 30 39 mj 13 30 39
s mj
42 70 42 70 42 70
85 ) 20 j 85 ) 20

数据结构课件_第10章 内部排序

数据结构课件_第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

西安电子科技大学_数据结构_第十章内部排序_课件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章 内部排序 资料水利水电学院.ppt

第10章 内部排序  资料水利水电学院.ppt
一、 直接插入排序 (Straight Insertion Sort)
基本思想是:假设待排序的记录存放在数组R[1..n]中。初始 时,R[1]自成1个有序区,无序区为R[2..n]。从i=2起直至i=n为止, 依次将R[i]插入当前的有序区R[1..i-1]中,生成含n个记录的有序 区。
当插入第i (i 1) 个记录时,前面的 R[1], …, R[i-1]已经排好 序。这时,用R[i]的关键字与R[i-1], R[i-2], … R[1] 的关键字顺序 进行比较,找到插入位置即将R[i]插入,插入位置之后的所有记 录依次向后移动。
InfoType otherinfo; //其它数据项
}RcdType;
typedef struct {
RcdType r[MAXSIZE+1]; // r[0] 闲置或用作哨兵单元
int length;
//顺序表长度
}SqList;
//顺序表类型
9
2. 评价排序算法好坏的标准: ① 时间性能分析 以算法中用得最多的基本操作的执行次数(或者其 数量级)来衡量,这些操作主要是比较元素、移动或 交换元素。在一些情况下,可能还要用这些次数的平 均数来表示。
13
直接插人排序算法描述: 方法:Ki与Ki-1,Ki-2,…K1依次比较,直到找到应插入的位置。 void InsertSort (SqList&L){ //对顺序表L作直接插入排序。
for(i=2;i<=L.length;++i) if LT(L.r[i].key,L.r[i-1].key){//“<”,需将L.r[i]插入有序子表 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章_内排序

按排序过程中使用到的存储介质来分,可以将排 序分成两大类 内排序和外排序。 序分成两大类:内排序和外排序。 两大类: 内排序是指在排序过程中所有数据均放在内存中 内排序是指在排序过程中所有数据均放在内存中 处理,不需要使用外存的排序方法。而对于数据量很 大的文件,在内存不足的情况下,则还需要使用外存, 这种排序方法称为外排序 这种排序方法称为外排序。 外排序。 排序码相同的记录,若经过排序后,这些记录 仍保持原来的相对次序不变,称这个排序算法是稳 仍保持原来的相对次序不变,称这个排序算法是稳 不稳定的排序算法。 定的。否则,称为不稳定的排序算法 定的。否则,称为不稳定的排序算法。
为了方便, 为了方便,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)。

第十章 内部排序

第十章  内部排序

共进行n-1趟排序, 共进行n(n-1)/2次比较 T(n)=O(n2)
二、快速排序
• 算法思想:
1. 指定枢轴(通常为第一个记录)
2. 通过一趟排序将以枢轴为中心,把待排记录 分割为独立的两部分,使得左边记录的关键 字小于枢轴值,右边记录的关键字大于枢轴 值
3. 对左右两部分记录序列重复上述过程,依次 类推,直到子序列中只剩下一个记录或不含 记录为止。
27 38 13 49 76 97 65 49 13 27 38 49 65 76 97
具体实现: low=s; high=t; pivotkey=L.r[low].key; 1. 从high开始往前找第一个关键字小于pivotkey的记 录,与枢轴记录交换 2. 从 low 开始往后找第一个关键字大于 pivotkey 的记 录,与枢轴记录交换 3. 重复上述两步直到low= =high为止 4. 此时枢轴记录所在的位置i=low=high
int partition(SqList &L, int low, int high) { //交换顺序表L中的子表L.r[low..high]的记录,枢轴记录到位,并返回其所在位置 //此时在它之前(后)的记录均不大(小)于它 piovtkey=L.r[low].key; //用子表的第一个记录作枢轴记录 while(low<high) //从表的两端交替地向中间扫描 { while(low<high&&L.r[high].key>=piovtkey) - -high; L.r[low] L.r[high]; //将比枢轴记录小的记录交换到低端 while(low<high&&L.r[low].key<=priotkey) ++low; L.r[low] L.r[high]; //将比枢轴记录大的记录交换到高端 } return low; //返回枢轴所在的位置 }//Partition

内部排序

内部排序
7
2013-8-3
第十章 内部排序
直接插入排序算法
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为待比较元素下标,初始时指 向待插入元素前一个单元*/
起来叫做排序(sort)。
对一批记录的排序,应该指定是根据记录中哪
个域的数据进行排列。这个作为排序依据的数 据域我们称之为关键字(key)。
本章讨论的排序均为按递增顺序排序,并假定
要排序的记录均已存储在一个一维数组中。
2013-8-3 第十章 内部排序 2
该一维数组定义如下:
#define MAXITEM 100 struct record { KeyType key; /*关键字*/ ElemType data; /*其他域*/ }sqlist[MAXITEM];
2013-8-3 第十章 内部排序 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)。 对于有相同关键字记录的情况,此算法是稳定的。
2013-8-3 第十章 内部排序 6
(0)
42 [20 [17 [13 [13 [13 [13 [13
20 42] 20 17 17 14 14 14
17
13
28
14
23
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
L.r[j+1]=L.r[j]; //将j……i-1的记录后移一格 L.r[j+1]=L.r[0]; } //将Ri插入到位置j+1 }
-
算法效率
时间复杂度
待排序记录按关键字从小到大排列(正序)
n
比较次数: 1 n 1 i2
移动次数: 0
待排序记录按关键字从大到小排列(逆序)
比较次数:
n i (n2)(n1)
i2
2
移动次数:
n
(n4)(n1)
(i1)
i2
2
待排序记录随机,取平均值
比较次数: n 2
4
移动次数: n 2
4
总的时间复杂度:T(n)=O(n2)
空间复杂度:S(n)=O(1)
-
3. 折半插入排序
排序过程:用折半查找方法确定插入位置。 举例:
i=1: (38) (49) 38 65 97 76 13 27 49
5 R’={5}
R={10,2}
2 R’={2,5}
R={2}
10 R’={2,5,10}
R={ }
2 R’={2,2,5,10}
-
2. 直接插入排序
排序过程:整个排序过程为n-1趟插入
将序列中第1个记录看成是一个有序子序列 从第2个记录开始,逐个进行插入,直至整个序列有序
R1 R2 …… Rn
内部排序适用于记录个数不很多的小文件; 外部排序则适用于记录个数太多,不能一次 将其全部放入内存的大文件
排序依据策略
插入排序:直接插入排序, 折半插入排序, 希尔排序 交换排序:冒泡排序, 快速排序 选择排序:简单选择排序, 堆排序 归并排序:2-路归并排序 基数排序
-
3. 排序的基本操作
LMH
H LM H+1:插入位置
i=2: (65) (38 49) 65 97 76 13 27 49
LM H;1:插入位置
i=8:
(13 27 38 49 49 65 76 97)
-
算法程序
void BInsertSort ( Sqlist &L)
{ for( i=2; i<=L.length; ++i ) {
}RedType;
//关键字项 //其它数据项 //记录类型
type struct {
RedType r[MAXSIZE+1]; //r[0]空作为哨兵
int length;
//顺序表长度
}SqList;
//顺序表类型
-
5. 算法复杂度分析
评价排序算法的标准:
执行时间 所需辅助空间 稳定性
实现排序时修改地址向量中的地址,排序结束时统一 调整记录的存储位置
-
顺序存储结构定义
#define MAXSIZE 20 //顺序表的长度 typedef int KeyType; //关键字类型为整数类型
typedef struct{ KeyType key; InfoType otherinfo;
-
算法程序
viod Dinsertsort(Sqlist &L) { for (i=2;i<=L.length;++i) //对每一个Ri∈R
//小于时,需将L.r[i]插入到有序表 if LT(L.r[i].key, L.r[i-1].key) { L.r[0]=L.r[i]; //复制为哨兵
/*寻找插入位置j*/ for (j=i-1; LT(L.r[0].key, L.r[j].key); --j)
排序的稳定性:假设Ki=Kj,(1≤i≤n; 1≤j≤n; i≠j)且在排序前的序列中Ri领先于Rj,如在排序后 Ri仍领先于Rj,则称所用的排序方法是稳定的,反 之则称排序方法是不稳定的。
-
2. 排序的分类
待排序记录所在位置
内部排序:待排序记录存放在内存中 外部排序:排序过程中需对外存进行访问的排序
排序的基本操作:
比较操作:比较两个关键字的大小 改变指向记录的指针(逻辑关系)或将一个记录从
一个位置移动到另一个位置
-
4. 数据的存储形式
待排记录一般有三种存储形式
存放在一组地址连续的存储单元中,类似顺序表
实现排序必须借助移动记录
存放在静态链表中
实现排序只需修改指针
存放在一组地址连续的存储单元中,同时另设一 个指示各个记录存储位置的地址向量
R’={R1} R={ R2,R3,……,Rn }
若R[1..i-1]为有序区,寻找R[i]插入位置的方法:
在R[0]处设置监视哨,即令:R[0]=R[i] 从j=i-1的记录位置开始依次向前比较 若R[i].key<R[j].key,R[j]后移,否则插入位置找到
,将R[i]插入到第j+1个位置
第10章 内部排序
主要内容: 排序的基本概念 插入排序 交换排序 选择排序 归并排序 各种排序方法的比较
-
§10.1 概述
1. 基本概念
排序:将一个数据元素(或记录)的任意序列,重新 排列成一个按关键字有序的序列的过程叫排序。
设序列{R1, R2, …, Rn},相应关键字序列为{ K1, K2, …, Kn },所谓排序是指重新排列{ R1, R2, …, Rn }为 { Rp1, Rp2, …, Rpn },使得满足: {Kp1≤Kp2 …… ≤Kpn} 或 {Kp1≥Kp2 ……≥Kpn}
非就地排序所要求的辅助空间一般为O(n)
-
§10.2 插入排序
1. 插入排序的基本思想
基本思想:设R={R1,R2,……,Rn}为原始序列 ,R’={ }初始为空。插入排序就是依次取出R中的
元素Ri,然后将Ri有序地插入到R’中。
例如:
有序插入
R={5,2,10,2}
R’={ }
R={2,10,2}
L.r[0]=L.r[i];
low=1; high=i-1;
while (low<=high){ //折半查找位置
m=(low+high)/2;
if (L.r[0].key<L.r[m].key) high=m-1;
排序算法的时间开销
排序所需时间
简单排序:T(n)=O(n2) 先进的排序:T(n)=O(logn) 基数排序:T(n)=O(d.n)
主要是关键字的比较次数和记录的移动次数。
有的排序算法其执行时间不仅依赖于问题的规模,还取 决于输入实例中数据的状态。
排序算法的空间开销
若所需辅助空间不依赖于问题的规模n,即辅助空间为 O(1),则称为就地排序。
相关文档
最新文档