教 师:曾晓东 电 话:13679007201 E_mail: zengxiaodong@263.net 计算机软件技术基础 教 师:曾晓东 电 话:13679007201 E_mail: zengxiaodong@263.net.

Slides:



Advertisements
Similar presentations
摸清变化 调整现状 信息技术学考选考阅卷体会和启示 嵊州高级中学 马喜音.
Advertisements

7.4 用矩阵初等行变换 解线性方程组 主要内容: 一.矩阵的行初等变换 二.用行初等变换求逆矩阵 三.用矩阵法求线性方程组.
第 九 章 搜尋(Search) 課程名稱:資料結構 授課老師:_____________.
主讲:计算机工程学院 李兰 答疑地点:主教学楼B区213
情緒與壓力管理─背部舒緩 指導老師:彭易璟 第六組組員:會資三乙 499A0047 謝宛霖 會資三乙 499A0019 吳汶諭
神奇的宇宙 我们的太阳系 宇宙中天体有哪些类型? 刊号:CN77-87 编辑: 施雅苑 今日一叠4版 第1期 认识宇宙 16岁的哈勃
算法设计与分析 第二章 递归与分治策略 杨圣洪.
組員:4A140013張瓊云 4A1I0039石宜芬 4A1I0909許峻綱 指導老師:王立杰老師
数据结构(C语言版) Data Structure
第十章 内部排序 知识点3:快速排序.
第九章 排序 插入排序 交换排序 选择排序 归并排序 基数排序.
9.1 概述 9.2 插入排序 9.3 交换排序 9.4 选择排序 9.5 归并排序 9.6 基数排序 9.7 各种内部排序的比较
第8章 查找 在英汉字典中查找某个英文单词的中文解释;在新华字典中查找某个汉字的读音、含义;在对数表、平方根表中查找某个数的对数、平方根;邮递员送信件要按收件人的地址确定位置等等。可以说查找是为了得到某个信息而常常进行的工作。 计算机、计算机网络使信息查询更快捷、方便、准确。要从计算机、计算机网络中查找特定的信息,就需要在计算机中存储包含该特定信息的表。如要从计算机中查找英文单词的中文解释,就需要存储类似英汉字典这样的信息表,以及对该表进行的查找操作。本章将讨论的问题即是“信息的存储和查找”。
第八章 查找.
第十章 内部排序 10.1 概述 10.2 插入排序 直接插入排序 其他插入排序 希尔排序
現代文學導讀 ─ 盧新華 傷痕 組 員:林于翔 4A1L0084
对程序进行推理的逻辑 计算机科学导论第二讲
C语言基础——指针的高级应用 Week 05.
第8章 查找 数据结构(C++描述).
专题研讨课二: 数组在解决复杂问题中的作用
第2章 线性表 线性结构 是一个数据元素的有序集合。.
選擇排序法 通訊一甲 B 楊穎穆.
第8章 排序.
第十章 排序.
第九章 排序 概述 插入排序 交换排序 选择排序 归并排序 基数排序 外排序.
排序 Sorting.
第九章 排序 9.1排序的基本概念 9.2简单排序方法(复杂度 O(n2)) 9.3先进排序方法(复杂度 O(nLogn))
快速排序法 (Quick Sort).
第9章 排序.
1、基本概念 2、插入排序 3、交换排序 4、选择排序 5、归并排序 6、基数排序 7、外部排序
搜尋資料結構 Search Structures.
第12章 樹狀搜尋結構 (Search Trees)
第2章 线性表 线性表抽象数据类型 顺序表 主要知识点 单链表 循环单链表 循环双向链表 静态链表 设计举例.
第8章 排 序 8.1 排序技术概述 8.2 插入排序 8.3 选择排序 8.4 交换排序 8.5 归并排序 8.6 基数排序
第九章 查找 2018/12/9.
本章重点难点 重点:顺序查找、二分查找、二叉排序树查找以及散列表查找的基本思想和算法实现。
第 3 讲 线性表(一).
数 据 结 构 Ch.4 串 计 算 机 学 院 肖明军
陈海明 副教授 信息学院 计算机系 电子信息类非计算机专业选修课 程序设计实践 陈海明 副教授 信息学院 计算机系
中央广播电视大学开放教育试点课程 数据结构 辅导教师 倪政林.
第9章 内部排序 9.1 概述 9.2 插入排序 9.3 快速排序 9.4 选择排序 9.5 归并排序 9.6 基数排序
数据结构 第9章 查找 什么是查找?? 静态查找 动态查找 哈希表 数据结构.
数据结构 Data Structure CSU 主讲人:王国军,郑瑾 中南大学信息院计科系
第九章 查找 2019/2/16.
数据结构 第八章 查找.
数据结构 第一章 绪论.
第 4 章 递 归 教学要求 本章重点 了解递归算法的概念与递归设计要领 掌握应用递归算法求解排序与选择、实现排列组合等典型案例
计算机算法设计与分析(第3版) 王晓东 编著 电子工业出版社.
等差数列的前n项和.
陈海明 副教授 信息学院 计算机系 电子信息类非计算机专业选修课 程序设计实践 陈海明 副教授 信息学院 计算机系
第三节 堆及其应用.
3.1 线性表及逻辑结构 3.2 线性表的顺序存储 3.3 线性表的链式存储 3.4 链式存储结构的应用
ACM 程序设计(一) 主讲:朱佳 博士 华南师范大学计算机学院.
经典算法之 冒 泡 排 序.
第1章 绪论 2019/4/16.
第九章 排序 概述 插入排序 快速排序 交换排序(起泡排序) 选择排序 归并排序.
第1章 绪论(二) 教学目标 理解算法的特性及评价标准 掌握算法时间复杂度和空间复杂度的分析方法 1/
99高中資訊科選修課程 夥伴學習教師 專業進修研習 進階程式設計--演算法 教學示例與研討
代码优化.
第十章 优化 网上教学系统: : 编译原理 第十章 优化 网上教学系统: : 编译原理.
算法导论第一次习题课.
演算法的效率分析.
累堆排序法 (Heap Sort).
第六章 贪心算法.
第8章 排序 8.1排序基本概念 8.2插入类排序 8.3交换类排序 8.4选择类排序 8.5归并排序 8.6基数排序
第三章 线性表 3.1 线性表的类型定义 3.2 顺序存储的线性表 3.3 链式存储的线性表 3.4 有序表 3.5 顺序表和链表的综合比较.
數學遊戲二 大象轉彎.
算法的基本思想: 第6章 内部排序 6.2 气泡排序 将待排序的记录看作是竖着排列的“气泡”,关键字较小 的记录比较轻,从而要往上浮。
排序 排序(sorting)是计算机程序设计中的一种重要操作,它的功能是将一个数据元素(或记录)的任意序列,重新排列成一个按关键字有序的序列。 由于待排序的记录数量不同,使得排序过程中涉及的存储器不同,可将排序方法分为两大类:一类是内部排序,指的是待排序记录存放在计算机存储器中进行的排序过程;另一类是外部排序,指的是待排序记录的数量很大,以致内存一次不能容纳全部记录,在排序过程中对外存进行访问的排序过程。
数列求和 Taojizhi 2019/10/13.
Presentation transcript:

