文章目录

  • 1、二叉堆
  • 2、一个例子
    • 2.1 生成完全二叉树:
    • 2.2、调整为小根堆
    • 2.3、插入元素
    • 2.4、取出堆顶元素
    • 2.5、Java代码
  • 3、画图工具

1、二叉堆


首先参考了一下→\rightarrow→什么是二叉堆? 此博客也是在看了这篇微信推文的基础上写的。

什么是二叉堆?

二叉堆本质上是一种完全二叉树,它分为两个类型:
1.最大堆
2.最小堆

什么是最大堆呢?最大堆任何一个父节点的值,都大于等于它左右孩子节点的值。

什么是最小堆呢?最小堆任何一个父节点的值,都小于等于它左右孩子节点的值。

二叉堆的根节点叫做堆顶

最大堆和最小堆的特点,决定了在最大堆的堆顶是整个堆中的最大元素;最小堆的堆顶是整个堆中的最小元素。

2、一个例子


一个二叉堆的操作大致有三种,
1. 调整堆
2. 插入元素
3. 取出堆顶元素

假设给我的一串数字是:【10 2 4 21 15 13 18 7 11】 ,即:

int[] a = new int[] {10,2,4,21,15,13,18,7,11};

下面过一遍堆的调整、插入和取出。提醒一点,向上调整只比较一次,向下调整比较两次。 下面会有提到。

2.1 生成完全二叉树:


对于任何一个序列,我们所需要做的是先把它当作一颗完全二叉树,就是下面这样子。

2.2、调整为小根堆


堆调整是向下调整, 从后往前依次调整每棵子树,每次调整时需要比较两次,子节点之间一次,较小的(对小根堆来说)子节点和根节点之间一次。

先在最后一颗子树上调整:


比较子节点。7更小一点。

于是721比较,发现721更小。调换两个节点的值。

往上,调整前一颗子树。比较子节点,1318比较,13小。13再与4比较,4小。于是此子树也不需要做调整。

再往上,还是无需调整。

再往上,2较小,210比较。这里我没提子节点之间的比较了,其实是有的,下面也都一样,省略了。不懂我说什么可以前翻一下下黄字处。

10换下来。同理,710比较。

7小。调整节点。

10小。至此小根堆就调整好了。

调整完后,输出的序列应为:【2 7 4 10 15 13 18 21 11】。

2.3、插入元素


插入是堆调整中唯一往上调整的一个环节, 刚才说了,往上调整只比较一次,因为插入时,堆已经调整好了,父节点一定是比子节点小的。任一向上调整环节,如果插入的节点小于父节点,交换两个节点,否则调整结束。

假设插入一个1。先把1插在完全二叉树的末尾,再依次向上调整调整。如果小于父节点,便与父节点交换,直到小于时停止。

1与15比较并调整。

1与7比较并调整。

1与2比较并调整。

插入完成。

插入1完成后的序列为:【1 2 4 10 7 13 18 21 11 15】。

2.4、取出堆顶元素


堆只能从堆顶取元素。对于小根堆,每次取出的元素就是最小的元素。方法就是用堆中最后一个元素,覆盖堆顶元素,然后去掉最后一个元素。再次从上往下调整。同样,每次调整比较两次

15覆盖1,并去掉15。

15比较小的子节点2小,所以向下调整。

15比较小的子节点7小,所以向下调整。因为已经被调整到了页节点上,所以停止。

取出小根堆堆顶元素后的序列为:【2 7 4 10 15 13 18 21 11 】。

2.5、Java代码


