Algorithm 二项式堆结构不允许使用指向节点(或迭代器)的指针

Algorithm 二项式堆结构不允许使用指向节点(或迭代器)的指针,algorithm,data-structures,heap,heapsort,Algorithm,Data Structures,Heap,Heapsort,我一直在玩二项式堆,我遇到了一个我想在这里讨论的问题,因为我认为这可能与实现二项式堆数据结构的用户有关 我的目标是让指向节点或句柄的指针直接指向二项式堆内部节点,当我将它们插入二项式堆时,这些节点又包含我的优先级值,通常是一个整数。 通过这种方式,我将指针/句柄保留到插入的内容,如果是这样,我可以直接使用二项式\u heap\u delete\u nodenode删除该值,就像迭代器一样 正如我们将看到的,对于二项式堆,这是不可能的,这是因为这种数据结构的体系结构 二项式堆的主要问题是,在某个时

我一直在玩二项式堆,我遇到了一个我想在这里讨论的问题,因为我认为这可能与实现二项式堆数据结构的用户有关

我的目标是让指向节点或句柄的指针直接指向二项式堆内部节点,当我将它们插入二项式堆时,这些节点又包含我的优先级值,通常是一个整数。 通过这种方式,我将指针/句柄保留到插入的内容,如果是这样,我可以直接使用二项式\u heap\u delete\u nodenode删除该值,就像迭代器一样

正如我们将看到的,对于二项式堆,这是不可能的,这是因为这种数据结构的体系结构

二项式堆的主要问题是,在某个时刻,您需要一个操作:二项式堆交换父项和子项父项,子项,并且在二项式堆减少键节点、键和二项式堆删除节点中都需要此操作。通过阅读他们的名字,这些行动的目的非常清楚

所以,问题在于二项式的\u heap\u swap\u parent\u和\u childparent,child是如何工作的:在我看到的所有实现中,它在节点之间交换优先级值,而不是节点本身。 这将使所有指向节点的指针/句柄/迭代器无效,因为它们仍然指向正确的节点,但这些节点的优先级值与您之前插入的不同,而是另一个

这是非常合乎逻辑的,如果我们观察二项式堆或二项式树的结构,通常是这样的:你有一个父节点,被许多子节点视为父节点,所以很多子节点指向它,但父节点不知道有多少子节点,更重要的是,哪些子节点指向它,所以不可能像这样交换节点的位置。您唯一的选择是交换整数优先级键,但这将使所有指向节点的指针/句柄/迭代器无效

注意:一个可能的解决方案不是使用二项式\u heap\u delete\u nodenode,而是将要删除的节点的优先级设置为-9999999或这样的最小值,然后弹出最小节点:这不会解决问题,因为二项式\u heap\u reduce\u keynode,key仍然需要节点父子交换操作,唯一的解决方案是交换整数优先级

我想知道以前是否有人卷入过这个问题。
我认为唯一的解决方案是使用另一个堆结构,例如二进制堆、配对堆或其他一些结构。

与许多数据结构问题一样,通过额外的间接寻址解决这个问题并不困难。定义如下:

struct handle {
  struct heap_node *node;  // points to node that "owns" this handle
  struct user_data *data;  // priority key calculated from this
}
通过复制或指针/引用向用户提供句柄;你的选择

每个内部节点正好指向一个句柄,即节点->句柄->节点==节点。交换两个这样的指针以交换父指针和子指针


有几种可能的变化。例如,数据字段可以是数据本身,而不是指向它的指针。其主要思想是在句柄和节点之间添加间接级别提供了必要的灵活性。

是的,您的解决方案非常明显,就像在每个节点中添加指针向量一样,将指向该节点的子节点指针作为父节点。但无论是在每个节点上添加更多数据,还是添加更多级别的间接寻址,我都会降低性能。所以现在,解决方案仍然是使用另一种不是二项式堆的数据结构。@MarcoPagliaricci我想很明显你没有提到它;-。但在其他堆中也会遇到类似的问题。例如,一个简单的二进制堆以通常的方式作为数组中的一个完整的二叉树进行维护:如果基本实现在数组中存储数据,则要获取delete和reduce键,必须在数组中存储指针或数组索引,并引用其他位置的数据。您必须维护从数据到完整树数组的反向映射。这是我的一个特殊用途的实现:@MarcoPagliaricci NB:另一点是,我不确定你所说的kill性能是什么意思。通过仔细的实现,您将为每个节点添加一个指针。这确实是一个罕见的应用程序,每个节点4或8个字节,每次访问一个指针解引用会导致显著的差异。这正是C++对象引用引入的开销,例如,代码非常有趣,谢谢分享。说真的,我太专注于算法了,以至于我认为所有其他的解决方案,比如增加更多的间接层次等等都是微不足道的。顺便说一句,您在这里指出了一点:其他堆结构也受到此限制,如您提到的使用向量实现的二进制堆。但不是用真正的二叉树和节点实现的二进制堆:在这种情况下,我可以让迭代器正常工作,因为我不交换优先级值。我想我们可以考虑
这个任务结束了:-@MarcoPagliaricci,但是你放弃了每个节点2个指针,而不是1个!