版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
10.4选择排序(1)简单选择排序(2)堆排序基本思路主要的选择排序方法:全局有序区无序区选出最小元素R[minj]1/4310.4.1简单选择排序1.排序思路
从一个无序区中选出最小的元素,最简单方法是逐个进行元素比较,例如,从无序区R[i..n-1]中选出最小元素R[minj]。minj=i;
//minj先置为区间中的首元素序号for(intj=i+1;j<n;j++)
//从R[i..n-1]中选最小元素的R[minj]
if(R[j]<R[minj])
//与区间中其他元素比较
minj=j;简单选择2/43有2n个整数,找到其中最大整数需要比较次数最少是()次。A.n B.log2n C.n2D.2n E.2n-1 F.n-1示例3/43全局有序区R[0]
……
R[i-1]无序区R[i]
……
R[n-1]全局有序区R[0]
……
R[i-1]R[i]无序区R[i+1]
……
R[n-1]采用简单选择方法选出最小元素初始时,全局有序区为空i=0~n-2,共经过n-1趟排序4/43
【例10.6】设待排序的表有10个元素,其关键字分别为(6,8,7,9,0,1,3,2,4,5)。说明采用简单选择排序方法进行排序的过程。初始关键字
[]6 8 7 9 0 1 3 2 4 5i=0的结果: [0] 8 7 9 6 1 3 2 4 5i=1的结果: [0 1] 7 9 6 8 3 2 4 5i=2的结果: [0 1 2] 9 6 8 3 7 4 5i=3的结果: [0 1 2 3] 6 8 9 7 4 5i=4的结果: [0 1 2 3 4] 8 9 7 6 5i=5的结果: [0 1 2 3 4 5] 9 7 6 8i=6的结果: [0 1 2 3 4 5 6] 7 9 8i=7的结果: [0 1 2 3 4 5 6 7] 9 8i=8的结果: [0 1 2 3 4 5 6 7 8] 95/432.排序算法voidSelectSort(vector<int>&R,intn) //简单选择排序{for(inti=0;i<n-1;i++) //做第i趟排序{intminj=i;
for(intj=i+1;j<n;j++)
//在当前无序区R[i..n-1]中选最小元素R[minj]
if(R[j]<R[minj])
minj=j;
//minj记下目前找到的最小元素的位置if(minj!=i) //若R[minj]不是无序区首元素swap(R[i],R[minj]); //交换R[i]和R[minj]}}6/437/43简单选择排序3.算法分析
无论初始数据序列的状态如何,在第i趟排序从无序区R[i..n-1](含n-i个元素)中选出最小元素时,内for循环需做n-i-1次比较,因此,总的比较次数为8/43元素的移动次数当初始数据序列正序时,移动次数为0。反序时每趟排序均要执行交换操作,此时总的移动次数为最大值3(n-1)。最好、最坏和平均情况的时间复杂度均为O(n2)。9/43是一种不稳定的排序方法(5,
5,1)无序区交换(1,
5,5)10/4310.4.2堆排序1.排序思路11/43全局有序区无序区选出最大元素R[k]采用堆方法选出最大元素:堆排序算法一个序列R[0..n-1],关键字分别为k0、k1、、kn-1。堆的定义该序列满足如下性质(简称为堆性质):
ki≤k2i+1
且ki≤k2i+2
或
ki≥k2i+1
且ki≥k2i+2
(0≤i≤
n/2-1)满足第
种情况的堆称为小根堆,满足第
种情况的堆称为大根堆。下面讨论的堆是大根堆。12/43a0a1a2an-1…完全二叉树i2i+12i+2左孩子右孩子大根堆:对应的完全二叉树中,任意一个结点的关键字都大于或等于它的孩子结点的关键字。最小关键字的元素一定是某个叶子结点!!!层序编号方式:a0
a1
…
an-1
将序列a0
a1
…
an-1看成是一颗完全二叉树13/431295413n=6如何判断一颗完全二叉树是否为大根堆013245从编号为n/2-1=2的结点开始,逐一判断所有分支结点所有分支结点满足定义
为大根堆14/43堆排序的关键是构造堆,这里采用筛选算法建堆。所谓“筛选”指的是,对一棵左/右子树均为堆的完全二叉树,“调整”根结点使整个二叉树也成为一个堆。堆堆筛选堆2.排序算法15/43是一个堆是一个堆295413
筛选:不是堆
堆从根开始筛选大根堆tmp16/43295413从根开始筛选直接插入排序思路17/43自顶向下筛选:从根结点R[low]开始向下依次查找较大的孩子结点,构成一个序列(2,9,4),其中除了2外其他元素的子序列恰好是递减的。采用类似直接插入排序的思路使其成为一个递减序列(因为大根堆中从根到每个叶子结点的路径均构成一个递减序列)。仅仅处理从根结点
某个叶子结点路径上的结点n个结点的完全二叉树高度为
log2(n+1)
所有筛选的时间复杂度为O(log2n)295413从根开始筛选18/43low2*low+12*low+2……high…向下筛选算法siftDown(RecType[]R,intlow,inthigh):R[low..high]R[low..high]根最后结点19/43voidsiftDown(vector<int>&R,intlow,inthigh)//R[low..high]的自顶向下筛选{inti=low;intj=2*i+1; //R[j]是R[i]的左孩子inttmp=R[i]; //tmp临时保存根结点while(j<=high) //只对R[low..high]的元素进行筛选{if(j<high&&R[j]<R[j+1])j++; //若右孩子较大,把j指向右孩子if(tmp<R[j]) //tmp的孩子较大{R[i]=R[j]; //将R[j]调整到双亲位置上
i=j;j=2*i+1; //修改i和j值,以便继续向下筛选}elsebreak; //若孩子较小,则筛选结束}R[i]=tmp;
//原根结点放入最终位置}20/43向上筛选算法voidsiftUp(vector<int>&R,intj)//自底向上筛选:从叶子结点j向上筛选{inti=(j-1)/2; //i指向R[j]的双亲while(true){if(R[j]>R[i]) //若孩子较大swap(R[i],R[j]); //交换if(i==0)break; //到达根结点时结束j=i;i=(j-1)/2; //继续向上调整}}R[0]根结点R[1]R[2]…R[j]叶子结点R[i]21/43
一颗完全二叉树
初始堆435216013245例如,序列:(4,3,5,2,1,6),n=6从编号为n/2=3的结点开始,逐一筛选65546初始堆:(6,3,5,2,1,4)for(inti=n/2-1;i>=0;i--)
//从最后一个分支结点开始循环建立初始堆
siftDown(R,i,n-1);
//对R[i..n-1]进行筛选最大元素筛选步骤:siftDown(R,2,5)siftDown(R,1,5)siftDown(R,0,5)采用向下筛选方法22/43或者采用向上筛选方法从每个叶子结点调用自底向上的筛选算法来建立初始堆:for(intj=n/2;j<n-1;j++) //循环建立初始堆
siftUp(R,j);
//对R[j]进行筛选(R[j]为叶子结点)不如采用向下筛选方法好!?23/43635214013245
最大元素归位4,3,5,2,1,6最大元素6归位R[0]R[i]4352101324654R[0]R[i-1]再对R[0..i-1]的记录进行筛选24/43堆排序算法:voidHeapSort(vector<int>&R,intn) //堆排序{for(inti=n/2-1;i>=0;i--) //从最后一个分支结点开始循环建立初始堆
siftDown(R,i,n-1); //对R[i..n-1]进行筛选for(inti=n-1;i>0;i--) //进行n-1趟排序,每一趟后无序区元素个数减1{swap(R[0],R[i]); //将无序区中尾元素与R[0]交换,扩大有序区
siftDown(R,0,i-1); //对无序区R[0..i-1]继续筛选}}25/43
【例10.7】设待排序的表有10个记录,其关键字分别为{6,8,7,9,0,1,3,2,4,5}。说明采用堆排序方法进行排序的过程。排序序列:6,8,7,9,0,1,3,2,4,58952401376看成是一棵完全二叉树26/43调整成初始大根堆:8952401376调整完毕,成为一个大根堆987651324027/438602451379输出9(归位)从根结点筛选6420513780876513249第1趟排序28/43642051378输出8(归位)从根结点筛选642510370674513289第2趟排序其他各趟排序依此进行0123456789最终结果:29/43
对高度为h的堆,一次“筛选”所需进行的关键字比较的次数至多为2(h-1)。
调整“堆顶”n-1次,总共进行的关键字比较的次数不超过:
2(
log2(n-1)
+
log2(n-2)
+…+log22)<2n(
log2n
)
对n个关键字,建成高度为h(=
log2n+1)的堆,所需进行的关键字比较的次数不超过4n。3.算法分析堆排序的时间复杂度为O(nlogn)。空间复杂度为O(1),不稳定。30/43设有1000个无序的整数,希望用最快的速度挑选出其中前10个最大的元素,最好选用()排序方法。A.冒泡排序 B.简单选择排序
C.堆排序 D.直接插入排序n=1000,k=10冒泡排序的大致时间:kn堆排序的大致时间:4n+klog2n。示例31/43数据结构经典算法的启示简单选择排序算法堆排序算法利用了连续多次查找最大元素的特性优先队列就是采用堆实现的!32/4310.4.3堆数据结构线性表append(e):向堆中插入元素e。pop():删除堆顶元素并且返回该元素。gettop():取除堆顶元素。empty():判断堆是否为空。用R[0..n-1]存放一个堆,即(R,n)33/43定义大根堆类Heap:template<typenameT>classHeap
//堆数据结构的实现(默认大根堆){intn;
//堆中元素个数
vector<T>R;
//用R[0..n-1]存放堆中元素public:Heap():n(0){} //构造函数34/43voidsiftDown(intlow,inthigh) //R[low..high]的自顶向下筛选{inti=low;intj=2*i+1; //R[j]是R[i]的左孩子Ttmp=R[i]; //tmp临时保存根结点while(j<=high) //只对R[low..high]的元素进行筛选{if(j<high&&R[j]<R[j+1])j++; //若右孩子较大,把j指向右孩子if(tmp<R[j]) //tmp的孩子较大{R[i]=R[j]; //将R[j]调整到双亲位置上i=j;j=2*i+1; //修改i和j值,以便继续向下筛选}elsebreak; //若孩子较小,则筛选结束}R[i]=tmp; //原根结点放入最终位置}35/43voidsiftUp(intj) //自底向上筛选:从叶子结点j向上筛选{inti=(j-1)/2; //i指向R[j]的双亲while(true){if(R[i]<R[j]) //若孩子较大,则交换swap(R[i],R[j]);if(i==0)break; //到达根结点时结束j=i;i=(j-1)/2; //继续向上调整}}
//堆的基本运算算法};36/431.插入运算算法设计85632(a)一个大根堆85632(b)末尾添加1010810632(c)10与双亲交换5108632(d
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 《特种设备安全风险分级管控和隐患排查治理规范》
- 小儿传染病的预防和护理
- 2025年河北省辛集市数学三年级第二学期期中教学质量检测模拟试题含答案解析
- 2026 ACC-AHA血脂异常管理指南解读
- 直肠癌术后放疗护理查房
- 手术智慧医疗系统建设规范
- 2025年河北省保定市蠡县数学四年级第二学期期末学业质量监测试题(含答案)
- 概论期末综合试题及答案
- 4天培训就上养老护理实操考试?视频课实操演示速存
- DB45T 2936-2024 儿童康复机构社会工作服务规范
- 2026法检系统书记员招聘考试(书记员知识 综合知识 行测 申论)历年参考题库含答案详解3卷
- 新版(2026秋新版)部编版语文九年级上册教学计划合集
- T CCIAT 0112‑2026 灌注桩缺陷修复技术标准(征求意见稿)
- 成都市市场监督管理局所属事业单位2026年公开招聘编制外工作人员(34人)笔试备考试题及答案详解
- Unit 1 课时1 Section A 1a-1d(教学设计)英语新教材人教版九年级上册
- 2026年新教材人教PEP版五年级上册英语Unit 1 Different friends教学设计
- 产20万方混凝土加气块生产线项目可行性研究报告模板-备案审批
- 大健康加盟合同范本
- 《装配式污水处理设施设计建设标准》
- 2026年国网四川省电力公司提前批校园招聘笔试历年难易错考点试卷带答案解析
- 经济师考试运输经济专业知识和实务(初级)梳理要点详解(2026年)
评论
0/150
提交评论