9.1 概述 9.2 插入排序 9.3 交换排序 9.4 选择排序 9.5 归并排序 9.6 基数排序 9.7 各种内部排序的比较

Slides:



Advertisements
Similar presentations
第 8 章 数组 计算机科学学院 李淮 Tel QQ
Advertisements

A A A.
教师成绩录入步骤 1. 登录教务系统 2. 进入教师成绩管理界面 3. 选择相应的教学班,点击 “ 课程成绩录 入 ” 进入成绩录入界面 4. 点击 “ 设置 ” 按钮设置 “ 成绩分项 ” 5. 录入成绩, “ 保存成绩 ” 按钮可以保存成 绩但不提交(提交后不能再修改成绩) 6. “ 提交成绩 ”
7.2 图示化记忆 记忆的概述 图示化记忆 联想记忆法 奇特联想记忆法 用手记忆.
第一节三 怎样实现合理膳食. 饮食与健康 探 究 竟探 究 竟 1. 根据课本后的部分食物营养成分表(附表一),分组将聪聪和明明一天所吃的 食物重量分别换算成糖类、蛋白质、脂肪和钙的重量。 聪聪(女 12 岁)明明(男 13 岁) 鸡 蛋 75g 油 条 200g 牛 奶 250g.
1 债券融资业务拓展交流 债券业务部 二 O 一二年二月. 2 目 录  第一部分 债券融资业务概述  第二部分 东兴证券债券融资业务情况介绍及前景展望  第三部分 什么样的企业适合发债  第四部分 债券融资业务合作开发方式及激励探讨.
轴对称(一) 课堂引入 仔细观察下列图片,思考这些图片有什么样 的特点.
《地方名人文化资源网站的建设与应用研究》. 乐至名人 叶 镛 KJ09001 乐至县吴仲良中学 邓祖明.
期末書面報告指定書籍 王鼎鈞回憶錄---昨天的雲
8 企业信息管理的定量分析 第八讲 企业信息管理的定量分析 8.1 企业信息化水平的测评 8.2 企业信息管理绩效的测评.
小班早期阅读讲座.
資料結構與演算法 課程教學投影片.
股票市場技術面概念介紹 斗六高中 馬明宏.
成才之路 · 语文 人教版 • 中国古代诗歌散文欣赏 路漫漫其修远兮 吾将上下而求索.
禁毒知识教育 ·.
物理3-5选修模块.
项目亮点 融资方为AA级发债主体,是当地唯一的综合平台公司
“八皇后”问题 崔萌萌 吕金华.
主讲:计算机工程学院 李兰 答疑地点:主教学楼B区213
数据结构及应用算法教程(修订版) 配套课件.
评价是为了促进 学生发展的评价。. 评价是为了促进 学生发展的评价。 语言有温度,字词知冷暖.
第十章 内部排序 知识点3:快速排序.
简单选择排序.
排序.
第九章 排序 插入排序 交换排序 选择排序 归并排序 基数排序.
第八章 查找.
第十章 内部排序 10.1 概述 10.2 插入排序 直接插入排序 其他插入排序 希尔排序
第二章 线性表 1 线性表的逻辑结构及其基本操作 2 线性表的顺序存储结构 3 线性表的链式存储结构 4 静态链表 5 应用实例.
C语言基础——指针的高级应用 Week 05.
課程名稱:資料結構 授課老師:_____________
C语言程序设计 课程 第5章 数组 主讲:李祥 博士、副教授 单位:软件学院软件工程系.
第8章 排序.
第十章 排序.
第九章 排序 概述 插入排序 交换排序 选择排序 归并排序 基数排序 外排序.
排序 Sorting.
第九章 排序 9.1排序的基本概念 9.2简单排序方法(复杂度 O(n2)) 9.3先进排序方法(复杂度 O(nLogn))
快速排序法 (Quick Sort).
第十章 排序 10.1排序的基本概念 10.2简单排序方法(复杂度 O(n2))
第9章 排序.
1、基本概念 2、插入排序 3、交换排序 4、选择排序 5、归并排序 6、基数排序 7、外部排序
搜尋資料結構 Search Structures.
第六章 二叉树和树 6.1树的基本概念 6.2二叉树 6.3二叉树遍历 6.4线索二叉树 6.5树和森林 6.6树的应用(霍夫曼树及其编码)
第九章 排序 9.1排序的基本概念 9.2简单排序方法(复杂度 O(n2)) 9.3先进排序方法(复杂度 O(nLogn))
第8章 排 序 8.1 排序技术概述 8.2 插入排序 8.3 选择排序 8.4 交换排序 8.5 归并排序 8.6 基数排序
第九章 查找 2018/12/9.
数 据 结 构 Ch.4 串 计 算 机 学 院 肖明军
中央广播电视大学开放教育试点课程 数据结构 辅导教师 倪政林.
第9章 内部排序 9.1 概述 9.2 插入排序 9.3 快速排序 9.4 选择排序 9.5 归并排序 9.6 基数排序
基數排序法.
Sorting 排序 Bubble Sort O(n2) Insert Sort Selection Sort Quick Sort
数据结构 Data Structure CSU 主讲人:王国军,郑瑾 中南大学信息院计科系
数据结构 第八章 查找.
教 师:曾晓东 电 话: E_mail: 计算机软件技术基础 教 师:曾晓东 电 话: E_mail:
3.1 线性表及逻辑结构 3.2 线性表的顺序存储 3.3 线性表的链式存储 3.4 链式存储结构的应用
ACM 程序设计(一) 主讲:朱佳 博士 华南师范大学计算机学院.
資料結構與C++程式設計進階 排序與搜尋 講師:林業峻 CSIE, NTU 6/ 14, 2010.
第8章 資料排序 資料結構設計與C++程式應用
綠色能源.
第九章 排序 概述 插入排序 快速排序 交换排序(起泡排序) 选择排序 归并排序.
第1章 绪论(二) 教学目标 理解算法的特性及评价标准 掌握算法时间复杂度和空间复杂度的分析方法 1/
99高中資訊科選修課程 夥伴學習教師 專業進修研習 進階程式設計--演算法 教學示例與研討
算法导论第一次习题课.
資料結構與C++程式設計進階 遞迴(Recursion) 講師:林業峻 CSIE, NTU 6/ 17, 2010.
单片机原理及应用 实践部分 主讲人:刘 强 四川工商学院单片机教学团队 单片机原理及应用 实践部分 主讲人:刘 强
第七章  数 组.
第8章 排序 8.1排序基本概念 8.2插入类排序 8.3交换类排序 8.4选择类排序 8.5归并排序 8.6基数排序
第1章 数据结构基础概论 本章主要介绍以下内容 数据结构研究的主要内容 数据结构中涉及的基本概念 算法的概念、描述方法以及评价标准.
算法的基本思想: 第6章 内部排序 6.2 气泡排序 将待排序的记录看作是竖着排列的“气泡”,关键字较小 的记录比较轻,从而要往上浮。
第三章 流程控制 程序的运行流程 选择结构语句 循环结构语句 主讲:李祥 时间:2015年10月.
排序 排序(sorting)是计算机程序设计中的一种重要操作,它的功能是将一个数据元素(或记录)的任意序列,重新排列成一个按关键字有序的序列。 由于待排序的记录数量不同,使得排序过程中涉及的存储器不同,可将排序方法分为两大类:一类是内部排序,指的是待排序记录存放在计算机存储器中进行的排序过程;另一类是外部排序,指的是待排序记录的数量很大,以致内存一次不能容纳全部记录,在排序过程中对外存进行访问的排序过程。
Presentation transcript:

