漫画算法-小灰的算法之旅(11)

文章目录

  • 漫画算法-小灰的算法之旅(11)
    • 1. 什么是二叉堆
      • 什么是最大堆?
      • 什么是最小堆?
    • 2. 二叉堆堆自我调整
      • 插入节点
      • 删除节点
      • 构建二叉堆
      • 时间复杂度
    • 3. 二叉堆的代码实现
      • 代码实现

1. 什么是二叉堆

二叉堆:本质上是一种完全二叉树,它分两个类型。

  • 最大堆
  • 最小堆

什么是最大堆?

最大堆:最大堆的任何一个父节点的值,都大于或等于它左、右孩子节点的值。

什么是最小堆?

最小堆:最小堆的任何一个父节点的值,都小于或等于它左、右孩子节点的值。

二叉堆的根节点叫作堆顶。最大堆和最小堆堆特点决定了:最大堆的堆顶是整个堆中的最大元素;最小堆的堆顶是整个堆中的最小元素

2. 二叉堆堆自我调整

对于二叉堆,有如下几种操作:

  • 插入节点
  • 删除节点
  • 构建二叉堆

这几种操作都是基于堆的自我调整。所谓堆的自我调整,就是把一个不符合堆性质的完全二叉树,调整为一个堆。以最小堆为例,讲解二叉堆事如何进行自我调整的。

插入节点

  1. 二叉堆插入节点时,插入位置是完全二叉树的最后一个位置。例如插入一个新节点,值为0.
  2. 此时,新节点的父节点5比0大,显然不符合最小堆的性质。于是让新节点**“上浮”**,和父节点交换位置。
  3. 继续用节点0和父节点3做比较,因为0小于3,则让新节点继续**“上浮”**。
  4. 继续比较,最终新节点0**“上浮”**,到了堆顶位置。

删除节点

二叉堆删除节点的过程和插入节点的过程正好相反,所删除的是处于堆顶的节点。例如删除最小堆的堆顶节点1.

此时,为了继续维持完全二叉树的结构,我们把堆堆最后一个节点10临时不到原本堆顶顶的位置。

接下来,让暂处堆顶位置的节点10和它的左、右孩子进行比较,如果左、右孩子节点中最小的一个(显然是节点2)比节点10小,那么让节点10**“下沉”**。

继续让节点10和它的左、右孩子做比较,左、右孩子中最小的是节点7,由于10大于7,让节点10继续**“下沉”**。

这样一来,二叉堆重新得到了调整。

构建二叉堆

构建二叉堆,也就是把一个无序的完全二叉树调整为二叉堆,本质上就是让所有非叶子节点依次“下沉”

下面举一个无序完全二叉树的例子,如下图所示。

首先,从最后一个非叶子节点开始,也就是从节点10开始。如果节点10大于它左、右孩子节点中最小的一个,则节点10”下沉“。

接下来轮到节点3,如果节点3大于它左、右孩子节点中最小的一个,则节点3“下沉”。

然后轮到节点1,如果节点1大于它左、右孩子节点中最小的一个,则节点1“下沉”。事实上节点1小于它的左、右孩子,因此不用改变。

接下来轮到节点7,如果节点7大于它左、右孩子节点中最小的一个,则节点7“下沉”。

节点7继续比较,继续“下沉”。

经过上述几轮比较和“下沉”操作,最终每一个节点都小于它的左、右孩子节点,一个无序的完全二叉树就被构建成了一个最小堆。

时间复杂度

插入节点:时间复杂度是O(logn);是单一节点的"上浮",平均交换次数都是堆高度的一半。 空间复杂度O(n)

删除节点:时间复杂度是O(logn);删除操作是针对单节点的"下沉",平均交换次数都是堆高度的一半。空间复杂度O(n)

3. 二叉堆的代码实现

二叉堆虽然是一个完全二叉树,但它的存储方式并不是链式存储,而是顺序存储

因此,二叉堆的所有节点都存储在数组中。

在数组中,在没有左、右指针的情况下,如何定位一个父节点的左孩子和右孩子呢?

如上图所示,采用数组下标来计算。

假设父节点的下标是parent,那么它的左孩子下标就是2xparent+1;右孩子下标就是2xparent+2.

示例中,节点6包含9和10两个孩子节点,节点6在数组中的下标是3,节点9在数组中的下标是7,节点10在数组的下标是8.

7=3x2+1;

8=3x2+2;

代码实现

/**
* “上浮”调整
* param array. 待调整的堆
*/
public static void upAdjust(int[] array){int childIndex=array.length-1;int parentIndex=(childIndex-1)/2;// temp保存插入的叶子节点值,用于最后的赋值int temp=array[childIndex];while(childIndex >0 && temp< array[parentIndex]){// 无须真正交换,单向赋值即可array[childIndex]=array[parentIndex];childIndex=parentIndex;parentIndex=(parentIndex-1)/2;}array[childIndex]=temp;
}/**
* “下沉”调整
* param array   待调整的堆
* param parentIndex 要“下沉”的父节点
* param length 堆的有效大小
*/
public static void downAdjust(int[] array, int parentIndex,int length){// temp保存父节点值,用于最后的赋值int temp =array[parentIndex];int childIndex=2*parentIndex+1;while(childIndex<length){//如果有右孩子,且右孩子小于左孩子的值,则定位到右孩子if(childIndex+1<length && array[childIndex+1]<array[childIndex]){childIndex++;}//如果父节点小于任何一个孩子的值,则直接跳出if(temp<=array[childIndex]){break;}//无须真正交换,单向赋值即可array[parentIndex]=array[childIndex];parentIndex=childIndex;childIndex=2*childIndex+1;}array[parentIndex]=temp;
}/**
* 构建堆
* param  array 待调整的堆
*/
public static void buildHeap(int[] array){// 从最后一个非叶子节点开始,依次做"下沉"调整for(int i=(array.length-2)/2;i>=0;i--){downAdjust(array,i,array.length);}
}public static void main(String[] args){int[] array=new int[]{1,3,2,6,5,7,8,9,10,0};upAdjust(array);System.out.println(Arrays.toString(array));array=new int[]{7,1,3,10,5,2,8,9,6};buildHeap(array);System.out.println(Arrays.toString(array));
}