import java.rmi.dgc.*;
import javax.lang.model.element.*;class HeapOperator { //实现的是一个小根堆public static void Adjust(int a[]){int len = a.length;int[] b = new int[len];int FatherNodeNum = len / 2;if(len % 2 == 0){//如果数组a的长度为偶数if(a[len - 1] < a[FatherNodeNum - 1]){//父节点大于子节点int tmp = a[len - 1];a[len - 1] = a[FatherNodeNum - 1];a[FatherNodeNum - 1] = tmp;}--FatherNodeNum;}//下面的每个父节点都有两个子节点while (FatherNodeNum > 0) {int k = FatherNodeNum; //k一直跟着当前的节点,直到此节点被换到叶子结点上while (k <= len / 2) { //len/2 - 1是第一个叶节点的下标int lNode = 2 * k - 1; //左子节点下标int rNode = 2 * k; //右子节点下标if(a[lNode] <= a[rNode]){//如果左子节点小于等于右子节点if (a[lNode] < a[k - 1]) { //同时左子节点小于父节点int tmp = a[lNode];  a[lNode] = a[k - 1];a[k - 1] = tmp;k = 2 * k; //记下此节点是数组中第几个值}else { //如果父节点不小于最小的子节点的值 跳出循环break;}}else { //若右节点更小一点if (a[rNode] < a[k - 1]) { //如果右子节点小于父节点int tmp = a[rNode];a[rNode] = a[k - 1];a[k - 1] = tmp;k = 2 * k + 1; //记下此节点是数组中第几个值}else { //如果父节点不小于最小的子节点的值 跳出循环break;}}}--FatherNodeNum;}}public static int[] InsertNode(int a[],int m){//先实现的简单一点,假设a数组不为空int len = a.length + 1;int[] b = new int[len];System.arraycopy(a, 0, b, 0, len - 1); //将数组a的内容拷贝到b中b[len - 1] = m;//b数组的最后一个元素先赋值为mint k = len; //k-1就是新加入的节点的父节点while(k > 1){ //k为根节点的时候停下来if (b[k - 1] >= b[k/2 - 1]) { //若加入的节点不小于其父节点break; //直接跳出循环}else {//否则交换一下子节点和父节点的值int tmp = b[k - 1];b[k - 1] = b[k/2 - 1];b[k/2 - 1] =tmp; k = k/2;}}return b;}public static int[] FetchNode(int a[]){int len = a.length - 1;int[] b = new int[len];System.arraycopy(a, 0, b, 0, len); //把a数组的前len-1给赋给bb[0] = a[a.length - 1]; //去除a的最小元素,为保持树状,覆盖第一个元素int k = 1; //现在要把二叉堆从上到下调整while(k <= len / 2){ //k为叶节点的时候停下来int lNode = 2*k - 1; //左子节点的下标int rNode = 2*k; //右子节点的下标if(b[lNode] <= b[rNode]){if (b[lNode] < b[k - 1]) {int tmp = b[lNode];b[lNode] = b[k - 1];b[k - 1] = tmp;k = 2*k;}else {break; //当此节点不小于任何一个子节点的时候,他也会跳出循环}}else {if (b[rNode] < b[k - 1]) {int tmp = b[rNode];b[rNode] = b[k - 1];b[k - 1] = tmp;k = 2*k + 1;}else {break; //当此节点不小于任何一个子节点的时候,他也会跳出循环}}}return b;}public static void main(String[] args) {int[] a = new int[] {10,2,4,21,15,13,18,7,11};Adjust(a); //将其调整为小根堆int i = 0;System.out.print("调整过后的小根堆为:");while (i < 9) {System.out.print(a[i]+" ");++i;}System.out.print("\n");int[] b = new int[a.length + 1];b = InsertNode(a, 1); //在小根堆里面插入一个1i = 0;System.out.print("插入1后的小根堆为:");while (i < 10) {System.out.print(b[i]+" ");++i;}System.out.print("\n");int[] c = new int[a.length];c = FetchNode(b);i = 0;System.out.print("取出小根堆最小元素后的小根堆:");while (i < 9) {System.out.print(c[i]+" ");++i;}System.out.print("\n");}
}

运行结果:

调整过后的小根堆为:2 7 4 10 15 13 18 21 11
插入1后的小根堆为:1 2 4 10 7 13 18 21 11 15
取出小根堆最小元素后的小根堆:2 7 4 10 15 13 18 21 11

3、画图工具


写这篇博文主要是最近可能要用Java编程,所以提前练练手,但是又引发了我一直没有解决的问题。程序员画流程图一般都用什么工具? 我网上找了一下,最后集大家的智慧找到了draw.io 。这是一款在线画图软件,支持各种格式的导出,包括html、xml、PDF等等,也支持中文并且完全免费,这里我都是导出为png格式。下面给一张截图。

可能截图看不太清,想了解的可以自己再找找资料,试试看好不好用。

好了,老铁们,到这趴~~

