C 如何在作为二进制堆实现的优先级队列中保持相同优先级元素的顺序?

C 如何在作为二进制堆实现的优先级队列中保持相同优先级元素的顺序?,c,algorithm,priority-queue,binary-heap,C,Algorithm,Priority Queue,Binary Heap,我创建了一个二进制堆,它表示一个优先级队列。这只是经典的著名算法。此堆按时间顺序安排不同事件的顺序(排序键为时间) 它支持两种操作:插入和删除。堆的每个节点的密钥都大于或等于其每个子节点。但是,添加具有相同键的事件不会保留它们添加的顺序,因为每次调用Remove或Insert之后,heap-up和heap-down过程都会打破顺序 我的问题是:在一个经典算法中应该改变什么以保持具有相同优先级的节点的顺序?一个解决方案是向插入的元素添加插入时间属性。这可能只是每次向堆中插入新元素时递增的一个简单计

我创建了一个二进制堆,它表示一个优先级队列。这只是经典的著名算法。此堆按时间顺序安排不同事件的顺序(排序键为时间)

它支持两种操作:插入和删除。堆的每个节点的密钥都大于或等于其每个子节点。但是,添加具有相同键的事件不会保留它们添加的顺序,因为每次调用Remove或Insert之后,heap-up和heap-down过程都会打破顺序


我的问题是:在一个经典算法中应该改变什么以保持具有相同优先级的节点的顺序?

一个解决方案是向插入的元素添加插入时间属性。这可能只是每次向堆中插入新元素时递增的一个简单计数器。然后,当两个元素的优先级相等时,比较插入时间。

如果元素按时间顺序插入,并且保持此顺序(例如,使用“附加”而不是“插入”和“删除和打包”而不是“删除”),则可以使用内存地址(根据环境强制转换为无符号32位或64位整数)作为最后的比较步骤。早期元素的地址数将比后期元素的地址数低。

据我所知,堆从来都不是为了保持顺序而构建的(这就是为什么“堆排序”以不稳定排序著称)

我知道你要问的是,一个小的算法技巧是否能够改变这一点(这不是好的可靠的“时间戳”解决方案)。我认为这是不可能的

我想建议的是以下的一些版本:

  • 保持相同的“插入”

  • 修改“remove”,以确保具有给定优先级的元素具有一定的顺序

要做到这一点,在heap-down中,不要向下交换元素直到保留顺序:向下交换元素直到它作为具有相同值的元素树状图的结尾,并且始终选择在可以的时候向右移动


不幸的是,这样做的问题是您不知道insert将在何处添加具有给定优先级的元素:它可能会出现在树中的任何位置。我相信,更改这一点不仅仅是对结构的调整。

假设您添加一个具有已存在优先级的新元素。顺序如何?添加另一个字段我们称之为插入顺序(long-long),插入时它总是递增的。因此,最后的键是w/pair:priority+insert-order。这是一个有趣的问题,值得进一步研究(我将继续研究)。实际上,这已经被问到并回答了:“那么,当两个元素的优先级相等时,比较插入时间。”---但我可以有更多的元素,而不仅仅是两个键相等的元素。比较它们需要遍历二叉树!@psihodelia:不。在您的实现中,插入或删除元素时必须比较优先级。只需通过不仅比较优先级,还比较时间戳来扩展此比较。