9.1 概述 9.2 插入排序 9.3 交换排序 9.4 选择排序 9.5 归并排序 9.6 基数排序 9.7 各种内部排序的比较 第九章 排序 9.1 概述 9.2 插入排序 9.3 交换排序 9.4 选择排序 9.5 归并排序 9.6 基数排序 9.7 各种内部排序的比较

9.1 概述 一、排序 定义——将一个数据元素(或记录)的任意序列,重新排列成一个按关键字有序的序列叫~ 二、排序分类 9.1 概述 一、排序 定义——将一个数据元素(或记录)的任意序列,重新排列成一个按关键字有序的序列叫~ 二、排序分类 1.按待排序记录所在位置 内部排序:待排序记录存放在内存 外部排序:排序过程中需对外存进行访问的排序 2.按排序依据原则 插入排序:直接插入排序、折半插入排序、希尔排序 交换排序:冒泡排序、快速排序 选择排序:简单选择排序、堆排序 归并排序:2-路归并排序 基数排序

3、按排序所需工作量 简单的排序方法:T(n)=O(n²) 先进的排序方法:T(n)=O(logn) 基数排序:T(n)=O(d.n) 4、排序基本操作 比较两个关键字大小 将记录从一个位置移动到另一个位置 三、排序的稳定性 如果两个相同的关键字ki与关键字kj在排序之前其序号为i<j,在排完序后,这两个关键字的关后位置关系依然为i<j, 则认为排序是稳定的,反之认为是不稳定的。

