我一直在玩Binomial Heaps,我遇到了一个我想在这里讨论的问题,因为我认为它可能涉及某些用户实现二项式数据结构。
我的目标是指向直接指向二项式堆内部节点的节点或句柄,当我将它们插入二项式堆时,二进制堆内部节点又包含我的优先级值,通常是整数。
通过这种方式,我将指针/句柄保存到我插入的内容中,如果是这样的话,我可以直接使用binomial_heap_delete_node(node)
删除该值,就像迭代器一样。
正如我们所知,由于这种数据结构的体系结构,使用二项式堆可能 NOT ,而这是因为这种数据结构的体系结构。
二项式堆的主要问题是,在某些时候您需要执行操作:binomial_heap_swap_parent_and_child(parent, child)
,并且您需要在binomial_heap_decrease_key(node, key)
和{{{{{}}中执行此操作1}}。通过阅读他们的名字,这些操作的目的非常明确。
所以,问题是binomial_heap_delete_node(node)
如何工作:在 all 我看到的实现中,它在节点之间交换优先级值,而 NOT 节点本身。
这将使节点的所有指针/句柄/迭代器无效,因为它们仍将指向正确的节点,但这些节点不会具有您之前插入的相同优先级值,而是另一个节点。
这是非常符合逻辑的,如果我们观察二项式堆(或二项式树,一般)是如何构造的:你有一个父节点,被许多孩子视为"父母",这么多孩子指向它,但该父节点不知道有多少个孩子(或者更重要的是,哪个孩子)指向它,所以它将不可能像这样交换节点的位置。您唯一的选择是交换整数优先级键,但这将使节点的所有指针/句柄/迭代器无效。
注意:可能的解决方案是 NOT 而不是使用binomial_heap_swap_parent_and_child(parent, child)
,可以将节点的优先级设置为删除到-999999999(或这样的最小值)并弹出最小节点输出:这不会解决问题,因为binomial_heap_delete_node(node)
仍然需要节点父子交换操作,唯一的解决方案是交换整数优先级。
我想知道以前是否有人遇到此问题。 我认为唯一的解决方案是使用另一个堆结构,例如Binary Heap,Pairing Heap或其他东西。
答案 0 :(得分:0)
与许多数据结构问题一样,使用额外的间接级别来解决这个问题并不困难。定义如下内容:
struct handle {
struct heap_node *node; // points to node that "owns" this handle
struct user_data *data; // priority key calculated from this
}
您为用户提供句柄(通过复制或指针/引用;您的选择)。
每个内部节点都指向一个句柄(即node->handle->node == node
)。两个这样的指针被交换以交换父母和孩子。
有几种变化是可能的。例如。 data
字段可以是数据本身,而不是指向它的指针。主要思想是在句柄和节点之间添加间接级别提供了必要的灵活性。