本篇的主旨是理解二叉堆结构,所以具体实现代码会留到第二篇讲解。

提到堆,其实Java中的优先队列PriorityQueue就是基于堆结构实现的;

而Java中的延迟队列DelayQueue里面就用到了PriorityQueue;

再比如kafka中基于时间轮TimingWheel实现的延时定时器, 同样离不开DelayQueue的配合。

这一切都和堆息息相关。

1 数组和树

堆其实就是一个数组结构, 如图

下面我们来点小魔法, 把数组变成树!

这个数组对应的树结构就是下面这样:

数组结构的下标和树结构的节点对应关系如下:

如果根节点对应的数组下标是0, 那么对于 i 节点,

左右子节点的位置为 2i +1和 2i+2;

i 节点的父节点位置为 ( i-1)/2;

简单理解了数组和树之后,下面我们进入正题。

2 最小堆结构

首先我们来一个乱序的数组:

这个数组对应的树结构:

这只是一个简单的树结构, 还不是堆, 堆结构是下面这样子的:

这是一个最小堆, 可以看到根节点, 也就是堆顶, 是数组中最小的那个元素。

同时,整一个大的堆, 是由很多个小的堆组成的。

比如左边这个小堆, 也是符合最小堆的定义, 堆顶的4是三个数字中最小的:

右边的小堆也是一个最小堆, 堆顶的3是最小的数字:

那么怎么把一颗树变成一个最小二叉堆呢?

3 插入和上浮

最简单的办法, 就是新建一个空的堆(一个空的数组), 把乱序数组中的所有元素依次插入到堆中, 在这个过程中堆会通过上浮来调整自身的结构。

下面我们来解析下上面的动画:

首先, 是往堆中 插入 元素, 比如往下面的这个最小堆中插入数字1:

当1插入数组尾部之后, 就处于树的最后一个叶子节点的位置:

然后通过 上浮 操作, 把A移到合适的位置。

简单来说就是先和A的父节点比较, 如果比父节点小, 就和父节点交换位置, 这个过程一直持续到A的父节点比A小, 或者A已经到达堆顶的位置。

下面继续数字1这个例子, 当1插入数组尾部之后, 会和他的父节点8作比较:

1比父节点8小, 交换位置:

1再和他的父节点4作比较:

1比父节点4小, 交换位置后1到达堆顶, 形成了一个最小堆结构。

4 删除和下沉

接下来讲讲堆节点的删除, 这里的删除是指取出堆顶的节点。

我们把堆顶的元素取出后, 堆会把剩下的数字中最小的那个数字再次推到堆顶的位置。

仔细看动画,这里值得注意的是, 取出堆顶的元素, 并不是直接把堆顶的元素删除。什么意思呢?

在JavaScript中, 数组的pop操作就是把数组中最后一个元素删除; 而Java中的堆栈Stack也有pop操作, 同样是把最后一个元素移除。

而堆的 删除 操作, 也是基于pop操作来实现。这样做是为了维持完全二叉树的结构。

比如我们要把堆顶的1删除:

1. 先把根节点和最后一个节点交换位置, 也就是1和6交换位置;

此时堆顶不再是最小的数字,最小堆的特性被打破, 接下来我们要对堆顶的元素进行 下沉 操作, 把树结构重新调整为堆结构。

2. 先比较左右子节点大小,与最小节点交换位置 ;

3. 继续步骤2;

继续上面的例子,当1节点移除后,此时会先对堆顶6的左右子节点进行大小比较, 找出比较小的那个子节点,也就是右节点3:

然后, 节点6再和右节点3比较:

节点6下沉, 此时6已经是叶子节点了, 下沉操作结束, 可以看到此时整棵树已经重新变回了最小堆结构:

5 堆排序

有趣的是, 通过上面简单的【插入并上浮】 和 【删除并下沉】 , 我们就可以对乱序数组执行堆排序了。

下面对乱序数组进行堆排序:

堆化,插入并上浮:

删除并下沉:

排序完成后的数组:

最后对堆排序的总结就是:

1. 先把乱序数组堆化 (文中使用的是插入+上浮)

2. 再通过pop操作删除堆顶元素, 通过下沉调整堆结构

6 堆化 Heapify

平常的使用堆排序肯定不会再新建一个空的堆, 再把乱序数组的元素逐个插入堆中, 这样太浪费空间, 下一章我们来讲一下堆化。

7 色谱图

简单了解了堆排序后, 我们来看看16个元素进行堆排序后生成的色谱图

也有网友说这是大肠图, 感兴趣的可以看看这篇文章了解下【译】排序算法可视化之色谱图, 后面本公众号会开一个系列专门讲解这种有趣的静态可视化方法。

我们把这个图拆成两部分来看, 首先是左边部分

这就是堆排序的第一步, 堆乱序数组堆化的过程

再来看看右边部分

可以看到, 堆排序的第二步就是pop操作把堆顶元素移除, 图中也体现得非常清晰,先把堆顶元素移到尾部, 被移除的元素就相当于排好序了.

每次移除元素后, 都会对新的堆顶节点执行下沉操作, 也就是图中pop和pop之间的红框部分, 我们可以清晰地看到堆在自我调节的过程

排序结束之后, 由浅到深的颜色依次呈现在我们眼前!

温馨提示

文中的动画是基于d3.js制作而成。

作者:字节武装
链接:https://www.jianshu.com/p/d4cd1d54e5ef
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

