文章目录

  • 一、二叉堆
  • 二、堆的自我调整
    • 1.插入节点
    • 2.删除节点
    • 3.构建二叉堆
  • 三、堆的实现
  • 四、LeetCode

一、二叉堆

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

  1. 最大堆:最大堆任何一个父节点的值,都大于等于它左右孩子节点的值。
  2. 最小堆:最小堆任何一个父节点的值,都小于等于它左右孩子节点的值。
      二叉堆的根节点叫做堆顶。最大堆和最小堆的特点决定了在最大堆的堆顶是整个堆中的最大元素;最小堆的堆顶是整个堆的最小元素。

二、堆的自我调整

1.插入节点

  下面以最小堆为例,看看二叉堆是如何进行调整的?

如图所示,在二叉堆中插入节点0,节点0与节点5不满足二叉堆的结构,所以节点0与节点5进行交换;节点0与节点3不满足二叉堆的结构,所以节点0与节点3进行交换,同时,交换后看节点3与节点5是否满足二叉树的结构,满足!节点0与节点1不满足二叉树的结构,两者进行交换,同时,同理看节点1与节点3是否满足二叉树的结构。

主要原则:

插入节点与父节点是否满足二叉堆的结构,如果不满足,则插入节点向上调整,父节点向下调整。

2.删除节点

  删除节点即从堆中pop节点,一般是pop堆顶。下面以最小堆为例,展示二叉堆是如何删除节点的?

  当我们删除最小堆的堆顶(并不是完全删除,而是替换到最后面)

如图所示,先把堆顶节点1与最后面的叶子节点10交换。然后看节点10是否满足二叉堆的结构,如果不满足,则向下调整,节点10与小的叶子节点2进行交换(如果与叶子节点3进行交换,仍然不会满足二叉堆结构),节点10仍然不满足最小堆的定义,与叶子节点7进行交换。

3.构建二叉堆

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

  • 自下而上
  • 自上而下


下面叙述自下而上的方式将上述无序二叉树调整成最小堆:

首先,节点6与节点10交换,节点2与节点3进行交换,由于节点5与节点2在原二叉树中为叶子节点,所以无需在向下调整。节点1与节点7交换,节点7向下调整,节点7与节点5交换,最小二叉堆建立完毕!

三、堆的实现

  二叉堆虽然是一颗完全二叉树,但是它的存储方式并不是链式存储,而是顺序存储。换句话说,二叉堆的所有节点都存储在数组中。
  那么,如何来定位孩子节点的父节点或者父节点的孩子节点呢?

  二叉堆可以转化成数组。数组也可以转化成二叉堆。数组中孩子节点与父节点的索引关系如下:

如果父节点的索引为n,两个子节点的索引分别为2n+1,2n+2。
如上图所示,节点6,9,10的索引分别为3,7,8.
7 = 2×3 + 1
8 = 2×3 + 2
如果已知子结点索引,(子节点索引 - 1)/2再向下取整。

四、LeetCode

  215.在未排序的数组中找到第k个最大的元素(需要找的是数组排序后第k个最大的元素)

输入:[3,2,1,5,6,4]和k
输出:5

class Solution():def findKthLarget(self, nums, k):self._k = kreturn self.heap_sort(nums)def heap_sort(self, nums):"""堆排序将根节点取出与最后一位做对调,对前面len-1个节点继续进行堆调整过程:param nums: 数组:return:"""self.build_max_heap(nums)print(nums)cnt = 0# 调整后列表的第一个元素就是这个列表中最大的元素,# 将其与最后一个元素交换,然后将剩余的列表再递归的调整为最大堆for i in range(len(nums) - 1, -1, -1):nums[0], nums[i] = nums[i], nums[0]cnt += 1if cnt == self._k:return nums[i]self.max_heapify(nums, i, 0)def build_max_heap(self, nums):"""构建最大堆:param nums: 数组:return: 最大堆"""length = len(nums)for i in range((length - 2) // 2, -1, -1):  # 自底向上建堆self.max_heapify(nums, length, i)def max_heapify(self, nums, length, root):'''调整列表中的元素并保证以root为根的堆是一个大根堆给定某个节点的下标root,这个节点的父节点、左子节点、右子节点的下标都可以被计算出来。索引从0开始时父节点:(root-1)//2左子节点:2*root + 1右子节点:2*root + 2  即:左子节点 + 1'''left = 2 * root + 1right = left + 1larger = rootif left < length and nums[larger] < nums[left]:larger = leftif right < length and nums[larger] < nums[right]:larger = right# larger的值等于左节点或者右节点的值时,需要做堆调整if larger != root:nums[larger], nums[root] = nums[root], nums[larger]# 递归的对子树做调整self.max_heapify(nums, length, larger)def main():nums = [3,2,1,5,6,4]k = 2s = Solution()kth_element = s.findKthLarget(nums, k)print('数组中第%d个最大元素为%d' % (k, kth_element))if __name__ == '__main__':main()
[6, 5, 4, 3, 2, 1]
数组中第2个最大元素为5

