zoukankan      html  css  js  c++  java
  •   参考自:

      https://www.jianshu.com/p/6b526aa481b1

      堆就是用数组实现的完全二叉树,所以它没有使用父指针或者子指针。它根据“堆属性”来排序,“堆属性”决定了树中节点的位置。

      堆分为两种:大顶堆小顶堆,两者的差别在于节点的排序方式。

      大顶堆:每一个父节点的值都比其子节点要大。

      小顶堆:每一个父节点的值都比其子节点要小。

    注意:堆的根节点中存放的是最大或者最小元素,但是其他节点的排序顺序是未知的。例如,在一个最大堆中,最大的那一个元素总是位于 index 0 的位置,但是最小的元素则未必是最后一个元素。唯一能够保证的是最小的元素是一个叶节点,但是不确定是哪一个。最小堆也同理

    堆和二叉搜索树的比较:

      节点的顺序

      在二叉搜索树中,左子节点必须比父节点小,右子节点必须必比父节点大。

      但是在堆中并非如此。在最大堆中两个子节点都必须比父节点小,而在最小堆中,它们都必须比父节点大。

      内存占用

      二叉搜索树占用的内存空间比它们存储的数据要多。你必须为节点对象以及左/右子节点指针分配额为是我内存。

      堆仅仅使用一个数据来村塾数组,且不使用指针。

      平衡

      二叉搜索树必须是“平衡”的情况下,其大部分操作的复杂度才能达到O(log n)。你可以按任意顺序位置插入/删除数据,或者使用 AVL 树或者红黑树。

      但是在堆中实际上不需要整棵树都是有序的。我们只需要满足对属性即可,所以在堆中平衡不是问题。因为堆中数据的组织方式可以保证O(log n) 的性能。

      搜索

      在二叉树中搜索会很快,但是在堆中搜索会很慢。

      在堆中搜索不是第一优先级,因为使用堆的目的是将最大(或者最小)的节点放在最前面,从而快速的进行相关插入、删除操作。

    堆的操作:

      插入

      

      我们向数组[ 10, 7, 2, 5, 1 ]中添加16。

      插入后,16被添加到最后的位置上,树变成了:

      

      但是这棵树不满足堆的属性,所以交换16和2的位置:

      

      仍旧不满足堆属性,交换16和10的位置,此时插入16成功得到大顶堆:

      

      

      删除根节点

       

      删除这个堆中的根节点10。

      

      新的根节点应该怎么办?

      当插入节点的时候,我们将新的值返给数组的尾部。现在我们来做相反的事情:我们取出数组中的最后一个元素,将它放到树的顶部,然后再修复堆属性。

      以1位根节点。

      

      不满足大顶堆的属性,交换1和7:

      

      不满足大顶堆的属性,交换1和5:

      

      得到删除根节点后的大顶堆。

      删除任意节点

       绝大多数时候你需要删除的是堆的根节点,因为这就是堆的设计用途。

      

      删除7

      因为移除一个元素会破坏最大堆或者最小堆属性,所以我们需要将删除的元素和最后一个元素交换:

      

      最后一个元素就是我们需要返回的元素,然后调用方法把它删除即可。

      

      在对删除后的树修复堆属性,就可得到删除任意节点的堆了。

      

    转载请注明地址:https://www.cnblogs.com/fangxiaoqi/

    觉得有帮助的话可以点一下推荐,thanks

  • 相关阅读:
    C语言|博客作业02
    少走弯路的十条忠告
    怎么算是优秀的程序员写给工作2,3年了的同行
    .NET世界的M型化原文作者奚江华
    工作以后十不要 减少奋斗30年
    <转>[创业经验]程序员创业:我的软件推广成功之路
    一个程序员的C#命名规则<转>
    推荐奚江华著《圣殿祭祀ASP.NET 3.5 专家技术手册 C#篇及他的TW博客进入方法》
    C#算法
    使用 DataFormatString 属性来提供列中各项的自定义格式
  • 原文地址:https://www.cnblogs.com/cruelty_angel/p/10505226.html
Copyright © 2011-2022 走看看