教 师:曾晓东 电 话:13679007201 E_mail: zengxiaodong@263.net 计算机软件技术基础 教 师:曾晓东 电 话:13679007201 E_mail: zengxiaodong@263.net

6.2 排序 一、基本概念 二、选择排序 三、插入排序 四、交换排序 五、归并排序 六、各种排序算法的比较 计算机软件技术基础 查找与排序

Kp1≤Kp2≤•••≤Kpn(或Kp1≥Kp2≥ •••≥Kpn) 一、基本概念 1. 排序 设有含n个记录的序列为{ R1,R2,…,Rn },其相应的关键字序列为{ K1,K2,...,Kn }。现要求确定一种排序p1,p2,...pn, 使其关键字满足递增(或递减)的关系: Kp1≤Kp2≤•••≤Kpn(或Kp1≥Kp2≥ •••≥Kpn) 使原序列成为一个按关键字有序的序列: { Rp1,Rp2,…Rpn } 计算机软件技术基础 查找与排序

一、基本概念 2.排序方法的稳定性 若Ki=Kj(1≤i≤n ,1≤j≤n ,i≠j),在排序前Ri领先于Rj ,排序后Ri仍领先于Rj ,则称此排序方法是稳定的;反之称为不稳定的。 3. 排序的分类 若排序时待排序记录存放在内存中进行排序,则称为内部排序; 若待排序记录数量很大,在内存中一次不能容纳全部记录,需要在排序过程中对外存进行访问,则称为外部排序。 4.基本操作 1)对记录中关键字大小进行比较; 2)将记录从一个位置移到另一个位置。 计算机软件技术基础 查找与排序

一、基本概念 5. 排序的时间开销: 6. 算法执行时所需的附加存储 排序的时间开销是衡量算法好坏的最重要的标志。排序的时间开销可用算法执行中的数据比较次数与数据移动次数来衡量。 算法运行时间代价的大略估算一般都按平均情况进行估算。对于那些受对象排序码序列初始排列及对象个数影响较大的,需要按最好情况和最坏情况进行估算。 6. 算法执行时所需的附加存储 评价算法好坏的另一标准。 计算机软件技术基础 查找与排序

一、基本概念 7. 待排序的数据表 使用顺序存储结构存储 其数据类型定义如下: 记录结点的类型定义: typedef struct{ keywordtype key; datatype data; }RECORDNODE; 待排序的数据表是RECORDNODE类型的数组 struct RECORDNODE a[MaxSize]; 计算机软件技术基础 查找与排序

二、选择排序 选择排序是不断在待排序序列(无序区)中按记录关键字递增(或递减)次序选择记录,放入有序区中,逐渐扩大有序区,直到整个记录区为有序区为止。 其基本思想是: 每一趟 (例如第 i 趟, i = 1, 2, …, n-1) 在后面 n-i 个待排序对象中选出排序码最小的对象, 作为有序对象序列的第 i 个对象。待到第 n-1 趟作完, 待排序对象只剩下1个, 就不用再选了。 计算机软件技术基础 查找与排序

