数据结构之堆详解

数据结构之堆详解

什么是堆?

堆(Heap)是一种特殊的树形数据结构。堆具有以下两个特点:

  1. 堆是一颗完全二叉树;
  2. 堆中每个节点的值都必须大于等于或小于等于其左右子节点的值,分别称作大根堆和小根堆。

上述的大根堆和小根堆其实是两种不同的堆的实现方式。对于大根堆,每个节点的值都比其左右子节点的值要大;小根堆则相反,每个节点的值都比其左右子节点的值要小。

堆的基本操作

插入元素

当我们在堆中插入一个元素的时候,需要满足以下几个步骤:

  1. 将新元素插入到堆的最后一个节点处;
  2. 将新元素向上调整至合适的位置,直到满足堆的性质为止。

具体的实现方式有两种,分别是“向上调整”(上滤)和“向下调整”(下滤)。这里我们只介绍向上调整的方式。

向上调整的方式如下:

  1. 在堆的最后插入一个新元素,令其为当前元素;
  2. 比较当前元素与其父节点,若当前元素小于其父节点,则交换当前元素和其父节点的位置;
  3. 重复第二步,直到当前元素不再小于其父节点或者已经到达堆顶。

示例:

我们以一个小根堆为例,初始堆为空,插入元素序列为3,1,5,2,4。

插入3后,堆如下所示(左图):

   3
  / \
 /   \
/     \

接着,我们插入1,此时1小于3,需要将其向上调整。

比较1和3,发现1小于3,交换1和3的位置。此时堆变成了下图的样子:

   1
  / \
 /   \
/     \
   3

现在再插入5,此时5大于1,不需要调整。

然后插入2,此时需要向上调整。

比较2和5,2小于5,交换2和5的位置得到下图:

   1
  / \
 /   \
/     \
   2   3
      /
     /
    5

最后插入4,不需要调整,最终的堆如下图所示:

   1
  / \
 /   \
/     \
   2   3
  / \
 /   \
4     5

删除元素

当我们从堆中删除一个元素的时候,需要满足以下几个步骤:

  1. 删除堆顶元素,并将堆的最后一个元素移到堆顶处。
  2. 将堆顶元素向下调整至合适的位置,直到满足堆的性质为止。

向下调整的方式如下:

  1. 令当前元素为堆顶元素,若当前元素没有左右子节点则终止操作;
  2. 比较当前元素与其左右子节点,若当前元素小于其左右子节点中的最小值,则与其左右子节点中的最小值交换位置;
  3. 重复第二步,直到当前元素小于其左右子节点或者没有左右子节点。

示例:

对于上面的例子,我们以小根堆为例,将堆顶元素3删除,得到下图:

   1
  / \
 /   \
/     \
   2   5
  /
 /
4

此时堆顶元素为1,需要向下调整。由于2小于5,我们选择与2交换位置,得到下图:

   1
  / \
 /   \
/     \
   4   5
  /
 /
2

最后进行一次向下调整即可。

堆的应用

堆的重要应用之一是排序算法,堆排序(Heap Sort)是一种基于堆实现的排序算法。堆还经常用于实现优先队列,认识和熟练掌握堆对于我们的编程能力提升非常有帮助。

结论

堆是一种很有用的数据结构,具有优秀的时间复杂度和空间复杂度。了解堆的基本操作和应用能够提升我们的编程能力,尤其对于算法和数据结构的学习更是非常重要。

以上就是数据结构之堆的详细攻略,希望您对此有所收获。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:数据结构之堆详解 - Python技术站