二叉堆的用处?

二叉堆是实现堆排序以及优先队列的基础。

漫画算法-学习笔记(11)相关推荐

  1. 漫画算法-学习笔记(17)

    漫画算法-小灰的算法之旅(17) 文章目录 漫画算法-小灰的算法之旅(17) 1. 什么是桶排序 实现步骤 代码实现 总结 1. 什么是桶排序 桶排序: 是一种线性时间的排序算法,类似于计数排序所创建 ...

  2. 漫画算法-学习笔记(10)

    漫画算法-小灰的算法之旅(10) 文章目录 漫画算法-小灰的算法之旅(10) 二叉树的广度优先遍历 二叉树的层序遍历 代码实现 时间复杂度 二叉树的广度优先遍历 如果说深度优先遍历是在一个方向上&qu ...

  3. 漫画算法-学习笔记(02)

    漫画算法-小灰的算法之旅(02) 文章目录 漫画算法-小灰的算法之旅(02) @[toc] 1. 什么是数组 2. 数组的基本操作 读取元素 更新元素 插入元素 删除元素 3. 数组的优势和劣势 1. ...

  4. 点云学习笔记11——VoxelNet算法+代码运行

    点云学习笔记11--VoxelNet算法+代码运行 一.算法分析 摘要 介绍 相关工作 1.2. 贡献 2.VoxelNet 2.1.特征学习网络 2.1.1 特征学习网络 二.代码复现 2.1.环境 ...

  5. Hadoop学习笔记—11.MapReduce中的排序和分组

    Hadoop学习笔记-11.MapReduce中的排序和分组 一.写在之前的 1.1 回顾Map阶段四大步骤 首先,我们回顾一下在MapReduce中,排序和分组在哪里被执行: 从上图中可以清楚地看出 ...

  6. matlab中x从0到5不含0,关于MATLAB的数学建模算法学习笔记

    关于MATLAB的数学建模算法学习笔记 目录 线性规划中应用: (3) 非线性规划: (3) 指派问题;投资问题:(0-1问题) (3) 1)应用fmincon命令语句 (3) 2)应用指令函数:bi ...

  7. LMS与RLS算法学习笔记

    LMS与RLS算法学习笔记 一. 研究目的 1.1最陡下降法理论 1.2$LMS$算法 1.3$RLS$算法 1.4研究目标 二.代码解析 三.结果 实现代码点击 这里下载 一. 研究目的 1.1最陡 ...

  8. 数学建模算法学习笔记

    数学建模算法学习笔记 作为建模Man学习数学建模时做的笔记 参考文献: <数学建模姜启源第四版> 网上搜罗来的各种资料,侵删 1.线性预测 levinson durbin算法,自相关什么的 ...

  9. 数据结构与算法 学习笔记(5):字符串

    数据结构与算法 学习笔记(5)- 字符串 本次笔记记录了LeetCode中关于字符串的一些问题,并给出了相应的思路说明和代码.题目编号与LeetCode对应,方便查找. 题目1:LeetCode 13 ...

最新文章

  1. Win10系统如何在防火墙里开放端口
  2. hive数据导入导出
  3. 阿里不让多表join?我偏要!
  4. 用MPLAB IDE编程时,软件总是弹出一个窗口提示: “the extended cpu mode configuration bit is enabled,but the program that
  5. AlphaGo之父哈萨比斯: 先解决智能 再用智能解决一切
  6. 3、构建bass服务及model
  7. 10个相似图片搜索以图找图的网站
  8. 计算机设计学校,计算机设计制作大赛
  9. CentOS 7 更换 yum 源
  10. ASP.NET 2.0 本地化功能:本地化 Web 应用程序的新方法
  11. python pip3 pip_Python:pip 和pip3的区别
  12. 《重来》值得你多看几遍
  13. 百面机器学习—11.集成学习(GBDT、XGBoost)面试问题总结
  14. 百度地图SDK集成定位,卫星地图
  15. 读书笔记(平凡的世界)
  16. Flutter HellowWord
  17. 程序员对私密聊天的乱想
  18. 利用Arcgis制作图像分割数据集
  19. JZOJ7月28日提高组反思
  20. Error connecting to the target: (Error -6305) PRSC module failed to write to to a register

热门文章

  1. 只需4步实现批量删除音视频的片头片尾
  2. 什么是PCB钢网?有什么做用
  3. kali linux攻击靶机win2K3实验------FTP匿名登录漏洞
  4. Flink、Iceberg和Hive的Catalog比较研究
  5. php qq钱包扫码接口,php最新版qq钱包扫码支付源码
  6. 鹏城深圳,2年后端腼腆小伙四面轻松拿下offer
  7. 相干波和杨氏双缝实验(大学物理笔记)
  8. python matplotlib 条形图的填充效果
  9. DNA 16. SCI 文章研究表型与基因型之间的关系工具(TASSEL)
  10. 计算机取证与司法鉴定基础知识