二、选择排序 直接选择排序 过程: 在当前无序序列中选择一个关键字最小的记录,并将它和最前端的记录交换。重复上述过程,使记录区的前端逐渐形成一个由小到大的有序区。 2) 基本步骤 (1)在一组对象 a[i]~a[n] 中选择具有最小关键字的对象; (2)若它不是这组对象中的第一个对象, 则将它与这组对象中的第一个对象对调; (3)在这组对象中剔除这个具有最小关键字的对象。在剩下的对象a[i+1]~a[n]中重复执行第(1)、(2)步, 直到剩余对象只有一个为止。 计算机软件技术基础 查找与排序

i = 0 i = 1 i = 2 初始 最小者 08 交换21,08 最小者 16 交换25,16 最小者 21 交换49,21 21 25* 16 08 1 2 3 4 5 6 初始 49 i = 0 21 25* 25 16 08 49 最小者 08 交换21,08 25 16 08 25* 49 21 i = 1 最小者 16 交换25,16 49 i = 2 08 16 25* 25 21 最小者 21 交换49,21 计算机软件技术基础 查找与排序

i = 3 i = 4 最小者 25* 无交换 最小者 25 无交换 结果 各趟排序后的结果 49 25* 1 2 3 4 5 6 08 1 2 3 4 5 6 i = 3 08 16 25 21 最小者 25* 无交换 25* i = 4 49 25 21 16 08 最小者 25 无交换 25 16 08 25* 49 21 结果 各趟排序后的结果 计算机软件技术基础 查找与排序

1. 直接选择排序 3)算法 void SelectSort(RECORDNODE a[],int n){ /*对记录数组a[1:n]进行直接选择排序*/ int i,j,small;RECORDNODE swap; for (i=1;i<n;i++){ small=i; /*记下位置*/ for(j=i+1;j<=n;j++) /*和余下的比较*/ if (a[small].key>a[j].key) small=j; if (small!=i){ /*交换*/ swap=a[small]; a[small]=a[i]; a[i]=swap; } } } 计算机软件技术基础 查找与排序

1. 直接选择排序 4)算法分析 算法由两层循环构成,外层循环表示共需进行n-1趟排序,内层循环需进行n-I次比较,也许会做一次交换,即记录移动次数最多为3。 总的时间性能为 ① 比较次数:n(n-1)/2 ② 移动次数:最坏情况下为3(n-1) 所以总的时间复杂度为:O(n2) 空间复杂度为:O(1) 交换记录时用 直接选择排序是一种不稳定的排序算法 计算机软件技术基础 查找与排序

二、选择排序 96 83 9 11 38 27 2. 堆排序 1) 堆 则称该序列构成的完全二叉树是一个堆。 设有序列{ k1,k2,…,kn },若满足: 则称该序列构成的完全二叉树是一个堆。 例如,有序列:{ 96,83,27,38,11,9 } 构成的完全二叉树如上图所示,它是一个堆。 易知堆顶元素为所有元素中的最小值或最大值 计算机软件技术基础 查找与排序

2. 堆排序 2)堆排序的过程由两部分组成: ① 将现有的序列构成一个堆 ② 输出堆顶元素,重新调整元素,构成新的堆,直到堆空为止。 3)堆的构造: ① 由所给序列生成对应的完全二叉树; ② 设完全二叉树a[1..n]中结点a[k]的左右子树均为堆,为构成以a[k]为根结点的堆,需进行调整。方法是将a[k]的值与其左右子树的根结点进行比较,若不满足堆的条件,则将a[k]与其左右子树中根结点大的交换,继续进行比较,直到所有子树均满足堆的定义为止。 计算机软件技术基础 查找与排序

建立初始的最大堆 21 25 25* 49 16 08 1 2 3 4 5 6 i 21 25 49 25* 16 08 初始排序码集合 21 25 49 25* 16 08 4 21 25 25* 16 49 08 1 3 6 5 2 i i = 2 时的局部调整 计算机软件技术基础 查找与排序

4 21 25 25* 49 16 08 1 2 3 5 6 i 21 25 49 25* 16 08 i = 1 时的局部调整 4 49 25 25* 16 21 08 1 3 6 5 2 49 25 21 25* 16 08 i = 0 时的局部调整 形成最大堆 计算机软件技术基础 查找与排序

2. 堆排序 最大堆的向下调整算法 Void createHeap(RECORDNODE a[],int p,int n){ /*将a[p:n]建立为以a[p]为根的最大堆*/ int i,j,k; i=p; j=2*i;a[0]=a[i];/*a[i]暂存到a[0]中*/ while(j<=n){ if(j<n&&a[j].key<a[j+1].key) j++;/*选两子女的较大者*/ if(a[0].key<a[j].key){ /*a[j]移向堆顶*/ a[i]=a[j];i=j;j=2*i;} else break; } a[i]=a[0]; } 计算机软件技术基础 查找与排序

2. 堆排序 ③ 对于一个无序序列a[1..n]构成的完全二叉树,只要从它最后一个非终端结点:(n/2)开始直到根结点为止,逐步进行上述调整,即可将该完全二叉树调整为堆。 算法为: int p=n/2,i; for (i=p;i>=1;i--) Sieve(a,i,n); 计算机软件技术基础 查找与排序

2. 堆排序 4)堆排序 由以下两个步骤进行: ① 由给定的无序序列构造最大堆; ② 最大堆堆顶a[1]具有最大的关键字,将a[1]与a[n]对调,把具有最大关键字的对象交换到最后,再对前面的n-1个对象,使用堆的调整算法Sieve(a,1,n-1),重新建立最大堆,具有次最大关键字的对象又上浮到a[1]位置。 再对调a[1]和a[n-1],调用Sieve(a,1,n-2),对前n-2个对象重新调整,…。 如此反复执行,最后得到全部排序好的对象序列。这个算法即堆排序算法。 计算机软件技术基础 查找与排序

