​经典算法09 堆排序

活动地址:CSDN21天学习挑战赛

*学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩;迟一天就多一天平庸的困扰。

简介

堆排序和简单选择排序一样属于选择排序

简单排序:每一趟在待排序的元素中选取关键字最小(或最大)的元素加入有序子序列

堆排序:每一趟将堆顶元素加入有序子序列(与待排序序列中的最后一个元素交换)并将待排序元素序列再次调整为大根堆(小元素不断“下坠”)

堆排序基于一个叫做堆的数据结构,所以我们先看什么是堆

定义:

若n个关键字序列L[1…n〕 满足下面某一条性质,则称为堆 (Heap)
①若满足:L(i)≥L(2i)且L≥l(2i+1) (1≤i≤n/2)—— 大根堆(大顶堆)
②若满足:L(i)≤L(2i)且L(i)≤L(2i+1) (1≤i ≤n/2)——小根堆(小顶堆)

可以结合完全二叉树的顺序存储来理解,即大根堆位完全二叉树中,根大于等于左和右的情况,小根堆位根小于等于左右节点情况,如下图所示
(图片来自王道考研)

大根堆

在我们知道了堆的概念之后,我们所需要做的就是对于所给出的初始序列,建立大根堆,即把所有非终端节点都检查一遍,是否满足大根堆的要求,如果不满足,则进行调整

分析:

给定初始序列,在顺序存储的完全二叉树中,非终端节点编号i<=[n/2]
(图片来自王道考研)

首先,先处理四号节点,,检查当前节点是否满足根>=左、右,若不满足,将当前节点与更大一个孩子互换,他只有一个孩子即和31进行互换

接着看三号节点,孩子的下标为2i,2i+1即6和7,78大于67但小于87,不符合大根堆特性,即78和87互换
(图片来自王道考研)

接下来处理二号节点,17小于32,也小于45,我们选择更大的45与17互换,如果换32,45大于32,不符合大根堆的特性
(图片来自王道考研)

最后处理一号节点,87更大,所以互换
(图片来自王道考研)

此时问题发生了,53下落以后,导致下一层的子树不符合大根堆的要求,此时我们需要继续调整,是53和78互换
(图片来自王道考研)

##代码实现

//建立大根堆
void BuildMaxHeap(int A[], int len){for(int i=len/2;i>0;i--)
HeadAdjust (A, i, len); //从后往前调整所有非终端结点
}
//将以 k 为根的子树调整为大根堆
void HeadAdjust(int All, int k, int len){A[0]=A[k]; //A[0]暂存子树的根结点
for(int i=2*k;i<=len; i*=2){ //取key较大的子结点向下筛选
if(i<len&&A[i]<A[i+1])
i++;          //取key较大的子结点的下标
if(A[0]>=A[i])
break; //筛选结束
else{A[k]=A[i]:     //将Ard]调整到双亲结点上
k=i;       //修改k值,以便继续向下筛选
}
A[k]=A[0]: //被筛选结点的值放入最终位置
}

##基于大根堆进行排序

堆排序:每一趟将堆顶元素加入有序子序列(与待排序序列中的最后一个元素交换)

分析:

基于上述,我们建立了大根堆如下图所示
(图片来自王道考研)

我们需要将09和87进行交换,87换到了末尾,87不需要进行变动了

(图片来自王道考研)

此时09到了堆顶,上面的一部分已经不是一个大根堆了,所以我们需要对09进行下坠,09的右孩子大,所以和78进行互换,再和65进行互换

(图片来自王道考研)

此时,上面部分又成了大根堆,和上面一样,将堆顶的元素和末尾的元素进行交换
(图片来自王道考研)

此时53到了堆顶,又不满足大根堆的特性,所以继续上述的操作,将剩余部分变成大根堆
(图片来自王道考研)

第三趟,堆顶元素65和堆底元素09进行互换,09继续下坠形成大根堆
(图片来自王道考研)

第四趟,堆顶元素53和堆底元素17进行互换,17继续下坠形成大根堆
(图片来自王道考研)

第五趟,堆顶元素45和堆底元素17进行互换,17继续下坠形成大根堆
(图片来自王道考研)

第六趟,堆顶元素32和堆底元素09进行互换,09继续下坠形成大根堆
(图片来自王道考研)

第七趟,堆顶元素17和堆底元素09进行互换,此时已经完成,不需要进行调整了
(图片来自王道考研)

对于n个元素的序列,我们进行了n-1趟的处理,得到递增的序列

如果使用小根堆,则得到递减的序列

基于大根堆进行排序(代码)

//建立大根堆
void BuildMaxHeap(int A[], int len)//将以 k 为根的子树调整为大根堆
void HeadAdjust (int A[],int k, int len)//堆排序的完整逻辑
void HeapSort (int A[], int len){BuildMaxHeap (A, len);      //初始建堆
for(int i=len;i>1;i--){     //n-1趟的交换和建堆过程
swap(A[i],A[1]) ;                   //堆顶元素和堆底元素交换
HeadAdjust (A,1, i-1) ; //把剩余的待排序元素整理成堆
}
}

算法效率分析:

结论: 一个结点,每“下坠”一层,最多只需对比关键宇2次
若树高为h,某结点在第i层,则将这个结点向下调整最多只需要“下坠”h-i层,关键字对比次数不超过 2(h-i)
(图片来自王道考研)

故建堆的过程,关键字对比次数不超过4n,建堆时间复杂度=O(n)
(图片来自王道考研)

空间复杂度=O(1)

稳定性:不稳定

总结:
(图片来自王道考研)

​经典算法09 堆排序相关推荐

  1. 白话经典算法系列之七 堆与堆排序

     堆排序与高速排序,归并排序一样都是时间复杂度为O(N*logN)的几种常见排序方法.学习堆排序前,先解说下什么是数据结构中的二叉堆. 二叉堆的定义 二叉堆是全然二叉树或者是近似全然二叉树. 二叉堆满 ...

  2. 十大经典排序算法之堆排序(Java代码实现)

    算法原理 堆排序(Heap Sort)是指利用堆这种数据结构所设计的一种排序算法.堆积是一个近视完全二叉树的结构,并同时满足堆积的性质:即子节点的键值或索引总是小于(或者大于)它的父节点.堆排序可以说 ...

  3. 十大经典算法总结(JavaScript描述)

    前言 读者自行尝试可以想看源码戳这,博主在github建了个库,欢迎star.读者可以Clone下来本地尝试.此博文配合源码体验更棒哦~~~ 个人博客:Damonare的个人博客 原文地址:十大经典算 ...

  4. 前端笔试常考设计模式,操作系统,数据结构,ACM模板,经典算法,正则表达式,常用方法

    考试时允许使用草稿纸,请提前准备纸笔.考试过程中允许上厕所等短暂离开,但请控制离开时间 笔试得分60%一般通过,面试答对80%才能通过 合集:2023年最全前端面试题考点HTML5+CSS3+JS+V ...

  5. 经典算法书籍推荐以及算法书排行【算法四库全书】

    经典算法书籍推荐以及算法书排行[算法四库全书] 作者:霞落满天   https://linuxstyle.blog.csdn.net/    https://blog.csdn.net/21aspne ...

  6. 【经典算法必读】图片分类系列之(一): 你真的了解图片分类(Image Classification)吗?...

    欢迎关注我的个人微信公众号:小纸屑 图片分类是机器学习经典问题,也是深度学习声名鹊起之作.正是2012年AlexNet在图片分类竞赛ImageNet出乎寻常的性能,使得深度学习一夜爆红,方有今天人工智 ...

  7. 常用排序算法之——堆排序

    堆与堆排序的原理,参考该博客: 白话经典算法系列之七 堆与堆排序 二叉堆是个完全二叉树,可以用一个数组来保存节点,不会浪费空间,能快速定位:本人用一个vector来代替数组,省去自己对内存的分配/重分 ...

  8. 还在为数学建模的事发愁?带你一起来看看数模竞赛中必备的经典算法

    前言 数学建模比赛是本科生和研究生阶段最重要的比赛之一,包括全国大学生数学建模竞赛(俗称"国赛")和美国大学生数学建模竞赛(俗称"美赛").在这些比赛中取得好成 ...

  9. 数据结构经典算法集锦

    数据结构经典算法集锦 第2章 线性表 KMP算法 //获得next数组 void GetNext(char *t, int next[MAX]) {int i = 1, j = 0;next[1] = ...

最新文章

  1. 课堂作业03--淘宝网质量属性
  2. jQuery页面顶部下拉广告
  3. Linux shell利用sed如何批量更改文件名详解
  4. 使用order by排序判断返回结果的列数,order by排序判断字段数原理详解
  5. Yii2 使用 .env 来配置项目环境变量
  6. 斐讯K2 刷华硕固件
  7. ARX二次开发 遍历删除所有的约束
  8. java数据结构与算法基础(二)-排序
  9. 网红神盾七号重疾险再创新高,自带住院津贴,还能赔两次!
  10. 如何设置默认浏览器?快速学会,简单易懂
  11. 不可逆加密算法MD5 SHA与可逆加密算法Base64
  12. 基于ZigBee的家居控制系统的设计与应用
  13. 雅思英语作文计算机和历史,关于computer的雅思写作范文
  14. 项目经验之谈--驱动崩溃分析之栈回溯技术与反汇编
  15. 最坏的不是面试被拒,而是没面试机会,以面试官视角分析哪些简历至少能有面试机会
  16. opencv学习---计算图像的水平积分投影和垂直积分投影
  17. Lucene 索引文件之tvdtvxtvm
  18. django使用Q进行复杂查询
  19. linux写磁带软件,如何在Linux下安装磁带机
  20. 细说OA系统的繁荣发展

热门文章

  1. Codeforces--50B--Choosing Symbol Pairs
  2. 职场新人必看:如何应对职场难题?
  3. 被商业化「催熟」的B站
  4. 编程新手入门:初学编程的正确学习方法!快速提升你的学习效率
  5. Spring中经常用到的注解提交方式@Postmapping、@GetMapping、@PutMapping、DeleteMapping
  6. 蓝桥杯获奖经验分享,博主连续两届嵌入式组国一和国二
  7. 用管程解决生产者消费者问题
  8. 开源OA:手把手教你搭建OA办公系统(9)快速搭建企业门户
  9. 国内学历证书的类别有哪些?
  10. gensim---LDA---perplexity