堆快速插入和删除O(log n)

时间:2017-01-21 23:59:28

标签: c++ c algorithm search

我正在尝试找到一个具有下述几个属性的算法:

  • 使用数组作为存储(缓存友好)。
  • 仅存储无符号整数。
  • 没有关联的值。
  • 插入和删除第i项应按O(log n)时间顺序排列。
  • 保持结构稳定,以便在遍历时删除元素。
  • 订购和查找单个项目并不重要,也不是Max或Min。

针对此类问题有许多解决方案。 一种非常常见的是红/黑树。我不喜欢这个问题的树,因为我必须在其他方面使用动态内存(比如存储我不需要的指针和相关值)。

我想到的另一个选择是使用二进制堆。它旨在快速删除min / max元素,因此适用于优先级队列。在我的情况下,我需要一些扩展版本,允许删除堆中的任意项。 是否可以在log(n)时间内删除。网上已经提到,如果你在数组中有位置就是这种情况。但是我找不到证明这是正确的证据。 另一件事是删除期间的稳定性。 如果答案是否定的,你会建议什么?

2 个答案:

答案 0 :(得分:3)

是的,可以在堆中的随机元素上删除O(lg n)时间。

如何?假设这是你的堆:

                   4
                 /   \
                10   20
               /  \  ...
              30  40  ...
             /  \   ......
            50  60

假设你要删除10,然后(因为这是一个Min-Heap)你得到10个最小的孩子并放到他的位置,然后从10岁的小孩(30)重新开始并带来30& #39;最小的孩子(50)。

如果正确构建了堆,则在此方法运行时将保留属性。

事实上,这只不过是从根本开始的Heapify。

        4                    4                    4 
      /   \                /   \                /   \
   [10]   20              30   20              30   20
   /  \   ...    =>      /  \   ...    =>     /  \   ...
  30  40   ...        [30]  40   ...         50  40   ...
 /  \    ......       /  \     ......       /  \    ......
50  60               50  60              [50]  60

答案 1 :(得分:2)

如果我正确理解了这个问题,那么您无需按价值查找项目,也不需要关心他们的订单是什么?

如果是这种情况那么你应该把它们放在从头开始的数组中。如果你必须删除中间的项目,那么只需将它与项目和结束交换,然后从那里删除它。

在迭代数组时也很容易做到这一点。当您删除某个项目时,您只是不增加该位置,因为要访问的下一个项目已交换到您删除的项目的位置。