49 25 25* 21 16 08 1 2 3 4 5 6 49 25 21 25* 16 08 初始最大堆 08 25 25* 16 21 49 1 3 6 5 4 2 08 25 21 25* 16 49 交换 0 号与 5 号对象, 5 号对象就位 计算机软件技术基础 查找与排序

25 25* 08 21 16 49 1 2 3 4 5 6 25 25* 21 08 16 49 从 0 号到 4 号 重新 调整为最大堆 4 08 16 25* 25 21 49 1 3 6 5 2 16 25* 21 08 25 49 交换 0 号与 4 号对象, 4 号对象就位 计算机软件技术基础 查找与排序

25* 16 08 21 25 49 1 2 3 4 5 6 25* 16 21 08 25 49 从 0 号到 3 号 重新 调整为最大堆 4 08 16 25* 25 21 49 1 3 6 5 2 08 16 21 25* 25 49 交换 0 号与 3 号对象, 3 号对象就位 计算机软件技术基础 查找与排序

21 16 08 25* 25 49 21 16 25* 08 25 49 1 2 3 4 5 6 从 0 号到 2 号 重新 调整为最大堆 08 16 21 25* 25 49 25* 08 16 25 21 49 1 3 6 5 4 2 交换 0 号与 2 号对象, 2 号对象就位 计算机软件技术基础 查找与排序

3 25* 16 08 21 25 49 1 2 4 5 6 16 08 21 25* 25 49 从 0 号到 1 号 重新 调整为最大堆 08 16 25* 25 21 49 1 3 6 5 4 2 08 16 21 25* 25 49 交换 0 号与 1 号对象, 1 号对象就位 计算机软件技术基础 查找与排序

2. 堆排序 堆排序的算法 Void HeapSort(RECORDNODE a[],int n){ /*使用堆排序算法对记录数组a[1:n]按关键字递增排序*/ int i; for(i=n/2;i>=1;i--) Sieve(a,i,n); /*建立初始最大堆*/ for(i=n;i>=2;i--){ a[0]=a[1]; a[1]=a[i];a[i]=a[0]; /*交换a[1]和a[I]*/ createHeap (a,1,i-1); /*重建最大堆*/ } 计算机软件技术基础 查找与排序

19 01 23 68 35 84 27 14 84 68 23 27 35 19 01 14 14 68 23 27 35 19 01 68 35 23 27 14 19 01 01 35 23 27 14 19 35 27 23 01 14 19 19 27 23 01 14 27 19 23 01 14 19 23 01 14 23 19 01 14 14 19 01 19 14 01 01 19 14 19 01 14 14 01 14 01 01 01 堆为空,结束。 计算机软件技术基础 查找与排序

2. 堆排序 5) 算法分析 若设堆中有 n 个结点, 且 2k-1  n  2k, 则对应的完全二叉树有 k 层。在第 i 层上的结点数  2i-1 (i = 1, 2, …, k)。 在第一个形成初始堆的 for 循环中对每一个非叶结点调用了一次堆调整算法Sieve( ),因此该循环所用的计算时间为: 其中, i 是层序号, 2i-1 是第 i 层的最大结点数, (k-i)是第 i 层结点能够移动的最大距离。 计算机软件技术基础 查找与排序

2. 堆排序 第二个for循环中调用了n-1次Sieve( )算法, 该循环的计算时间为O(nlog2n)。因此, 堆排序的时间复杂性为O(nlog2n)。 该算法的附加存储主要是在第二个for循环中用来执行对象交换时所用的一个临时对象。因此,该算法的空间复杂性为O(1)。 堆排序是一个不稳定的排序方法。 计算机软件技术基础 查找与排序

三、插入排序 插入排序是将当前无序区中最前端的记录插入到有序区中,逐渐扩大有序区,直到所有记录都插入到有序区中为止。 1. 直接插入排序 1)基本思想是 : 当插入第i (i  1) 个对象时, 前面的a[0], a[1] , … , a[i-1]已经排好序。这时, 用a[i]的排序码与a[i-1], a[i-2], …的关键码顺序进行比较, 找到插入位置即将a[i]插入, 原来位置上的对象向后顺移。 为了减少查找关键码时的比较次数,可在有序区的前端a[0]处设一个监视哨,存放当前要插入的关键字。 计算机软件技术基础 查找与排序

各趟排序结果 49 25 25* 21 16 08 1 2 3 4 5 6 49 25 25 25* 21 16 i = 2 08 0 1 2 3 4 5 6 49 49 25 25* 21 16 i = 3 08 0 1 2 3 4 5 6 计算机软件技术基础 查找与排序

49 25* 25 25* 21 16 i = 4 08 0 1 2 3 4 5 6 49 25 25* 21 16 16 i = 5 08 0 1 2 3 4 5 6 49 25 25* 21 16 i = 6 08 08 0 1 2 3 4 5 6 计算机软件技术基础 查找与排序

