许多快速优先级队列(例如Fibonacci heap和pairing heap)支持减少键操作,该操作采用已存储在优先级队列中的元素并有效降低其优先级。对于Fibonacci和配对堆,可以比从优先级队列中删除元素并稍后重新插入它更快地执行reduce-key。
我想知道在有序字典结构(二叉搜索树,跳过列表等)上是否可以支持类似的操作。具体来说,假设我有一个有序字典,并希望将某个键/值对的键更改为不同的键。是否可以在有序字典的任何标准表示中按时间O(1)或O(log log n)执行此操作?我很好奇,因为有了平衡的BST,这可以通过删除元素并重新插入来在O(log n)时间内完成,但似乎可能有更快的方法来做到这一点。
谢谢!
答案 0 :(得分:1)
想象一下以下场景:
你开始N个元素。现在,
在大多数有序词典的实现中,步骤1和3都需要O(N)时间。如果reduce-key占用O(1)或O(log log N)时间,则步骤2需要O(N)或O(N log log N)时间。这意味着您可以在O(N)或O(N log log N)时间内进行排序。
通过基于比较的排序的O(N log N)下限,这意味着您不能在O(1)或O(N log log N)时间内执行reduce-key,除非
答案 1 :(得分:0)
排序数组或排序链表支持O(1)
减少或增加键(假设没有/最小重复,请参阅第4段)。这是因为,如果您考虑一下,您最多需要交换2个元素来进行减少或增加键操作。
在实践中不是最好的数据结构(虽然它们有它们的位置),但仍然是一个答案。
唯一的限制是你需要一个指向要开始的节点的指针,因为它只需要O(log n)
和O(n)
来分别找到节点。
如果有重复项,那么移动可能会对两者都采用最差情况O(n)
(如果大多数值都相同),这非常糟糕。但是,对于链表,应该可以通过具有某种链表的链表来获取O(1)
,大链表中的每个节点表示特定值和每个链表从那里代表所有节点等于该值。
(没有删除,因为浪费似乎是一种耻辱)
对于BBST或跳过列表,单个元素移动的最小情况小于O(log n)
,但是至少与重新插入一样有效从我所知道的。平均情况可能小于O(log n)
。
我们正在搜索它查找要查找要移动的元素的位置是O(log n)
,显然你需要这样做。< / p>
如果你因某些奇怪的原因已经有了这个职位:
为什么BST中最坏情况的移动不能小于O(log n)
:在尝试移动根时考虑,下一个元素位于树的高度(例如右边)孩子有一个左孩子,左孩子,左孩子,左孩子......到树的高度)。您需要O(log n)
才能找到它。
为什么在跳过列表中最坏情况的移动不能小于O(log n)
:考虑O(log n)
列表中存在的项目,后跟一个存在的项目在这些列表的O(log n)
中(如果这是可能的,从the picture看起来如此,我对跳过列表的理解有些基本)。显然,您需要交换O(log n)
列表中的适用项目。
如果您已经拥有该职位,那么可以存在一个有效的有序结构,但可能不存在任何基于树的结构(因为上面提到的论点),据我所知,这是大多数有效的有序结构。