数字能排序字符串不能排序_动图解说堆排序原理,让体育生也能看得明白相关推荐

  1. 数据结构排序算法实验报告_数据结构与算法-堆排序

    堆排序 堆排序是指利用堆这种数据结构所设计的一种排序算法.堆是一个近似完全二叉树的结构,并同时满足堆的性质:即子节点的键值或索引总是小于(或者大于)它的父节点,堆排序的时间复杂度为O(nlogn).( ...

  2. python字符串连接数字电视_【学习猿地】初识python脚本 #千万别看,我怕你控制不住...

    >编写python程序的文件,称为python的脚本或程序 >要求当前的python脚本的文件后缀名必须是.py #### pycharm使用注意 > 需要明确的知道你当前pycha ...

  3. 计算方位角_全站仪各方面应用的原理、操作及计算,看这篇就对了!

    来源:豆丁施工 版权归原作者所有 全站仪是什么? 全站仪,即全站型电子速测仪.它是随着计算机和电子测距技术的发展,近代电子科技与光学经纬仪结合的新一代既能测角又能测距的仪器,它是在电子经纬仪的基础上增 ...

  4. 全站仪和手机连接软件_全站仪各方面应用的原理、操作及计算,看这篇就对了!...

    来源:豆丁施工 版权归原作者所有 全站仪是什么? 全站仪,即全站型电子速测仪.它是随着计算机和电子测距技术的发展,近代电子科技与光学经纬仪结合的新一代既能测角又能测距的仪器,它是在电子经纬仪的基础上增 ...

  5. 全站仪和手机连接软件_全站仪各方面应用的原理、操作及计算,看这篇就对了...

    全站仪是什么? 全站仪,即全站型电子速测仪.它是随着计算机和电子测距技术的发展,近代电子科技与光学经纬仪结合的新一代既能测角又能测距的仪器,它是在电子经纬仪的基础上增加了电子测距的功能,使得仪器不仅能 ...

  6. js 中 中文、空格、数字、字符串混合排序

    最近有个需求,需要对后台的数组对象按照某个属性进行排序,属性值可能是 中文.字符串.数字.特殊字符.空字符串,网上大部分都只是针对某一个类型进行排序,在参考这篇博客的基础之上https://blog. ...

  7. 字母排序 字符串跟字符串比较大小 字符串跟数字比较大小

    两个字符比较返回的都是Boolean值 对于非数字进行比较 则会先转换为数字进行比较 所有包含NaN的比较返回值都为false 包括NaN==NaN 特殊情况 当两边都是字符串 不会转换为数字进行比较 ...

  8. Java对字符串中数字进行按自然顺序排序

    Java对字符串中数字进行按自然顺序排序 import java.util.Arrays;public class Test01 {public static void main(String[] a ...

  9. python字符串去重排序_python实现字符串转数字排序-女性时尚流行美容健康娱乐mv-ida网...

    女性时尚流行美容健康娱乐mv-ida网 mvida时尚娱乐网 首页 美容 护肤 化妆技巧 发型 服饰 健康 情感 美体 美食 娱乐 明星八卦 首页  > 高级搜索 python 取子 字符 串 ...

最新文章

  1. java父子表_数据库二维表转父子关系,java,stream,list
  2. ajaxfileupload返回结果undefined_Null amp; Undefined 简易对比
  3. 【Fiddler学习】Fiddler抓包HTTPS请求和手机抓包
  4. 修改anaconda3 jupyter notebook 默认路径
  5. AI:《DEEP LEARNING’S DIMINISHING RETURNS—深度学习的收益递减》翻译与解读
  6. 从零开始入门 K8s| K8s 的应用编排与管理
  7. 文件服务器和客户模式有什么区别,客户端和服务器端编程有什么区别?
  8. 对一个“世纪数学难题”的重新思考
  9. 数据结构实验之栈二:一般算术表达式转换成后缀式
  10. linux删除目录tmpab是什么意思_linux 下tmp目录文件怎么被删除的?
  11. VScode配置C语言环境 亲测 可用!!!
  12. 从零基础入门Tensorflow2.0 ----八、42. 自定义流程
  13. .text urlRewrite介绍
  14. 基于android的订餐系统 答辩ppt,外卖订餐系统答辩PPT
  15. (java毕业设计)基于java汽车租赁管理系统源码
  16. 小程序云开发(二) 上传图片到云服务器、上传图片并展示
  17. Ffmpeg实例,为视频添加一个循环播放的背景音乐(混声)
  18. 2022年北京购房攻略二 (城区交通篇)
  19. nodejs+vue基于决策树算法的大学生就业预测系统
  20. android做一个音乐播放器,制作一个简单的Android版的音乐播放器

热门文章

  1. mysql计算折纸_mysql数据库的创建和授权
  2. 三八妇女节可以应用的PSD分层模板
  3. 海报中应用广泛的书法(手写)字体素材
  4. UI素材干货|听说UI设计师更喜欢Sketch
  5. 巧妙布局的APP界面模板,让你的作品更有吸引力
  6. hashmap是有序还是无序_说实话,你要是看完这篇 HashMap ,和面试官扯皮真的就没问题了!
  7. Linux容器:cgroup,namespace原理与实现
  8. SMM - 系统管理模式,SMRAM
  9. i like share
  10. matlab条形图颜色矩阵,matlab中的条形图开关颜色