49 25 25* 21 16 完成 08 1 2 3 4 5 6 i = 4 时的排序过程 49 i = 5 j = 4 16 25 25* 21 16 16 08 0 1 2 3 4 5 6 49 49 i = 5 j = 3 16 25 25* 21 16 08 0 1 2 3 4 5 6 计算机软件技术基础 查找与排序

i = 5 j = 2 49 16 25 25* 25* 21 16 08 0 1 2 3 4 5 6 i = 5 j = 1 49 16 25 25 25* 21 16 08 0 1 2 3 4 5 6 i = 5 j = 0 49 16 25 25* 21 21 16 08 0 1 2 3 4 5 6 计算机软件技术基础 查找与排序

三、插入排序 2)函数实现 void straightinsert(RECORDNODE r[],int n){ /*使用直接插入排序法对数组a(1:n)排序*/ for (i=2;i<=n;i++){ a[0]=a[i]; /*设置监视哨*/ j=i-1; while (a[0].key<a[j].key){ a[j+1]=a[j]; j--; } a[j+1]=a[0]; } } 计算机软件技术基础 查找与排序

三、插入排序 3) 算法分析 设待排序对象个数为n, 则该算法的while循环执行n-1趟。 关键码比较次数和对象移动次数与对象关键码的初始排列有关。 最好情况下, 排序前对象已按关键码从小到大有序, 每趟只需与前面有序对象序列的最后一个对象比较1次, 移动2次对象, 总的关键码比较次数为 n-1, 对象移动次数为 2(n-1)。 最坏情况下, 第 i 趟时第 i 个对象必须与前面 i 个对象都做关键码比较, 并且每做1次比较就要做1次数据移动。则总关键码比较次数KCN和对象移动次数RMN分别为 计算机软件技术基础 查找与排序

三、插入排序 在平均情况下的排序码比较次数和对象移动次数约为 n2/4。因此,直接插入排序的时间复杂度为 o(n2)。 直接插入排序是一种稳定的排序方法。 计算机软件技术基础 查找与排序

三、插入排序 2. 折半插入排序 1)与直接插入排序相比,除了采用的是折半查找寻找插入的位置外,其它类似。 2)算法 void BinarySort(RECORDNODE a[],int n){ for (i=2;i<=n;i++){ a[0]=a[i]; low=1; high=i-1; while (low<high){ mid=(low+high)/2; if (a[0].key<r[mid].key) high=mid-1; else low=mid+1; } for (j=i-1;j>=low;j--) r[j+1]=r[j]; r[low]=r[0]; } 计算机软件技术基础 查找与排序

三、插入排序 3) 算法分析 折半查找比顺序查找查找快, 所以折半插入排序就平均性能来说比直接插入排序要快。 它所需的关键码比较次数与待排序对象序列的初始排列无关, 仅依赖于对象个数。在插入第 i 个对象时, 需要经过 log2i +1 次关键码比较, 才能确定它应插入的位置。因此, 将 n 个对象(为推导方便, 设为 n=2k )用折半插入排序所进行的排序码比较次数为: 其记录移动的数目与直接插入排序相同 因此,此算法的时间复杂度为O(n2) 折半插入排序是一个稳定的排序算法 计算机软件技术基础 查找与排序

三、插入排序 3. 希尔排序 1) 希尔排序方法又称为缩小增量排序。 2) 该方法的基本思想是 : 设待排序对象序列有 n 个对象, 首先取一个整数 gap < n 作为间隔, 将全部对象分为 gap 个子序列, 所有距离为 gap 的对象放在同一个子序列中,在每一个子序列中分别施行直接插入排序。然后缩小间隔 gap, 例如取 gap = gap/2,重复上述的子序列划分和排序工作。直到最后取 gap = 1, 将所有对象放在同一个序列中排序为止。 计算机软件技术基础 查找与排序

21 25 49 25* 16 08 1 2 3 4 5 6 21 25* i = 1 Gap = 3 49 25 16 08 25 16 49 25* 08 21 08 49 25 21 25* 16 计算机软件技术基础 查找与排序

21 25 49 25* 16 08 1 2 3 4 5 6 21 i = 2 08 Gap = 2 25 49 16 25* 16 08 21 25 49 25* 49 08 16 21 25* 25 计算机软件技术基础 查找与排序

21 25 49 25* 16 08 1 2 3 4 5 6 21 i = 3 08 Gap = 1 25 16 49 25* 开始时 gap 的值较大, 子序列中的对象较少, 排序速度较快; 随着排序进展, gap 值逐渐变小, 子序列中对象个数逐渐变多, 由于前面工作的基础, 大多数对象已基本有序, 所以排序速度仍然很快。 计算机软件技术基础 查找与排序

3.希尔排序 3)函数实现 Void shellsort(RECORDNODE s[],int n){ /*对记录数组s[1:n]进行希尔排序*/ /* d1=n/2,di=di-1/2 */ int i,j,d;d=n/2; /*d是间隔*/ while(d){ /*循环直到d为0*/ for(i=d+1;i<=n;i++){ /*对s[i],s[i-d],…直接插入排序*/ s[0]=s[i]; for(j=i;j>d;j=j-d) if(s[j].key>s[0].key) s[j]=s[j-d] else break; s[j]=s[0]; } d=d/2; } } 计算机软件技术基础 查找与排序

