使用双链表堆

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:机器人不会从存储桶中知道一点。)

以上是关于使用双链表堆的主要内容,如果未能解决你的问题,请参考以下文章

(王道408考研数据结构)第二章线性表-第三节2:双链表的定义及其操作(插入和删除)

数据结构之双链表

算法开启小码农双链表血脉

双链表的结构和插入节点

双链表和循环链表

数据结构-编程实现一个双链表的建立,双链表的打印,双链表的测长