(0)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • java数据结构基础:稀疏数组

    Java数据结构基础:稀疏数组 在开发过程中,我们需要处理一些稀疏矩阵(大部分元素为0)的数据。这时候,使用稀疏数组是比较高效的方法。 什么是稀疏数组 稀疏数组是由很多元素值相同的元素组成,这些元素的值通常为0。而这些值不同时都存储在一个数组中会浪费很多内存空间。因此,我们使用稀疏数组来存储这些元素。 稀疏数组的定义: 稀疏数组的行数可以理解为矩阵的行数,而…

    数据结构 2023年5月17日
    00
  • 【ACM博弈论】SG函数入门(2):博弈树SG函数的转移与子游戏的合并

    上一篇文章我们讲了两种经典的博弈模型:《【ACM博弈论】SG函数入门(1):从巴什博奕到尼姆游戏》,这一节我们开始讲解SG函数。 ? 作者:Eriktse? 简介:19岁,211计算机在读,现役ACM银牌选手?力争以通俗易懂的方式讲解算法!❤️欢迎关注我,一起交流C++/Python算法。(优质好文持续更新中……)?? 阅读原文获得更好阅读体验:https:…

    算法与数据结构 2023年4月17日
    00
  • Java数据结构之实现哈希表的分离链接法

    Java数据结构之实现哈希表的分离链接法 哈希表是一种非常常用的数据结构,它将数据存储在一个数组中,每个数组元素都存储着链表中的一个节点,这样可以实现高效的数据存储和查找操作。在哈希表中,我们可以通过哈希函数将关键字映射到数组中的特定位置。 但是,当哈希表的负载因子过高时,就会造成哈希冲突,这意味着两个或更多的关键字映射到了同一个数组位置。一种常见的解决方案…

    数据结构 2023年5月17日
    00
  • JavaScript数据结构之广义表的定义与表示方法详解

    JavaScript数据结构之广义表的定义与表示方法详解 什么是广义表 广义表是一种包含了无数元素的数据结构,可以是元素或者嵌套的子表。广义表可以表示为: $\quad\quad\quad GL = (a_0,a_1,…,a_n)$ 其中$a_i$可以是元素或者一个子表,如果$a_i$为一个子表,那么$a_i$本身也是一个广义表。广义表中,第一个元素$a…

    数据结构 2023年5月17日
    00
  • Java数据结构BFS广搜法解决迷宫问题

    Java数据结构BFS广搜法解决迷宫问题 什么是BFS广搜法? 广度优先搜索(BFS)是一种遍历或搜索数据结构(例如树或图)的算法经典方法之一,也是解决迷宫问题的有效解法之一。BFS方法是从图的某个节点出发,以广度优先的方式依次访问与该节点相通的各节点,直到访问所有节点。BFS算法主要借助队列的数据结构来实现。 解决迷宫问题的具体实现 数据准备: 在解决迷宫…

    数据结构 2023年5月17日
    00
  • Java数据结构之链表详解

    Java数据结构之链表详解 什么是链表? 链表是一种基本的动态数据结构,它的基本思想是利用指针将一些零散的内存块串联起来,形成一个逻辑上的整体。链表由一些称为节点的元素组成,每个节点保存两个部分:数据和指向下一个节点的指针。相比于数组这种静态数据结构,链表具有动态性,我们可以通过动态的增加或删除节点来改变链表的大小。 链表的分类 单向链表:每个节点只有一个指…

    数据结构 2023年5月17日
    00
  • 举例讲解C语言程序中对二叉树数据结构的各种遍历方式

    那么我们先来介绍一下二叉树。 什么是二叉树? 二叉树是一种树状的数据结构,它的每个节点最多有两个子节点,分别称为左子节点和右子节点。二叉树节点的定义如下: typedef struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(NUL…

    数据结构 2023年5月17日
    00
  • Java数据结构的十大排序

    Java数据结构的十大排序攻略 简介 在计算机科学中,排序算法是一种将一串数据按照特定顺序进行排列的方法,其中常见的排序算法有很多种,不同的算法适用于不同的数据类型和数据规模。Java是一种常见的编程语言,也提供了很多实现排序算法的类和方法。 本文将介绍Java数据结构的十大排序算法,分别为:插入排序、希尔排序、选择排序、冒泡排序、快速排序、归并排序、堆排序…

    数据结构 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部