3.希尔排序 4) 算法分析 Gap的取法有多种。最初 shell 提出取 gap = n/2,gap = gap/2,直到gap = 1。knuth 提出取 gap = gap/3 +1。 对特定的待排序对象序列,可以准确地估算排序码的比较次数和对象移动次数。 想要弄清排序码比较次数和对象移动次数与增量选择之间的依赖关系,并给出完整的数学分析,还没有人能够做到。 Knuth利用大量实验统计资料得出 : 当 n 很大时,排序码平均比较次数和对象平均移动次数大约在 n1.25 到 1.6n1.25 的范围内。这是在利用直接插入排序作为子序列排序方法的情况下得到的。 希尔排序是一种不稳定的排序方法 计算机软件技术基础 查找与排序

四、交换排序 交换排序是根据序列中两个结点关键字的比较结果,来对换在序列中的位置。 算法的特点是将关键字较大的结点向序列的尾部移动,关键字较小的结点向序列的前部移动。 基本思想是两两比较待排序对象的排序码,如发生逆序(即排列顺序与排序后的次序正好相反),则交换之。直到所有对象都排好序为止。 计算机软件技术基础 查找与排序

四、交换排序 1. 冒泡排序 基本方法:设待排序对象序列中的对象个数为 n。最多作 n-1 趟, i = 1, 2, , n-1。在第 i 趟中从后向前,j = n, n-1, , i,顺次两两比较a[j-1]和a[j]。如果发生逆序,则交换a[j-1]和a[j]。 1)过程:对无序表进行扫描,当发现相邻两个记录关键字逆序时就进行交换,第一次扫描后就将最大关键字记录沉到底部,而关键字较小的记录则像气泡一样逐渐上浮。然后对剩下的记录再进行扫描,直到某次扫描时不发生交换,则排序完成。 计算机软件技术基础 查找与排序

21 25 25* 16 08 1 2 3 4 5 6 49 21 25* i = 1 25 16 Exchang=1 08 49 25 16 08 25* 49 21 Exchang=1 i = 2 49 i = 3 08 16 Exchang=1 25* 25 21 25* i = 4 49 16 Exchang=0 08 25 21 计算机软件技术基础 查找与排序

1. 冒泡排序 2)算法 void BubbleSort(RECORDNODE a[],int n){ /*使用冒泡排序算法,对记录数组a[1:n}排序*/ int i,j;int exchange = 1;/*标志,记录是否有交换*/ for(i=1;i<n && exchange;i++){ exchange = 0; /*标志置为0,假定未交换*/ for(j=n;j>i;j--) if(a[j-1].key>a[j].key){/*逆序*/ a[0]=a[j]; a[j]=a[j-1]; a[j-1]=a[0];/*交换*/ exchange = 1;/*标志置为1,有交换*/ } 计算机软件技术基础 查找与排序

1. 冒泡排序 算法也可写成: void BubbSort(RECORDNODE a[],int n) { int i; for (i=0;i<n-1;i++) for (j=i+1;j<n;j++) if (a[i].key>a[j].key){ t=a[i]; a[i]=a[j]; a[j]=t; } } 计算机软件技术基础 查找与排序

1. 冒泡排序 3) 算法分析 第i趟对待排序对象序列a[i],a[I+1],,a[n]进行排序, 结果将该序列中排序码最小的对象交换到序列的第一个位置(i), 其它对象也都向排序的最终位置移动。在个别情形, 对象可能在排序中途向相反的方向移动。 最多做n-1趟冒泡就能把所有对象排好序。 在对象的初始排列已经按关键字从小到大排好序时,此算法只执行一趟起泡,做n-1次关键字比较,不移动对象。这是最好的情形。 最坏的情形是算法执行n-1趟起泡,第i趟 (1 i n) 做 n- i 次关键字比较, 执行 n-i 次对象交换。这样在最坏情形下总的关键字比较次数KCN和对象移动次数RMN为: 计算机软件技术基础 查找与排序

1. 冒泡排序 冒泡排序的平均时间复杂度为O(n2) 起泡排序需要一个附加对象以实现对象值的对换。 起泡排序是一个稳定的排序方法。 计算机软件技术基础 查找与排序

四、交换排序 2. 快速排序 1)基本思想 快速排序是对冒泡排序的一种改进。 基本思想是任取待排序对象序列中的某个对象 (例如取第一个对象) 作为基准,按照该对象的关键字大小,将整个对象序列划分为左右两个子序列: 左侧子序列中所有对象的关键字都小于或等于基准对象的关键字 右侧子序列中所有对象的关键字都大于基准对象的关键字 基准对象则排在这两个子序列中间(这也是该对象最终应安放的位置)。 然后分别对这两个子序列重复施行上述方法,直到所有的对象都排在相应位置上为止。 计算机软件技术基础 查找与排序

2. 快速排序 2)分割过程 ① 选取表中一个元素a[k](一般选取第一元素),令x=a[k],称为控制关键字,用控制关键字和无序区中其余元素关键字进行比较。 ② 设置两个指示器i,j,分别表示线性表第一个和最后一个元素位置。 ③ 将j逐渐减小,逐次比较a[j]与x,直到出现一个a[j]<x,然后将a[j]移到a[i]位置,将i逐渐增大,逐次比较a[i]与x,直到出现一个a[i]>x,然后将a[i]移到a[j]位置。 如此反复进行,直到i=j为止,最后将x移到a[j]位置,完成一趟排序。此时以x为界将原数组分割成两个子区。 计算机软件技术基础 查找与排序