LeetCode—2.堆排序算法相关推荐

  1. 技术图文:如何在leetcode上进行算法刻意练习?

    背景 众所周知,通过刻意练习高质量的题目可以加深我们对计算机科学中经典数据结构的深刻理解,从而可以快速用合适的数据结构去解决现实中的问题.而LeetCode就是一个收集了各大IT公司的笔试面试题的在线 ...

  2. 上标3下标6算法_图解堆排序算法

    堆排序定义 一般来说,算法就像数学公式,前人经过不断优化和验证得到有规律性的公式留给后人使用,当然也会交给后人验证的思路.那么堆排序算法就是这样,它有基本固定的定义如下: 1.将数组构建为一颗有规则的 ...

  3. 9个元素换6次达到排序序列_一文带你读懂排序算法(三):堆排序算法

    国庆节快乐~点击上方文字关注我们哦 堆是一种特殊的树形数据结构,其每一个结点都有一个值,通常提到的堆都是指一棵完全二叉树,根结点的值小于(或大于)两个子结点的值,同时,根结点的两个子树也分别是一个堆. ...

  4. 精通八大排序算法系列:二、堆排序算法

    精通八大排序算法系列:二.堆排序算法 作者:July .二零一一年二月二十日 本文参考:Introduction To Algorithms,second edition. ------------- ...

  5. 堆排序时间复杂度_堆排序算法

    堆排序是指利用堆积树这种数据结构所设计的一种排序算法,它是选择排序的一种.可以利用数组的特点快速定位指定索引的元素.堆是一个优先级队列,对于大顶堆而言,堆顶元素的权值最大.将待排序的数组建堆,然后不断 ...

  6. 【java排序】 归并排序算法、堆排序算法

    一.归并排序算法 基本思想: 归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的.然后再把有序子序列合并为整体有序序列. 归并 ...

  7. leetcode旋转数组 c语言,leetcode explore 初级算法第三题,旋转数组代码实现

    leetcode explore 初级算法第三题,旋转数组代码实现.原题链接: 题目分析 因为题目不是很长,这里把题目贴出来: 给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数. ...

  8. JavaScript实现heapsort堆排序算法(附完整源码)

    JavaScript实现heapsort堆排序算法(附完整源码) Heap.js完整源代码 MinHeap.js完整源代码 Comparator.js完整源代码 Sort.js完整源代码 HeapSo ...

  9. 经典排序算法(7)——堆排序算法详解

    堆排序(Heap sort)是指利用堆(最大堆.最小堆)这种数据结构所设计的一种排序算法.堆是一个完全二叉树的结构,并同时满足如下性质:即子结点的键值或索引总是小于(或者大于)它的父节点. 一.算法基 ...

  10. java 实现 堆排序算法_C程序实现堆排序算法

    java 实现 堆排序算法 Heap Sort is a comparison-based sorting algorithm that makes use of a different data s ...

最新文章

  1. Android SurfaceView 黑背景的处理方法
  2. [C#基础知识系列]专题十:全面解析可空类型
  3. Vue会了吗?来认识一下React吧(上)
  4. LeetCode 31 下一个排列
  5. c语言错误封装,C语言实现的封装,继承,多态
  6. 最优化知识笔记整理汇总
  7. 计算机备份u盘,如何备份电脑系统到u盘
  8. 《Adobe Photoshop CS5中文版经典教程(全彩版)》—第1课1.1节开始在Adobe Photoshop中工作...
  9. ubuntu下搜狗拼音输入法不见了
  10. 领导人怎样带领好团队
  11. wow插件入门资源整理
  12. 计算机网络怎么查看连接打印机驱动,怎么检查电脑中是否已成功连接网络打印机...
  13. 工具用法有道云笔记: Mac和Windows上有道云笔记更换背景方法--202205更新
  14. python识别屏幕图像后点击操作_Python学习笔记——用GUI自动化控制键盘和鼠标
  15. 广告机解决方案/安防监控网络方案/医疗方案
  16. HTML表格简单的创建与制作
  17. [面试笔试整理1]:深度学习机器学习面试问题准备(必会)
  18. 阿里云服务器ECS实例规格性能区别及选择攻略
  19. 查看Linux发行版名称及版本号
  20. 领袖的七个非常重要的根性-余世维

热门文章

  1. hibernate 批量插入 Batch
  2. Hadoop程序打印调试
  3. 关于pycharm安装出现的interpreter field is empty,无法创建项目存储位置
  4. Java课程设计-随机密码生成器
  5. Java Web 获取客户端真实IP
  6. 关于Location of the Android SDK has not been setup in the preferences的解决方法
  7. 使用HttpWebRequest自动更新客户端应用程序[转]
  8. iOS 25个性能优化/内存优化常用方法
  9. springboot系列二、springboot项目搭建
  10. MyBatis框架的使用及源码分析(三) 配置篇 Configuration