9.2 插入排序 9.2.1 直接插入排序 1.排序的思想: 排序过程:整个排序过程为n-1趟插入,即先将序列中第1个记录看成是一个有序子序列,然后从第2个记录开始,逐个进行插入,直至整个序列有序 2.算法描述: void InsertSort(SqList &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]; //监视哨 L.r[i]=L.r[i-1]; j=i-2; while(LT(L.r[0].key,L.r[j].key){j--;L.r[j+1]=L.r[j];} L.r[j+1]=L.r[0]; }

3.算法演示: 例 i=1 ( ) 49 38 65 97 76 13 27 i=2 38 (38 49) 65 97 76 13 27 i=3 65 (38 49 65) 97 76 13 27 i=4 97 (38 49 65 97) 76 13 27 i=5 76 (38 49 65 76 97) 13 27 i=6 13 (13 38 49 65 76 97) 27 i=7 (13 38 49 65 76 97) 27 27 27 38 49 65 76 97 j j j j j j (13 27 38 49 65 76 97) 排序结果:

.若待排序记录按关键字从小到大排列(正序) 关键字比较次数: 4.算法评价: (1)时间复杂度 .若待排序记录按关键字从小到大排列(正序) 关键字比较次数: 记录移动次数: .若待排序记录按关键字从大到小排列(逆序) 关键字比较次数: 记录移动次数: .若待排序记录是随机的,取平均值 关键字比较次数: T(n)=O(n²) 记录移动次数: (2)空间复杂度:S(n)=O(1)

9.2.2 折半插入排序 排序过程:用折半查找方法确定插入位置的排序叫~ 例 i=1 (30) 13 70 85 39 42 6 20 …... i=7 6 (6 13 30 39 42 70 85 ) 20 i=8 20 (6 13 30 39 42 70 85 ) 20 s j m i=8 20 (6 13 30 39 42 70 85 ) 20 s j m i=8 20 (6 13 30 39 42 70 85 ) 20 s j m i=8 20 (6 13 30 39 42 70 85 ) 20 s j i=8 20 (6 13 20 30 39 42 70 85 )