21 25 49 25* 16 08 1 2 3 4 5 6 x 21 25* i = 1 25 16 49 08 x 25* 16 08 25 49 21 i = 2 x 49 i = 3 08 16 25 25* 21 计算机软件技术基础 查找与排序

21 25 49 25* 16 08 1 2 3 4 5 6 i = 1 划分 x i 25* 25 16 49 08 x 21 比较4次 交换25,16 i 25 16 08 25* 49 x 21 比较1次 交换49,08 08 16 25* 25 21 49 low x 交换21,08 计算机软件技术基础 查找与排序

2. 快速排序 3)算法: void QuickSort(RECORDNODE a[],int low,int high){ /*对记录数组a[low:high]进行快速排序*/ if(low>=high) return; t=a[low]; i=low; j=high; while(i<j){ while(i<j&&a[j].key>=t.key) j--;/*从末端向中间搜索*/ if(i<j) a[i]=a[j]; while(i<j&&a[i]<=t.key) i++;/*从前端向中间搜索*/ if(i<j) a[j]=a[i]; } a[i]=t; if(low<i-1) QuickSort(a,low,i-1); if(i+1<high) QuickSort(a,i+1,high);} 计算机软件技术基础 查找与排序

4)举例:设序列为{46,55,13,42,94,5,17,70} ↑ j ↑ i 46 55 13 42 94 5 17 70 起始状态,46→x,46为控制关键字 ↑ j ↑ i 17 55 13 42 94 5 17 70 移动j,17→r[i] ↑ j ↑ i 17 55 13 42 94 5 55 70 移动i,55→r[j] ↑ j ↑ i 17 5 13 42 94 5 55 70 移动j,5→r[i] ↑ j ↑ i 17 5 13 42 94 94 55 70 移动i,94→r[j] ↑ j ↑ i 17 5 13 42 46 94 55 70 移动j,i=j,x→r[i],一趟排序结束 计算机软件技术基础 查找与排序

2. 快速排序 5) 算法分析 算法quicksort是一个递归的算法, 其递归树如图所示。 46 17 94 13 42 70 5 55 21 25* 25 49 08 16 计算机软件技术基础 查找与排序

2. 快速排序 T(n)  cn + 2T(n/2) /* c 是一个常数*/ 快速排序的趟数取决于递归树的高度。 如果每次划分对一个对象定位后, 该对象的左侧子序列与右侧子序列的长度相同, 则下一步将是对两个长度减半的子序列进行排序, 这是最理想的情况。 在 n个元素的序列中,对一个对象定位所需时间为 O(n)。若设t(n) 是对 n 个元素的序列进行排序所需的时间, 而且每次对一个对象正确定位后, 正好把序列划分为长度相等的两个子序列, 此时, 总的计算时间为: T(n)  cn + 2T(n/2) /* c 是一个常数*/  cn + 2( cn/2 + 2T(n/4) ) = 2cn + 4T(n/4)  2cn + 4( cn/4 +2T(n/8) ) = 3cn + 8T(n/8) ………  cn log2n + nT(1) = O(n log2n ) 计算机软件技术基础 查找与排序

2. 快速排序 可以证明, 函数quicksort的平均计算时间也是O(nlog2n)。实验结果表明: 就平均计算时间而言, 快速排序是所有内排序方法中最好的一个。 快速排序是递归的,需要有一个栈存放每层递归调用时的指针和参数。最大递归调用层次数与递归树的高度一致,理想情况为 log2(n+1) 。因此,要求存储开销为 O(log2n)。 在最坏的情况, 即待排序对象序列已经按其关键字从小到大排好序的情况下, 其递归树成为单支树, 每次划分只得到一个比上一次少一个对象的子序列。总的关键字比较次数将达 因此,快速排序在最坏情况下的时间复杂度为O(n2) 快速排序是一种不稳定的排序方法。 计算机软件技术基础 查找与排序

用第一个对象作为基准对象 快速排序退化的例子 08 16 21 25 25* 49 08 初始 16 21 25 25* 49 08 16 08 16 21 25 25* 49 08 1 2 3 4 5 6 t 初始 16 21 25 25* 49 08 16 i = 1 21 25 25* 49 21 08 16 i = 2 25 25 25* 49 08 16 21 i = 3 25* 49 25* 08 16 21 25 i = 4 49 08 16 21 25 25* i = 5 用第一个对象作为基准对象 快速排序退化的例子 计算机软件技术基础 查找与排序

2. 快速排序 用居中排序码对象作为基准对象 08 16 21 25 25* 49 21 初始 08 16 21 25 25* 49 08 其排序速度退化到简单排序的水平, 比直接插入排序还慢。占用附加存储(栈)将达到O(n)。 改进办法: 取每个待排序对象序列的第一个对象、最后一个对象和位置接近正中的 3 个对象,取其关键字居中者作为基准对象。 08 16 21 25 25* 49 1 2 3 4 5 6 t 21 初始 08 16 21 25 25* 49 08 25* i = 1 08 16 21 25 25* 49 i = 2 用居中排序码对象作为基准对象 计算机软件技术基础 查找与排序

