第10章-内排序第3讲-交换排序(冒泡-快速)
合集下载
数据结构-内排序
Shell排序的性能分析
Shell排序的时间复杂度在O(nlog2n)和O(n2)间, Knuth的 统计结论是,平均比较次数和记录平均移动次数在n1.25与 1.6n1.25之间
Shell排序是一种不稳定的排序方法
最后谈一下delta的取法。 Shell最初的方案是delta=n/2, delta=delta/2,直到delta=1。Knuth的方案是delta=delta/3 +1。其它方案有:都取奇数为好;或delta互质为好等等。 而使用象1, 2, 4, 8, …或1, 3, 6, 9, …这样的增量序列就不太 合适,因为这样会使几个元素多次被分到一组中,从而造 成重复排序,产生大量无用的比较操作
另外,在无序子表中向前移动的过程中,如果没 有交换元素,则说明无序子表已有序,无须再做 排序
24
冒泡排序算法实现
1 void bubble_sort(RecType R[ ], int n) { 2 //待排序元素用一个数组R表示,数组有n个记录
3 int i, j; 4 bool swap=TRUE; //判断无序子表是否已有序的变量
内排序和外排序 按照排序过程中使用内、外存的不 同将排序方法分为内排序和外排序。若待排序记录全 部在内存中,称为内排序;若待排序记录的数量很大, 以致内存一次不能容纳全部记录,在排序过程中需要 进行内、外存交换,称为外排序。本章仅讨论内排序
内排序可分为五大类:插入排序、交换排序、选择排 序、归并排序和基数排序
直接插入排序(straight insert sort) 折半插入排序(binary insert sort) Shell排序(Shell sort)
10
10.2.1 直接插入排序举例
数据结构-第十章-内部排序
0
1
2
3
4
5
6
7
8
i=5
MAXINT 49 2 3
MAXINT 49 6 3 MAXINT 49 6 3 MAXINT 49 6 8
38 1
38 1 38 1 38 1
65 97 5 0
65 5 65 5 65 5 97 0 97 0 97 0
76 4
76 4 76 4 76 4
13
27
49
i=6
最坏情况下,待排记录按关键字非递增有序 排列(逆序)时,第 i 趟时第 i+1 个对象 必须与前面 i 个对象都做排序码比较, 并且 每做1次比较就要做1次数据移动。总比较 次 数 为 (n+2)(n-1)/2 次 , 总 移 动 次 数 为 (n+4)(n-1)/2。 在平均情况下的排序码比较次数和对象移 动次数约为 n2/4。因此,直接插入排序的 时间复杂度为 O(n2)。 直接插入排序是一种稳定的排序方法。
折半插入排序 (Binary Insertsort)
基本思想 既然每个要插入记录之前的纪录 已经按关键字有序排列,在查找插入位 臵时就没有必要逐个关键字比较,可以 使用折半查找来实现。由此进行的插入 排序称之为折半插入排序。
折半插入排序的算法
void BInsertSort (SqList &L){ for (i=2;i<=L.length;++i){ L.r[0]=L.r[i]; low=1;high=i-1; //查找范围由1到i-1 while(low<=high){ m=(low+high)/2; if LT(L.r[0].key,L.r[m].key) high=m-1; else low=m+1; }//while 折半查找 for (j=i-1;j>=high+1;--j) L.r[j+1]=L.r[j]; //折半查找结束后high+1位臵即为插入位臵 L.r[high+1]=L.r[0]; }//for }//BInsertSort
第十章_排序方法(数据结构ppt-严蔚敏)
第二个问题解决方法——筛选
方法:输出堆顶元素之后,以堆中最后一个元素替代之;然 后将根结点值与左、右子树的根结点值进行比较,并与其中 小者进行交换;重复上述操作,直至叶子结点,将得到新的 堆,称这个从堆顶至叶子的调整过程为“筛选”
例 38 50 97 76
13 27 65 49 13 38
97 27 38 50 76
2 (n 4)(n 1) 记录移动次数: (i 1) 2 i 2
i 2 n
若待排序记录是随机的,取平均值 n2 关键字比较次数: T(n)=O(n² ) 4 记录移动次数:
空间复杂度:S(n)=O(1)
n2 4
折半插入排序
排序过程:用折半查找方法确定插入位置的排序叫~
初始时令i=s,j=t 首先从j所指位置向前搜索第一个关键字小于x的记录,并和rp 交换 再从i所指位置起向后搜索,找到第一个关键字大于x的记录, 和rp交换 重复上述两步,直至i==j为止 再分别对两个子序列进行快速排序,直到每个子序列只含有 一个记录为止
x 例 初始关键字: 27 49 i 完成一趟排序: ( 27 38 13 49 65 i 13) 49 97 76 j 97 49 13 j 97 65 49 27 50 j 50)
13 38
76 65 27 49
堆排序:将无序序列建成一个堆,得到关键字最小 (或最大)的记录;输出堆顶的最小(大)值后,使 剩余的n-1个元素重又建成一个堆,则可得到n个元素 的次小值;重复执行,得到一个有序序列,这个过程 叫~ 堆排序需解决的两个问题:
如何由一个无序序列建成一个堆? 如何在输出堆顶元素之后,调整剩余元素,使之成为一个新 的堆?
按排序所需工作量
《数据结构》陈慧南 第10章
n−1
n( n − 1 ) ∑i = 2 i =1
南京邮电大学计算机学院 陈慧南 2006年9月 2006年
9.2.3 冒泡排序
(48,36,68,72,12,48,02) 48,36,68,72,12,48,02) 36,48,68,72,12,48,02) (36,48,68,72,12,48,02) 36,48,68,72,12,48,02) (36,48,68,72,12,48,02) 36,48,68,72,12,48,02) (36,48,68,72,12,48,02) 36,48,68,12,72,48,02) (36,48,68,12,72,48,02) (36,48,68,12,48,72,02) 36,48,68,12,48,72,02) 36,48,68,12,48,02,72) (36,48,68,12,48,02,72)
南京邮电大学计算机学院 陈慧南 2006年9月 2006年
序列中两个元素R 序列中两个元素 i和Rj (i<j),且Ki=Kj,若 , 排序后仍保持p(i)<p(j),即Ri 仍然排在 j之 仍然排在R 排序后仍保持 , 则称所用的排序算法是稳定的。 反之, 前 , 则称所用的排序算法是稳定的 。 反之 , 称该排序算法是不稳定的。 称该排序算法是不稳定的。 如果待排序元素总数相对于内存而言较小, 如果待排序元素总数相对于内存而言较小 , 整个排序过程可以在内存中进行, 整个排序过程可以在内存中进行 , 则称之 为内部排序; 反之, 为内部排序 ; 反之 , 如果待排序元素总数 较多, 不能全部放入内存, 较多 , 不能全部放入内存 , 排序过程中需 访问外存, 则称之为外部排序。 访问外存 , 则称之为外部排序 。 本章讨论 内部排序。 内部排序。
n( n − 1 ) ∑i = 2 i =1
南京邮电大学计算机学院 陈慧南 2006年9月 2006年
9.2.3 冒泡排序
(48,36,68,72,12,48,02) 48,36,68,72,12,48,02) 36,48,68,72,12,48,02) (36,48,68,72,12,48,02) 36,48,68,72,12,48,02) (36,48,68,72,12,48,02) 36,48,68,72,12,48,02) (36,48,68,72,12,48,02) 36,48,68,12,72,48,02) (36,48,68,12,72,48,02) (36,48,68,12,48,72,02) 36,48,68,12,48,72,02) 36,48,68,12,48,02,72) (36,48,68,12,48,02,72)
南京邮电大学计算机学院 陈慧南 2006年9月 2006年
序列中两个元素R 序列中两个元素 i和Rj (i<j),且Ki=Kj,若 , 排序后仍保持p(i)<p(j),即Ri 仍然排在 j之 仍然排在R 排序后仍保持 , 则称所用的排序算法是稳定的。 反之, 前 , 则称所用的排序算法是稳定的 。 反之 , 称该排序算法是不稳定的。 称该排序算法是不稳定的。 如果待排序元素总数相对于内存而言较小, 如果待排序元素总数相对于内存而言较小 , 整个排序过程可以在内存中进行, 整个排序过程可以在内存中进行 , 则称之 为内部排序; 反之, 为内部排序 ; 反之 , 如果待排序元素总数 较多, 不能全部放入内存, 较多 , 不能全部放入内存 , 排序过程中需 访问外存, 则称之为外部排序。 访问外存 , 则称之为外部排序 。 本章讨论 内部排序。 内部排序。
第10章-内部排序PPT课件
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-路归并排序 基数排序
-
算法效率
时间复杂度
待排序记录按关键字从小到大排列(正序)
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-路归并排序 基数排序
第十章排序
第一趟:第1个与第2个比较,大则交换;第2个与第3个比较, 大则交换,……关键字最大的记录交换到最后一个位置上; 第二趟:对前n-1个记录进行同样的操作,关键字次大的记录交换 到第n-1个位置上;
依次类推,则完成排序。
正序:时间复杂度为O(n) 逆序:时间复杂度为O(n2)
适合于数据较少的情况。
2013-5-13 排序n个记录的文件最多需要n-1趟冒泡排序。 举例:图8-2-5
25
思想:小的 浮起,大的 沉底。
25 56 49 78 11 65 41 36
初 始 关 键 字
25 49 56 11 65 41 36 78
第 一 趟 排 序 后
25 49 11 56 41 36 65
25 11 49 41 36 56
11 25 41 36 49
11 25 36 41
11 25 36
简单选择排序、堆排序。
1、简单选择排序
思想:首先从1~n个元素中选 出关键字最小的记录交换到第 一个位置上。然后再从第2 个 到第n个元素中选出次小的记 录交换到第二个位置上,依次 类推。
时间复杂度为O(n2), 适用于待排序元素较少的情况。
3 j 3 k 3 k 3
互换
9 9 j 9 9
1 1 1 j 1 k 8
插入算法如下:
9
方法:Ki与Ki-1,K i-2,…K1依次比较,直到找到应插入的位置。 void insertSort(RedType L[ ],int n)
{ int i ,j; for(i=2; i<=n; i++) if(L[i].key<L[i-1].key)
{
L[0]=L[i];
L[j+1]=L[j]; L[j+1]=L[0];
依次类推,则完成排序。
正序:时间复杂度为O(n) 逆序:时间复杂度为O(n2)
适合于数据较少的情况。
2013-5-13 排序n个记录的文件最多需要n-1趟冒泡排序。 举例:图8-2-5
25
思想:小的 浮起,大的 沉底。
25 56 49 78 11 65 41 36
初 始 关 键 字
25 49 56 11 65 41 36 78
第 一 趟 排 序 后
25 49 11 56 41 36 65
25 11 49 41 36 56
11 25 41 36 49
11 25 36 41
11 25 36
简单选择排序、堆排序。
1、简单选择排序
思想:首先从1~n个元素中选 出关键字最小的记录交换到第 一个位置上。然后再从第2 个 到第n个元素中选出次小的记 录交换到第二个位置上,依次 类推。
时间复杂度为O(n2), 适用于待排序元素较少的情况。
3 j 3 k 3 k 3
互换
9 9 j 9 9
1 1 1 j 1 k 8
插入算法如下:
9
方法:Ki与Ki-1,K i-2,…K1依次比较,直到找到应插入的位置。 void insertSort(RedType L[ ],int n)
{ int i ,j; for(i=2; i<=n; i++) if(L[i].key<L[i-1].key)
{
L[0]=L[i];
L[j+1]=L[j]; L[j+1]=L[0];
第十章排序(可编辑修改word版)
主要辅助手段:多媒体
作业布置
10-4(2),(4),(5),10-6,
主 要 参考资料
1.《数据结构》,严蔚敏 吴伟民,清华大学出版社;2.数据结构题集(C语言版),
严蔚敏 吴伟民,清华大学出版社;
备注
重点难点
希尔的思想,实现,算法分析
要求掌握知识点和
分析方法
1.概念:排序,主(次)关键字,内部(外部)排序,比较排序算法的技术指标2。插入排序的基本思想;3。直接直接插入排序和希尔的思想,实现,算法分析。
教授思路,采 用 的 教学方法和辅助手段,板书设计,重 点 如 何突出,难点如何解决,师 生 互 动等
难点:堆的调整辅助手段:多媒体
作业布置
10-7,10-8
主 要 参考资料
1.《数据结构》,严蔚敏 吴伟民,清华大学出版社;2.数据结构题集(C语言版),
严蔚敏 吴伟民,清华大学出版社;
备注
章节
10.5归并排序10.6基数排序
讲授主要内容
归并排序 ,基数排序
重点难点
归并排序 ,基数排序的基本思想与算法实现
本章思考题和习题
主 要 参考资料
1.《数据结构》,严蔚敏 吴伟民,清华大学出版社;2.数据结构题集(C语言版),
严蔚敏 吴伟民,清华大学出版社;
备注
章节
10.1概念10.2插入排序
讲授主要内容
1.概念:排序,主(次)关键字,内部(外部)排序,比较排序算法的技术指标2.
插入排序的基本思想;3。直接直接插入排序和希尔的思想,实现,算法分析。
教授思路,采 用 的 教学方法和辅助手段, 板书设计,重 点 如 何突出,难点如何解决,师 生 互 动等
教学思路:
作业布置
10-4(2),(4),(5),10-6,
主 要 参考资料
1.《数据结构》,严蔚敏 吴伟民,清华大学出版社;2.数据结构题集(C语言版),
严蔚敏 吴伟民,清华大学出版社;
备注
重点难点
希尔的思想,实现,算法分析
要求掌握知识点和
分析方法
1.概念:排序,主(次)关键字,内部(外部)排序,比较排序算法的技术指标2。插入排序的基本思想;3。直接直接插入排序和希尔的思想,实现,算法分析。
教授思路,采 用 的 教学方法和辅助手段,板书设计,重 点 如 何突出,难点如何解决,师 生 互 动等
难点:堆的调整辅助手段:多媒体
作业布置
10-7,10-8
主 要 参考资料
1.《数据结构》,严蔚敏 吴伟民,清华大学出版社;2.数据结构题集(C语言版),
严蔚敏 吴伟民,清华大学出版社;
备注
章节
10.5归并排序10.6基数排序
讲授主要内容
归并排序 ,基数排序
重点难点
归并排序 ,基数排序的基本思想与算法实现
本章思考题和习题
主 要 参考资料
1.《数据结构》,严蔚敏 吴伟民,清华大学出版社;2.数据结构题集(C语言版),
严蔚敏 吴伟民,清华大学出版社;
备注
章节
10.1概念10.2插入排序
讲授主要内容
1.概念:排序,主(次)关键字,内部(外部)排序,比较排序算法的技术指标2.
插入排序的基本思想;3。直接直接插入排序和希尔的思想,实现,算法分析。
教授思路,采 用 的 教学方法和辅助手段, 板书设计,重 点 如 何突出,难点如何解决,师 生 互 动等
教学思路:
第十章 内部排序
(38) (65) (97) (76) (13) (27) (49)
直接插入排序算法
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[0]=L.r[i]; //复制为哨兵 for (j=i-1; LT(L.r[0].key, L.r[j].key); --j) L.r[j+1]=L.r[j]; //记录后移 L.r[j+1]=L.r[0]; //插入到正确位置 } }//InsertSort
改写上述算法:将枢轴暂存在r[0]的位置上,直至一趟排 序结束后再将枢轴记录移至正确位置上, 算法10.6(b): Int Partition(SqList &L, int low, int high) { L.r[0]=L.r[low]; Pivotkey=L.r[low].key; while (low<high) { while(low<high && L.r[high].key>=pivotkey) --high;
10。3交换排序
起泡排序思想: 依次对未排序部分相邻的两个元素进行比较,若逆序则 交换位置,每一趟可以使一个最大(最小)元素从这个序列 中冒出来,经过n-1趟,就可以排好序 例:
起泡排序示例
初始关键字 第一趟排序后 第二趟排序后 第三趟排序后 第四趟排序后 第五趟排序后 12 12 12 12 12 4 23 23 18 14 4 18 18 14 4 14 14 14 4 18 4 4 23 90 90
快速排序
交 换 排 序
(2) (3)
49 25*
25 49
21
25
leSort(SeqList R) {int i,j,exchange;
for(i=1;i<n;i++)
{ exchange=0; for(j=n-1;j>=i;j--)
if(R[j+1].key<R[j].key)
▪ 在整个排序过程中,最多执行(n-1)遍。但执行的 遍数可能少于(n-1),这是因为在执行某一遍的各 次比较没有出现结点交换时,就不用进行下一遍的 比较。
冒泡排序示例
i (4)
16 1
25* 2
49 3
25*
(0) (1) (5)
21 25 08
08 21 16
08 16 25*
08 16 49
划分算法
int Partition(SeqList R,int i,int j) {ReceType pivot=R[i];
while(i<j)
{while(i<j&&R[j].key>=pivot.key) j--;
if(i<j) R[i++]=R[j];
while(i<j&&R[i].key<=pivot.key) i++;
if(i<j)
R[j--]=R[i];
} //endwhile R[i]=pivot; return i;
}
快速排序的算法分析
考虑关键字的比较次数和对象移动次数
▪最坏情况是每次划分选取的基准都是当前无序区 中关键字最小(或最大)的记录,划分的结果是基 准的左边(或右边)为空,划分前后无序区的元素 个数减少一个,因此,排序必须做n-1趟,每一趟中 需做n-i次比较,所以最大比较次数为
数据结构使用C语言版朱战立丛书版本排序
{ span = d[m];
//取本次的增量值
for<k = 0; k < span; k++> //共span个小组
{
//组内是直接插入排序,区别是每次不是增1而是增
span
for<i = k; i < n-span; i = i+span>
{ temp = a[i+span];
j = i;
while<j > -1 && temp.key < a[j].key>
优点:实现简单
缺点:每趟只能确定一个元素,表长为n时需要n-1趟
算法如下:
void SelectSort<DataType a[], int n>
{
int i, j, small;
DataType temp;
for<i = 0; i < n-1; i++>
{ small = i;
//设第i个数据元素关键字
(a)初始最大堆 40
32
9
5
10
40 32 9 5 10 50 76 88 (d)交换顶点50后 9
5
76
50
40
5
10
9
32
76 50 40 5 10 9 32 88 (b)交换顶点88后 32
10
9
5
32 10 9 5 40 50 76 88 (e)交换顶点40后
5
9 5 10 32 40 50 76 88
{ a[j+span] = a[j];
j = j-span;
65
数据结构chapter_10
typedef struct { //定义每个记录 数据元素) 定义每个记录( //定义每个记录(数据元素)的结构 KeyType key ; //关键字 //关键字 InfoType otherinfo; //其它数据项 //其它数据项 }RedType; //记录类型 //记录类型 typedef struct { //定义顺序表 定义顺序表L //定义顺序表L的结构 RecordType r [ MAXSIZE +1 ]; //存储顺序表的向量 //存储顺序表的向量 //r[0] r[0]一般作哨兵或缓冲区 //r[0]一般作哨兵或缓冲区 int length ; //顺序表的长度 //顺序表的长度 }SqList; //顺序表类型 //顺序表类型
void BInsertSort (SqList &L) {
// 对顺序表 作折半插入排序 对顺序表L作折半插入排序 for ( i=2; i<=L.length; ++i ) { L.r[0] = L.r[i]; // 将L.r[i]暂存到 暂存到L.r[0] 暂存到 low = 1; high = i-1; while (low<=high) { // 在r[low..high]中折半查找有序插入的位置 中折半查找有序插入的位置 m = (low+high)/2; // 折半 if (L.r[0].key < L.r[m].key) high = m-1; // 插入点在低半区 else low = m+1; // 插入点在高半区 } // while for ( j=i-1; j>=low; --j ) L.r[j+1] = L.r[j]; // 记录后移 // 插入 L.r[high+1] = L.r[0]; } } // BInsertSort
数据结构第十、十一章:排序
14
9.2 交换排序
冒泡排序
排序过程
将第一个记录的关键字与第二个记录的关键字进行比较, 将第一个记录的关键字与第二个记录的关键字进行比较,若 为逆序r[1].key>r[2].key,则交换;然后比较第二个记录与 为逆序 ,则交换; 第三个记录;依次类推,直至第n-1个记录和第 个记录比较 个记录和第n个记录比较 第三个记录;依次类推,直至第 个记录和第 为止——第一趟冒泡排序,结果关键字最大的记录被安置在 第一趟冒泡排序, 为止 第一趟冒泡排序 最后一个记录上 对前n-1个记录进行第二趟冒泡排序,结果使关键字次大的 个记录进行第二趟冒泡排序, 对前 个记录进行第二趟冒泡排序 记录被安置在第n-1个记录位置 记录被安置在第 个记录位置 重复上述过程,直到“ 重复上述过程,直到“在一趟排序过程中没有进行过交换记 录的操作” 录的操作”为止
按待排序记录所在位置
内部排序: 内部排序:待排序记录存放在内存 外部排序: 外部排序:排序过程中需对外存进行访问的排序
稳定排序和不稳定排序 假设Ki=Kj(1≤i≤n,1≤j≤n,i≠j),且在排序前的序列中Ri领先 假设 ( , , ),且在排序前的序列中 领先 ),且在排序前的序列中 于Rj(即i<j)。若在排序后的排序中Ri仍领先于 ,即那些具 ( )。若在排序后的排序中 仍领先于Rj, )。若在排序后的排序中 仍领先于 有相同关键字的记录,经过排序后它们的相对次序仍然保持不变, 有相同关键字的记录,经过排序后它们的相对次序仍然保持不变, 则称这种排序方法是稳定的;反之,若Rj领先于 ,则称所用的 则称这种排序方法是稳定的;反之, 领先于Ri, 领先于 方法是不稳定的。 方法是不稳定的。 按排序依据原则
4
例
数结_9排序
对每个子表分别进行直接插入排序
由于n2>n12+n22+…+nk2
( n=n1+n2+…+nk )
所以对每个子表排序所耗费的时间之和要小于对整 个区间排序所耗费的时间
通过对子表小范围的排序,将排序区间调整成基本有 序的序列; 不断减少子表的个数(即扩大子表的长度), 直至子表 的个数为1, 完成整个排序操作.
R
0
15 58 46 45 90 08 32
1 2 3 4 5 6 7
第二趟后:
R
0
15 46 58 45 90 08 32
1 2 3 4 5 6 7
i=3
第二趟,i=3;
46<58,46赋给监视哨; 有序区中所有大于46的记录右移一位 将46放入腾出的空位
初态:
R
0
58 15 46 45 90 08 32
1 2 3 4 5 6 i=6 7
第五趟,i=6;
初态:
R
0
58 15 46 45 90 08 32
1 2 3 4 5 6 7
第一趟后: 第二趟后: 第三趟后: 第四趟后: 第五趟后: 第六趟后:
R
0
15 58 46 45 90 08 32
1 2 3 4 5 6 7
R
0
15 46 58 45 90 08 32
1 2 3 4 5 6 7
第一趟后:
R
0
15 58 46 45 90 08 32
1 2 i=2 3 4 5 6 7
第一趟,i=2;
15<58,15赋给监视哨;
有序区中所有大于15的记录右移一位 将15放入腾出的空位
排序算法精讲PPT课件
if (L.r[j].key > L.r[j+1].key ) {
for(j = i - 2; L.r[0].key < L.r[j].key]; j--)
L.r[0] = L.r[j]; L.r[j] = L.r[j+1];
L.r[j+1] = L.r[j];
L.r[j+1] = L.r[0]; exchanged =TRUE;
有序序列R[1..i-1]
第i趟 简单选择排序
无序序列 R[i..n] 从中选出关键字最小的记录
有序序列R[1..i]
无序序列 R[i+1..n]
简单选择排序算法
❖ 以顺序表作为存储结构的简单选择排序算法
void SelectSort(SqList &L) {//对顺序表作简单选择排序
ffoorr((ii==11;;ii<<LL..elnenggthth; ;i+i+++) ){{
数据结构定义
#define MAXSIZE 100
typedef int Keytype;
// 定义关键字类型为整型
typedef char InfoType[100];
typedef struct { KeyType key; InfoType otherinfo;
}RedType;
// 关键字项 // 其他数据项 // 记录类型
typedef struct { RedType r[MAXSIZE+1]; int length;
}SqList;
// r[0]闲置或用作哨兵 // 顺序表长度 // 顺序表类型
直接插入排序
直接插入排序(Straight Insertion Sorting)的基本思想 是:n个待排序的元素由一个有序表和一个无序表组成, 开始时有序表中只包含一个元素。排序过程中,每次从 无序表中取出第一个元素,将其插入到有序表中的适当 位置,使有序表的长度不断加长,完成排序过程。
for(j = i - 2; L.r[0].key < L.r[j].key]; j--)
L.r[0] = L.r[j]; L.r[j] = L.r[j+1];
L.r[j+1] = L.r[j];
L.r[j+1] = L.r[0]; exchanged =TRUE;
有序序列R[1..i-1]
第i趟 简单选择排序
无序序列 R[i..n] 从中选出关键字最小的记录
有序序列R[1..i]
无序序列 R[i+1..n]
简单选择排序算法
❖ 以顺序表作为存储结构的简单选择排序算法
void SelectSort(SqList &L) {//对顺序表作简单选择排序
ffoorr((ii==11;;ii<<LL..elnenggthth; ;i+i+++) ){{
数据结构定义
#define MAXSIZE 100
typedef int Keytype;
// 定义关键字类型为整型
typedef char InfoType[100];
typedef struct { KeyType key; InfoType otherinfo;
}RedType;
// 关键字项 // 其他数据项 // 记录类型
typedef struct { RedType r[MAXSIZE+1]; int length;
}SqList;
// r[0]闲置或用作哨兵 // 顺序表长度 // 顺序表类型
直接插入排序
直接插入排序(Straight Insertion Sorting)的基本思想 是:n个待排序的元素由一个有序表和一个无序表组成, 开始时有序表中只包含一个元素。排序过程中,每次从 无序表中取出第一个元素,将其插入到有序表中的适当 位置,使有序表的长度不断加长,完成排序过程。
DS10_排序01_概述和插入排序
排序
先迚排序方法,其时间复杂度为O(nlogn)
基数排序,其时间复杂度为O(d·n)
内排序的分类
按排序过程中依据的原则分
揑入类(直揑排序、二分排序、希尔排序) 交换类(冒泡排序、快速排序) 排序
选择类(直选排序、树型排序、堆排序)
归并类(二路归并排序、多路归并排序) 分配类(多关键字排序、基数排序)
3)折半插入排序性能分析
折半揑入排序减少了关键字的比较次数,但记彔的移动次数丌变,其 时间复杂度不直接揑入排序相同。
折半揑入排序是“稳定的”
3. 2-路插入排序
1)基本思想 2-路揑入排序是在折半揑入排序的基础上改迚的,目的是减少排序过 程中移动记彔的次数,但为此需要n个记彔的辅助空间。
2)具体做法
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; 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]; } }
另设一个和 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] 之后的有序表中。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
n个元素
划分时间为O(n)
n-1个元素
n层
n-2个元素
┇
此时时间复杂度为O(n2),空间复杂度为O(n)。
14/22
平均情况:
n个元素
划分时间为O(n)
k-1个元素
n-k个元素
k:1~n,共有n种情况
由此可得快速排序所需时间的平均值为:
Tavg (n)
Cn
1 n
n k 1
Tavg (k
1)
Tavg (n
整个区间:R[s..t]
3
1
5
4
2
tmp
左区间i:R[s..i-1]
右区间:R[i+1j..t]
i=j:区间处理完毕
划分完毕
8/22
【例10-4:p377】设待排序的表有10个记录,其关键字分别 为(6,8,7,9,0,1,3,2,4,5)。说明采用快速排序方法 进行排序的过程。
9/22
快速排序递归树
基本思路
两个记录反序时进行交换
常见的交换排序方法: (1)冒泡排序(或起泡排序) (2)快速排序
1/22
2/22
R[0]
有
序 区
┇
R[i-1]
R[i]
无 序
R[i+1]
区┇
R[n-1]
一趟排序
R[0]
有
┇
序 区
R[i-1] R[i]
将无序区中
最小记录放 在R[i]
R[i+1] ┇
无 序 区
R[n-1]
6879013245
542301 6 978
14230 5
87 9
0 1 234
78
树, 每个分支结点对应一次递 归调用。这里递归次数:
7 左右分区处理的顺序无关
0,1,2,3,4,5,6,7,8,9
10/22
【例(补充】采用递归方式对顺序表进行快速排序,下列关于 递归次数的叙述中,正确的是( )。
A. 顺序存储
B. 散列存储
C. 链式存储
D. 索引存储
说明:本题为2011年全国考研题
12/22
算法分析
最好情况:
n个元素
划分时间为O(n)
n/2或n/2 -1个元素
n/2或n/2 -1个元素
……
log2n层
此时时间复杂度为O(nlog2n),空间复杂度为O(log2n)。
13/22
最坏情况:
所以冒泡排序最好时间复杂度为O(n),最坏和平均为O(n2)。
5/22
6/22
基准
无序的记录序列
一次划分
无序子序列
基准 无序子序列
分别进行快速排序
每趟使表的第1个元素放入适当位置(归位),将表一分为 二,对子表按递归方式继续这种划分,直至划分的子表长为0或 1(递归出口)。
7/22
回顾划分:示例
A. 递归次数与初始数据的排列次序无关 B. 每次划分后,先处理较长的分区可以减少递归次数 C. 每次划分后,先处理较短的分区可以减少递归次数 D. 递归次数与每次划分后得到的分区处理顺序无关
说明:本题为2010年全国考研题
11/22
【例(补充)】 为实现快速排序法,待排序序列宜采用存储
方式是( )。
4/22
算法分析
最好的情况(关键字在记录序列中正序):只需进行一趟冒泡
“比较”的次数: n-1
“移动”的次数: 0
最坏的情况(关键字在记录序列中反序):需进行n-1趟冒泡
“比较”的次数:
n1
(n i 1) n(n 1) 2
i0
“移动”的次数:
n-2
3(n-i 1) 3n(n 1) 2
i0
k)
1次划分的时间
则可得结果: Tavg(n)=Cnlog2n。
结论: 快速排序的平均时间复杂度为O(nlog2n) 。
平均所需栈空间为O(log2n)。
15/22
16/22
━━本讲完━━
17/22
初始有序区为空。 i=0~n-2,共n-1趟使整个数据有序。
有序区总是全 局有序的
3/22
采用前面的冒泡排序方法对(2,1,3,4,5) 进行排 序
初始关键字 2 1 3 4 5
i=0
12345
已经全部有 序了
i=1
12345
i=2
12345
i=3
12345
如何提高效率?
一旦某一趟比较时不出现记录交换,说明已排好 序了,就可以结束本算法。