Java实现的小根堆相关推荐

  1. 大根堆和小根堆的区别

    大根堆和小根堆的区别 文章转自:https://blog.csdn.net/weixin_37197708/article/details/79546535 堆的概念 堆实际上是一棵完全二叉树,其任何 ...

  2. Java 中的大根堆和小根堆

    小根堆和大根堆 完全二叉树:完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树而引出来的.对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应 ...

  3. java大根堆和小根堆

    java使用优先队列实现大顶堆和小顶堆,默认是小根堆,当然记不住默认也没有关系 小根堆创建 PriorityQueue<Integer> minHeap = new PriorityQue ...

  4. java 小根堆 排序_堆排序(java实现)

    堆排序就是用大根堆或者小根堆的节点都比左孩子 右孩子大(小)的特性  来构建有序序列. 名词解释: 大根堆:所有节点(n)都比他的左孩子(2n+1)与右孩子(2n+2)大的完全二叉树. 小根堆:所有节 ...

  5. 堆排序(小根堆)的简单实现(java)

    堆排序是一种树形选择排序方法,它的特点是:在排序过程中,将L[1...n]看成是一棵完全二叉树的顺序存储结构,利用完全二叉树中双亲结点和孩子结点之间的内在关系,在当前无序区中选择关键字最大(或最小)的 ...

  6. 小根堆java_小根堆的Java实现

    1. 堆 堆是完全二叉树的数组形式,由于堆没有指针指向,所以可以利用下标来模拟指向,假设 i 为父节点,那么 2i+1 为左孩子,2i+2 为右孩子.假设 i 为当前节点,那么 (i - 1) / 2 ...

  7. 哈夫曼编码之大根堆小根堆揭西县

    哈夫曼编码 根据数据出现的频率对数据进行编码,从而压缩原始数据. 例如对于一个文本文件,其中各种字符出现的次数如下: a : 10 b : 20 c : 40 d : 80 可以将每种字符转换成二进制 ...

  8. 前K个高频元素[小根堆和大根堆的使用]

    小根堆 前言 一.前K个高频元素 二.小根堆&大根堆 1.O(KlogN)大根堆 2.O(NlogK)小根堆 总结 参考文献 前言 当题目需要有序性时,果断排序,可二分快速寻找答案,或是利用有 ...

  9. c语言建立小根堆的算法,小根堆(Heap)的详细实现

    堆的介绍 Heap是一种数据结构具有以下的特点: 1)完全二叉树 2)heap中存储的值是偏序 Min-heap: 父节点的值小于或等于子节点的值 Max-heap: 父节点的值大于或等于子节点的值 ...

最新文章

  1. 在CentOS 7.7 x86_64上安装InfluxDB 1.8.0实录
  2. 日调用量超三十万亿,腾讯开源百万级服务发现和治理中心北极星
  3. GAN不只会造假:捕获数据中额外显著特征,提高表征学习可解释性
  4. putty network error:Connection refused 乱码
  5. Google AI 碾压集成电路设计专家,ASIC智能设计时代来了!
  6. 阿里巴巴2018年纳税516亿元,稳居行业第一名,大家怎么看?
  7. 通过官方查看springCloud,springBoot版本对应关系
  8. 人口增长模型_未来中国近一半人口将生活在20强城市,这是异想天开还是大势所趋?...
  9. 疫情下的国内云市场,正是大展拳脚的好时机!
  10. java逻辑运算符的使用
  11. c语言 sizeof(unsign),C语言基础知识
  12. msdev.exe 应用程序错误的解决方法
  13. 07版qq默认经典表情下载
  14. 100个模具设计常用基本知识,你懂得几个?设计师干货
  15. 如何成为微信小程序的开发者?
  16. 参观一家买过十年货的淘宝店是怎样的体验?——新魔术8000生产基地探秘
  17. 360漏洞修复网管版小软件不错
  18. 鸿蒙系统pc版 硬件要求,原神全平台配置要求 原神配置需求一览
  19. 如何从零开始写一个操作系统?
  20. Python学习Day3-高级数据类型

热门文章

  1. runnable、callable、consumer、supplier
  2. 人际间亲密关系可能呈现函数式变化
  3. 12个 Linux 命令的超级用法实例,超实用!
  4. Confluence 6 配置快速导航
  5. 输入汉字转自动转拼音 20378个词库
  6. 百度地图开发者使用教程
  7. 运维部奖励员工之大连游记
  8. 火车票能不能选座_12306 现在可以选座了,但这个选座可能和你想的不太一样
  9. 【问题处理】Word修改页边距后,目录没有右对齐
  10. Python脚本自动化备份飞塔,华为,思科等设备配置文件。