五、归并排序 1. 归并,是将两个或两个以上的有序表合并成一个新的有序表。 对象序列a中两个有序表a[l] …a[m]和a[m+1] …a[n]。它们可归并成一个有序表, 存于另一对象序列b的b[l] …b[n] 中。 这种归并方法称为两路归并 (2-way merging)。 设变量 i 和 j 分别是表a[l] …a[m]和a[m+1] …a[n]的当前检测指针。变量 k 是存放指针。 计算机软件技术基础 查找与排序

五、归并排序 08 21 25 25* 49 62 72 93 16 37 54 start m m+1 end a i i i i i i i i j j j 08 16 21 25 25* 37 49 54 62 72 93 b k k k k k k k k k k k 当 i 和 j 都在两个表的表长内变化时, 根据对应项的排序码的大小,依次把排序码小的对象排放到新表 k 所指位置中; 当 i 与 j 中有一个已经超出表长时,将另一个表中的剩余部分照抄到新表中。 计算机软件技术基础 查找与排序

五、归并排序 2. 归并排序 归并排序算法就是利用两路归并过程进行排序的。其基本思想是: 假设初始对象序列有 n 个对象,首先把它看成是 n 个长度为 1 的有序子序列 (归并项),先做两两归并,得到 n / 2 个长度为 2 的归并项 (如果 n 为奇数,则最后一个有序子序列的长度为1);再做两两归并,…,如此重复,最后得到一个长度为 n 的有序序列。 计算机软件技术基础 查找与排序

五、归并排序 两路归并算法的函数实现 void merge(int start,int end,int m,RECORDNODE a[]){ /*将有序表a(start:m)和a(m+1:end)归并为一个新的有序表a(start:end)*/ RECORDNODE temp[MAXSIZE]; int i,j,k; i=start;j=m+1;k=start; while(i<=m&&j<=end) if(a[i].key<a[i].key){temp[i]=a[i];k++;I++;} else{temp[k]=a[j];k++;j++;} while(j<=end){temp[k]=a[j];k++;j++;} while(i<=m){temp[k]=a[i];k++;i++;} for(i=start;i<=end;I++) a[i]=temp{i};/*临时表的内容存回到a中*/ } 计算机软件技术基础 查找与排序

五、归并排序 归并排序的算法 Void MergeSort(RECORDNODE a[],int n){ /*对长度为n的数组a排序*/ Int length,left,right; left=0;length=1; while(length<N){ right=min(n-1,left+2*length-1) //限制right的值,使其不越界 Merge(left,right,length,a); if(right+length<N) left=right+1;//右边还有待合并段 else{length*=2;left=1;}//从新开始下一趟排序 } 计算机软件技术基础 查找与排序

五、归并排序 21 25 25* 93 62 72 08 37 16 54 49 len=1 25* 21 25 49 62 93 08 72 16 37 54 len=2 21 25 25* 49 08 62 72 93 16 37 54 len=4 08 21 25 25* 49 62 72 93 16 37 54 len=8 72 08 16 21 25 25* 37 49 54 62 93 len=16 计算机软件技术基础 查找与排序

五、归并排序 3. 算法分析 1) 时间复杂度 2) 空间复杂度 3) 归并排序是一个稳定的排序算法 在函数MergeSort中while循环将被执行log2n次 在while循环中,将调用Merge函数n/(2length)次 而在Merge函数中,将比较length次, 故在while循环中,将比较O(n)次 因此,此算法的时间复杂度为 O(nlogn) 2) 空间复杂度 归并排序占用附加存储较多, 需要另外一个与原待排序对象数组同样大小的辅助数组。这是这个算法的缺点。 3) 归并排序是一个稳定的排序算法 计算机软件技术基础 查找与排序

六、各种排序方法的比较 计算机软件技术基础 查找与排序

六、各种排序方法的比较  原则 1)待排序记录的个数 2)记录本身的大小 3)关键字的分布情况 4)对排序稳定性的要求 5)现有语言工具条件等 计算机软件技术基础 查找与排序

六、各种排序方法的比较  结论 1)若待排序的记录数n较小(n≤50),则可采用插入排序或直接选择排序。且由于插入排序的移动次数较选择排序多,因此若记录本身较大时宜采用选择排序。 2)若n较大,则应采用时间复杂度O(nlog2n)的排序方法,如快速排序或堆排序。当排序的关键字是随机分布时,快速排序的平均运行时间最短;堆排序只需1个辅助空间,且不会出现快速排序可能出现的最坏情况,但堆排序的建堆时间较长。 3)若待排序记录按关键字基本有序,则宜采用插入排序或冒泡排序。 计算机软件技术基础 查找与排序

六、各种排序方法的比较 4)从方法的稳定性看,所有时间复杂度为O(n2)的排序方法是稳定的,而快速排序、堆排序等性能较好的排序方法是不稳定的。 5)在一般情况下,待排序记录采用顺序存储结构,而当记录本身较大时,为避免耗费大量时间移动记录,可用链表作存储结构。 6)当待排序记录经常进行插入、删除时,为避免大量移动记录,宜采用动态存储结构。 计算机软件技术基础 查找与排序

小结 1、理解两种基本操作:比较、移位 2、掌握:各种排序方法及其时间复杂度和空间复杂度 计算机软件技术基础 查找与排序