1、算法描述 2、算法评价 void BInsertSort(SqList &L) {for(i=2;i<=L.length;++i) { L.r[0]=L.r[i]; low=1; high=i-1; //已排序的序列 while(low<=high){ //找位置 m=(low+high)/2; if(LT(L.r[m].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]; //移动 L.r[high+1]=L.r[0]; //插入 } //for }//BInsertSort 2、算法评价 时间复杂度:T(n)=O(n²) 空间复杂度:S(n)=O(1)

9.2.3 希尔排序(缩小增量法) 1.排序思想: 先取一个正整数d1<n,把所有相隔d1的记录放一组,组内进行直接插入排序;然后取d2<d1,重复上述分组和排序操作;直至di=1,即所有记录放进一个组中排序为止 2. 算法描述: void ShellInsert(SqList &L,int dk) {for(i=dk+1;i<=L.length;++i) if(LT(L.r[i].key,L.r[i-dk].key) { L.r[0]=L.r[i]; //监视哨 for(j=i-dk;j>0&&LT(L.r[0].key,L.r[j].key);j-=dk)//移动 L.r[j+dk]=L.r[j]; L.r[j+dk]=L.r[0]; //插入 }// if,for }//ShellInsert void ShellSort(SqList &L,int delta[],int t) { for(k=0;k<t;k++) ShellInsert(L,dlta[k] } //如dlta={5,3,1}

例 初始: 49 38 65 97 76 13 27 48 55 4 取d1=5 一趟分组: 49 38 65 97 76 13 27 48 55 4 一趟排序: 13 27 48 55 4 49 38 65 97 76 取d2=3 二趟分组: 13 27 48 55 4 49 38 65 97 76 二趟排序: 13 4 48 38 27 49 55 65 97 76 取d3=1 三趟分组: 13 27 48 55 4 49 38 65 97 76 三趟排序: 4 13 27 38 48 49 55 65 76 97

#define T 3 int d[]={5,3,1}; 例 49 38 65 97 76 13 27 48 55 4 13 27 48 55 4 49 38 65 97 76 j i j i j i j i j i 一趟排序: 13 27 48 55 4 49 38 65 97 76 4 38 27 55 j i j i j i j i j i j i j i j i 二趟排序: 13 4 48 38 27 49 55 65 97 76

3、希尔排序特点 (1) 子序列的构成不是简单的“逐段分割”,而是将相隔某个增量的记录组成一个子序列 (2)希尔排序可提高排序速度,因为 ○分组后n值减小,n²更小,而T(n)=O(n²),所以T(n)从总体上看是减小了 ○关键字较小的记录跳跃式前移,在进行最后一趟增量为1的插入排序时,序列已基本有序,所以移动次数并不多。 (3) 增量序列取法 ○无除1以外的公因子 ○最后一个增量值必须为1

9.3 交换排序 9.3.1 冒泡排序 1、排序思想 (1)将第一个记录的关键字与第二个记录的关键字进行比较,若为逆序r[1].key>r[2].key,则交换;然后比较第二个记录与第三个记录;依次类推,直至第n-1个记录和第n个记录比较为止——第一趟冒泡排序,结果关键字最大的记录被安置在最后一个记录上 (2)对前n-1个记录进行第二趟冒泡排序,结果使关键字次大的记录被安置在第n-1个记录位置 (3)重复上述过程,直到“在一趟排序过程中没有进行过交换记录的操作”为止

2、冒泡排序算法演示 排序前 10 21 22 33 15 7 8 1 4 找第1个最大数 第1步 10 21 22 33 15 7 8 1 4 15 7 33 33 8 1 33 33 15 4 33 33 找第 i 个最大数 第i步 10 15 7 8 1 4 21 22 33 7 8 15 15 1 15 4 15 从第 1个元素开始到第 i 个元素,把相邻两个元素进行比较,如果前面的比后面的大,则交换两个元素,这样可以得使第 i 个元素是最大的。算法如下: 让 j 从 1 到 i 变化,重复: 如果L.r[j].key>L.r[j+1].key ,则交换L.r[j]与L.r[j+1]

3.算法描述和实现 void BubbleSort(SqList &L) { n=L.length; for(i=1;i<=n;i++) {flag=FALSE; //交换标志 for(j=1;j<=n-i;j++) if(GT(L.r[j].key,L.r[j+1].key) //如果前面元素大于后面元素,则交换 { temp=L.r[j];L.r[j]=L.r[j+1];L.r[j+1]=temp; flag=TRUE; //有交换 }//if if(!flag) break; //如果无交换,则结束 }//for }//BubbleSort

4、算法评价 (1)时间复杂度 最好情况(正序) ◎比较次数:n-1 ◎移动次数:0 最坏情况(逆序) ◎比较次数: ◎移动次数: T(n)=O(n²) (2)空间复杂度:S(n)=O(1)

1、基本思想:通过一趟排序,将待排序记录分割成独立的三部分 9.3.2 快速排序 1、基本思想:通过一趟排序,将待排序记录分割成独立的三部分 (x1,x2,x3,...,xk-1) xk (xk+1,xk+2,....,xn) 其中,xk比左边的所有元素都大,但比右边所有元素都小。 2、排序过程:对r[s……t]中记录进行一趟快速排序,附设两个指针i和j,设数组记录rp=r[s],x=rp.key (1)初始时令i=s,j=t (2)首先从j所指位置向前搜索第一个关键字小于x的记录,并和rp交换 (3)再从i所指位置起向后搜索,找到第一个关键字大于x的记录,和rp交换 (4)重复上述(2)、(3)两步,直至i==j为止 (5)再分别对两个子序列进行快速排序,直到每个子序列只含有一个记录为止

x 例 初始关键字: 49 38 65 97 76 13 27 50 27 49 49 97 13 49 49 65 i j j i i j i j i j j i i j i j 完成一趟排序: ( 27 38 13) 49 (76 97 65 50) 分别进行快速排序: ( 13) 27 (38) 49 (50 65) 76 (97) 快速排序结束: 13 27 38 49 50 65 76 97

3、算法描述及实现: void QuickSort(SqList &L,int low,int high) int Patition(SqList &L,int low,int high) { x=L.r[low].key; //用子表第一个元素作分类 while(low<high) { //从后往前走,如果x大于r[high]元素,则结束并交换 while(low<high&&L.r[high].key>=x) --high; swap(L.r[low],L.r[high]); //交换 //从前往后走,如果x小于r[low]元素,则结束并交换 while(low<high&&L.r[low].key<=x) ++low; swap(L.r[low],L.r[high]); //交换 } return low; //分类元素所在下标 void QuickSort(SqList &L,int low,int high) { if(low<high) {m=Patition(L,low,high); QuickSort(SqList,low,m-1); QuickSort(SqList,m+1,high); }

4、算法评价 (1)时间复杂度 最好情况(每次总是选到中间值作分类元素) T(n)=O(nlog2n) (2)空间复杂度:需栈空间以实现递归 最坏情况:S(n)=O(n) 一般情况:S(n)=O(log2n)

9.4 选择排序 9.4.1 简单选择排序 1、排序思想 (1)首先通过n-1次关键字比较,从n个记录中找出关键字最小的记录,将它与第一个记录交换 (2)再通过n-2次比较,从剩余的n-1个记录中找出关键字次小的记录,将它与第二个记录交换 (3)重复上述操作,共进行n-1趟排序后,排序结束

k k k 例 i=1 初始: [ 49 38 65 97 76 13 27 ] 13 49 j j j j j j k k i=2 2、算法演示 k k k 例 i=1 初始: [ 49 38 65 97 76 13 27 ] 13 49 j j j j j j k k i=2 一趟: 13 [38 65 97 76 49 27 ] 27 38 j j j j j 二趟: 13 27 [65 97 76 49 38 ] 三趟: 13 27 38 [97 76 49 65 ] 四趟: 13 27 38 49 [76 97 65 ] 五趟: 13 27 38 49 65 [97 76 ] 六趟: 13 27 38 49 65 76 [97 ] 排序结束: 13 27 38 49 65 76 97

3、算法描述与实现 void SelectSort(SqList &L) {n=L.length; for(i=1;i<=n;i++) { p=SelectMinKey(L,i); //在i..n之间选择最小数下标 if(p!=i) swap(L.r[i],L.r[p]); }//for }//selectsort int SelectMinKey(SqList &L,int i) {min=i; for(k=i;k<=L.length;k++) if(LT(L.r[k].key,L.r[min].key) min=k; //找最小下标min return min; }

4、算法评价 (1)时间复杂度 记录移动次数 最好情况:0 最坏情况:3(n-1) 比较次数: T(n)=O(n²) (2)空间复杂度:S(n)=O(1)

n个元素的序列(k1,k2,……kn),当且仅当满足下列关系时,称之为堆 9.4.2 堆排序 1、堆的定义: n个元素的序列(k1,k2,……kn),当且仅当满足下列关系时,称之为堆 或 (i=1,2,…...n/2) kik2i kik2i+1 kik2i kik2i+1 例 (96,83,27,38,11,9) 例 (13,38,27,50,76,65,49,97) 13 27 38 49 65 76 50 97 96 27 9 11 38 83 可将堆序列看成完全二叉树,则堆顶 元素(完全二叉树的根)必为序列中 n个元素的最小值或最大值

2、堆排序思想:将无序序列建成一个堆,得到关键字最小(或最大)的记录;输出堆顶的最小(大)值后,使剩余的n-1个元素重又建成一个堆,则可得到n个元素的次小值;重复执行,得到一个有序序列,这个过程叫~ (1)堆排序需解决的两个问题: 如何由一个无序序列建成一个堆?(建堆) 如何在输出堆顶元素之后,调整剩余元素,使之成为一个新的堆?(调整堆) (2)第二个问题解决方法——筛选 方法:输出堆顶元素之后,以堆中最后一个元素替代之;然后将根结点值与左、右子树的根结点值进行比较,并与其中小者进行交换;重复上述操作,直至叶子结点,将得到新的堆,称这个从堆顶至叶子的调整过程为“筛选”

例 97 27 38 49 65 76 50 13 输出:13 27 49 38 97 65 76 50 13 输出:13 13 27 38 49 65 76 50 97 97 49 38 27 65 76 50 13 输出:13 27 38 49 50 27 65 76 97 13 输出:13 27 65 49 50 27 38 76 97 13 输出:13 27 38

49 65 50 27 38 76 97 13 输出:13 27 38 76 65 50 27 38 49 97 13 输出:13 27 38 49 50 65 76 27 38 49 97 13 输出:13 27 38 49 97 65 76 27 38 49 50 13 输出:13 27 38 49 50 65 97 76 27 38 49 50 13 输出:13 27 38 49 50 97 65 76 27 38 49 50 13 输出:13 27 38 49 50 65

76 65 97 27 38 49 50 13 输出:13 27 38 49 50 65 97 65 76 27 38 49 50 13 输出:13 27 38 49 50 65 76 97 65 76 27 38 49 50 13 输出:13 27 38 49 50 65 76 97

3、堆排序算法描述 (1)第一个问题解决方法—建堆 void HeapSort(HeapType &H) {for(i=H.length/2;i>0;--i) //建堆 HeapAdjust(H,i,H.length); for(i=H.length;i>1;--i) {swap(H.r[1],H.r[i] HeapAdjust(H,1,i-1); //调整H.r[1..i-1]为最大堆 } }//HeapSort (1)第一个问题解决方法—建堆 方法:从无序序列的第n/2个元素(即此无序序列对应的完全二叉树的最后一个非终端结点)起,至第一个元素止,进行反复筛选

例 含8个元素的无序序列(49,38,65,97,76,13,27,50) 49 65 38 27 13 76 97 50 49 65 38 27 13 76 50 97 49 13 38 27 65 76 50 97 49 13 38 27 65 76 50 97 13 27 38 49 65 76 50 97

4、调整堆算法描述 5、算法评价 (1)时间复杂度:最坏情况下T(n)=O(nlogn) (2)空间复杂度:S(n)=O(1) void HeapAdjust(HeapType &H,int s,int m) {//设H.r[s..m]之间的元素除了H.r[s]外,其余的H.r[s+1..m]满足最大堆性质 rc=H.r[s]; j=2*s; while(j<=m) {if(j<m&&LT(H.r[j].key,H.r[j+1].key) ++j; //找s的两个孩子的最大孩子 if(!LT(rc.key,H.r[j].key) break; //如果双亲不大于最大孩子,则已经是堆,结束 H.r[s]=H.r[j]; //最大元素调到双亲 s=j; //以最大孩子作为新的子树,继续向下调整 j=2*s; //新子树s的孩子 }//while }//HeapAdjust 5、算法评价 (1)时间复杂度:最坏情况下T(n)=O(nlogn) (2)空间复杂度:S(n)=O(1)

将两个或两个以上的有序表组合成一个新的有序表,叫~ 2、2路归并排序 (1)排序思想 9.5 归并排序 1、归并 将两个或两个以上的有序表组合成一个新的有序表,叫~ 2、2路归并排序 (1)排序思想 设初始序列含有n个记录,则可看成n个有序的子序列,每个子序列长度为1 两两合并,得到n/2个长度为2或1的有序子序列 再两两合并,……如此重复,直至得到一个长度为n的有序序列为止

例 初始关键字: [49] [38] [65] [97] [76] [13] [27] 一趟归并后: [38 49] [65 97] [13 76] [27] 二趟归并后: [38 49 65 97] [13 27 76] 三趟归并后: [13 27 38 49 65 76 97]

3、算法描述 4、算法评价 (1)时间复杂度:T(n)=O(nlog2n) (2)空间复杂度:S(n)=O(n) void Merge(RcdType SR[],RcdType &TR,int i,int m,int n) { j=m+1; k=i; //SR[i..m]与SR[m+1,n]合并,合并后放入TR[i..n]中 while(i<=m&&j<=n) if(LQ(SR[i].key,SR[j].key)TR[k++]=SR[i++]; else TR[k++]=SR[j++]; if(i<=m)TR[k..n]=SR[i..m]; //如果第一个数组未完,其余放入后面 if(j<=n) TR[k..n]=SR[j..n]; //如果第二个数组未完,其余放入后面 }//Merge //将SR[s..t]归并为TR1[s..t] void MSort(RcdType SR[],RcdType &TR1[],int s,int t) {if(s==t) TR1[s]=SR[s]; else { m=(s+t)/2; MSort(SR,TR2,s,m); //将SR[s..m]归并到TR2[s..m] MSort(SR,TR2,m+1,t);//将SR[m+1..t]归并到TR[m+1..t]中 Merge(TR2,TR1,s,m,t);//将TR2[s..t]归并入TR1中 } 4、算法评价 (1)时间复杂度:T(n)=O(nlog2n) (2)空间复杂度:S(n)=O(n)

2<3<……<A<2<3<……<A< 9.6 基数排序 9.6.1 多关键字排序 1.定义 例 对52张扑克牌按以下次序排序: 2<3<……<A<2<3<……<A< 2<3<……<A<2<3<……<A 两个关键字:花色( <<< ) 面值(2<3<……<A) 并且“花色”地位高于“面值” 2、多关键字排序方法 (1)最高位优先法(MSD):先对最高位关键字k1(如花色)排序,将序列分成若干子序列,每个子序列有相同的k1值;然后让每个子序列对次关键字k2(如面值)排序,又分成若干更小的子序列;依次重复,直至就每个子序列对最低位关键字kd排序;最后将所有子序列依次连接在一起成为一个有序序列

(2)最低位优先法(LSD):从最低位关键字kd起进行排序,然后再对高一位的关键字排序,……依次重复,直至对最高位关键字k1排序后,便成为一个有序序列 (3)MSD与LSD不同特点 按MSD排序,必须将序列逐层分割成若干子序列,然后对各子序列分别排序 按LSD排序,不必分成子序列,对每个关键字都是整个序列参加排序;并且可不通过关键字比较,而通过若干次分配与收集实现排序 9.6.2 链式基数排序 基数排序:借助“分配”和“收集”对单逻辑关键字进行排序的一种方法 链式基数排序:用链表作存储结构的基数排序

1、链式基数排序步骤 (1)设置10个队列,f[i]和e[i]分别为第i个队列的头指针和尾指针 (2)第一趟分配对最低位关键字(个位)进行,改变记录的指针值,将链表中记录分配至10个链队列中,每个队列记录的关键字的个位相同 (3)第一趟收集是改变所有非空队列的队尾记录的指针域,令其指向下一个非空队列的队头记录,重新将10个队列链成一个链表 (3)重复上述两步,进行第二趟、第三趟分配和收集,分别对十位、百位进行,最后得到一个有序序列

例 初始状态: 278 109 063 930 589 184 505 269 008 083 e[0] e[1] e[2] e[3] e[4] e[5] e[6] e[7] e[8] e[9] f[0] f[1] f[2] f[3] f[4] f[5] f[6] f[7] f[8] f[9] 一趟分配 930 083 184 505 008 269 589 063 278 109 930 063 083 184 505 278 008 109 589 269 一趟收集:

930 063 083 184 505 278 008 109 589 269 一趟收集: e[0] e[1] e[2] e[3] e[4] e[5] e[6] e[7] e[8] e[9] f[0] f[1] f[2] f[3] f[4] f[5] f[6] f[7] f[8] f[9] 二趟分配 109 930 269 589 278 008 184 505 063 083 505 008 109 930 063 269 278 083 184 589 二趟收集:

505 008 109 930 063 269 278 083 184 589 二趟收集: e[0] e[1] e[2] e[3] e[4] e[5] e[6] e[7] e[8] e[9] f[0] f[1] f[2] f[3] f[4] f[5] f[6] f[7] f[8] f[9] 三趟分配 083 184 278 589 930 063 008 109 269 505 008 063 083 109 184 269 278 505 589 930 三趟收集:

2、算法描述与实现 //分配算法,对第i个关键字进行分配 void Distribute(SLCell &r,int i,ArrType &f,ArrType &r) { for(j=0;j<Radix;++j) f[j]=0; p=r[0].next; while(p!=0) {j=ord(r[p].keys[i]); //将记录中第i个关键字映射到[0..RADIX-1],即第i个关键字对应队列j if(!f[j]) f[j]=p; //如果是空队,直接赋值 else r[e[j]].next=p; //放在队尾元素的后面,r[e[j]]表示队列j的队尾元素一 e[j]=p; //修改队列j的队尾指针 p=r[p].next; //取p元素的下一个元素 }//while }//Distribute void Collect(SLCell &r,int i,ArrType f,ArrType e) { for(j=0;f[j]!=0;j=succ(j)); //找第一非空子表 r[0].next=f[j];t=e[j]; while(j<RADIX){ for(j=succ(j);j<RADIX-1&&f[j]==0;j=succ(j)); if(f(j)!=0) {r[t].next=f[j];t=e[j];} }//while r[t].next=0; }//Collect

3、算法评价 (1)时间复杂度: (2)空间复杂度:S(n)=2rd个队列指针+n个指针域空间 分配:T(n)=O(n) 收集:T(n)=O(rd) T(n)=O(d(n+rd)) 其中:n——记录数 d——关键字数 rd——关键字取值范围 (2)空间复杂度:S(n)=2rd个队列指针+n个指针域空间

f[0]=0 e[0]=0 f[1]=0 e[1]=0 f[2]=0 e[2]=0 f[3]=0 e[3]=0 f[4]=0 e[4]=0 初始状态: 1 278 109 063 930 589 184 505 269 008 083 2 3 4 5 6 7 8 9 10 f[0]=0 e[0]=0 f[1]=0 e[1]=0 f[2]=0 e[2]=0 f[3]=0 e[3]=0 f[4]=0 e[4]=0 f[5]=0 e[5]=0 f[6]=0 e[6]=0 f[7]=0 e[7]=0 f[8]=0 e[8]=0 f[9]=0 e[9]=0 4 4 3 10 3 6 6 7 7 1 9 1 2 5 8 2 4 930 063 083 184 505 278 008 109 589 269 3 10 6 7 1 9 2 5 8

f[0]=0 e[0]=0 f[1]=0 e[1]=0 f[2]=0 e[2]=0 f[3]=0 e[3]=0 f[4]=0 e[4]=0 930 063 083 184 505 278 008 109 589 269 3 10 6 7 1 9 2 5 8 一趟收集: f[0]=0 e[0]=0 f[1]=0 e[1]=0 f[2]=0 e[2]=0 f[3]=0 e[3]=0 f[4]=0 e[4]=0 f[5]=0 e[5]=0 f[6]=0 e[6]=0 f[7]=0 e[7]=0 f[8]=0 e[8]=0 f[9]=0 e[9]=0 7 2 9 7 4 4 3 8 3 1 1 10 10 5 6 7 505 008 109 930 063 269 278 083 184 589 9 2 4 3 8 1 10 6 5 二趟收集:

f[0]=0 e[0]=0 f[1]=0 e[1]=0 f[2]=0 e[2]=0 f[3]=0 e[3]=0 f[4]=0 e[4]=0 7 505 008 109 930 063 269 278 083 184 589 9 2 4 3 8 1 10 6 5 二趟收集: f[0]=0 e[0]=0 f[1]=0 e[1]=0 f[2]=0 e[2]=0 f[3]=0 e[3]=0 f[4]=0 e[4]=0 f[5]=0 e[5]=0 f[6]=0 e[6]=0 f[7]=0 e[7]=0 f[8]=0 e[8]=0 f[9]=0 e[9]=0 9 10 3 9 2 6 2 8 8 1 7 5 7 4 9 008 063 083 109 184 269 278 505 589 930 3 10 2 6 8 1 7 5 4 三趟收集: 4

总 结 要求: 掌 握:插入算法、选择算法、冒泡算法 基本掌握:快速排序,堆排序,归并排序 希尔排序 理解:基数排序,折半排序 总 结 要求: 掌 握:插入算法、选择算法、冒泡算法 基本掌握:快速排序,堆排序,归并排序 希尔排序 理解:基数排序,折半排序 要素:排序思想,时间复杂度,算法稳定性