使用双链表堆
Posted
技术标签:
【中文标题】使用双链表堆【英文标题】:Heap using double linked list 【发布时间】:2020-12-06 18:24:46 【问题描述】:假设一个人想要使用一个双向链表来实现一个最大堆。能 与标准数组实现相比,使用双向链表可以实现相同的操作 Insert、ExtractMaxHeap 和 MaxHeapify 复杂度。
我的回答是我们可以使用数组在 log(n) 时间内完成所有三个操作 执行。但是,对于双向链表
插入 - logn ExtractMaxHeap -o(1) MaxHeapify - o(登录)
【问题讨论】:
欢迎来到堆栈溢出 @SE。您能否勾勒出Insert
的实现,它使您声称运行时增长与 log(n) 一样快?
【参考方案1】:
在标准数组实现中,可以在恒定时间内找到元素的子元素。如果当前节点由索引i标识,则左子节点由索引2i+1标识,右子节点由索引2i+2 em>*.
*在有 k 个孩子的堆中,这将是 ki+1, ki+2, ..., ki+k。原理是一样的
给定一个双向链表中的节点,无法在恒定时间内到达第一个子节点。节点在链表中的位置越深,它需要的步骤就越多——遍历链表的链——才能到达具有子节点的子链。
在数组实现中,您不需要访问位于节点及其子节点之间的元素。对孩子的访问(按索引)是立即的。这在链表中是不正确的。您别无选择,只能先访问下一个节点,然后访问下一个节点,......等等。直到您到达子节点所在的“索引”。这条链的长度,走向孩子,随着你开始的节点的深度呈指数增长。
当您需要查找节点的父节点时,也会出现类似的低效率。
由于堆上的所有基本操作都涉及将子值与父值交换,因此在双向链表实现中,与数组实现相比,此问题使这些操作的时间复杂度更差。
【讨论】:
你在这里假设一个二进制堆。还有其他堆。 @Sneftel,没错。不过原理是一样的。在我的回答中添加了关于 k-ary heaps 的数组实现的脚注。 @abdul 操作的时间复杂度取决于您想到的特定实现。如果你有一个特定的算法,你已经实现并且工作正常,但不确定它的时间复杂度,你应该问一个关于它的新问题。【参考方案2】:如果元素完全存储在链表中,没有其他结构,则不会。如果元素已排序,则插入将是 O(n)。如果不是,那么提取将是 O(n)。
【讨论】:
你能解释一下机器人,你是怎么说的吗? (@abdul:机器人不会从存储桶中知道一点。)以上是关于使用双链表堆的主要内容,如果未能解决你的问题,请参考以下文章