【问题标题】:position index for binary heap priority queues?二进制堆优先级队列的位置索引?
【发布时间】:2009-08-17 16:00:07
【问题描述】:

假设我有一个包含 N 个具有优先级的项目的优先级队列,其中 N 是数千个,使用通过 binary heap 实现的优先级队列。我了解EXTRACT-MININSERT 原语(请参阅Cormen, Leiserson, Rivest,它使用-MAX 而不是-MIN)。

但是DELETEDECREASE-KEY 似乎都要求优先级队列能够在给定项目本身的情况下在堆中找到项目的索引(或者,该索引需要由优先级队列的消费者提供,但是这似乎违反了抽象)....看起来像是疏忽。有没有一种方法可以有效地做到这一点,而不必在堆顶部添加哈希表?

【问题讨论】:

    标签: data-structures priority-queue


    【解决方案1】:

    对,我认为这里的重点是,对于优先级队列的实现,您可以使用二进制堆,其 API 为其 HEAP-INCREASE-KEY(A, i, key) 获取索引 (i),但是可以允许优先级队列的接口采用任意键。您可以让优先级队列封装 key->index 映射的详细信息。如果您需要您的 PQ-INCREASE-KEY(A, old, new) 在 O(log n) 中工作,那么您最好有一个 O(log n) 或更好的索引查找键来保持最新。这可能是一个哈希表或其他快速查找结构。

    所以,回答你的问题:我认为数据结构不可避免地要以某种方式进行扩充。

    【讨论】:

      【解决方案2】:

      FWIW,如果有人仍然在寻找类似的东西——我最近在做 Coursera 算法课程之一时偶然发现了一个 Indexed 优先级队列的实现。

      基本要点是使用 2 个数组合并反向查找,以支持 OP 所述的操作。

      这是Min Ordered Indexed Priority Queue 的明确实现。

      【讨论】:

        【解决方案3】:

        “但 DELETE 和 DECREASE-KEY 似乎都要求优先级队列能够在给定项目本身的情况下在堆中找到项目的索引”——从代码中可以清楚地看出,这些方法中至少有一些使用索引到堆而不是项目的优先级。显然,i 是 HEAP-INCREASE-KEY 中的索引:

        HEAP-INCREASE-KEY(A, i, key)
            if key < A[i]
                then error 'new key is smaller than current key"
            A[i] <-- key
            ...
        

        所以,如果这是 API,请使用它。

        【讨论】:

        • 它是 heap 的 API,而不是优先级队列。
        • 此外,一旦您从堆中插入或提取项目,索引就不再保证有效,因此在某个时间点知道项目的索引不一定有帮助您可以知道某个项目在另一个时间点的索引。
        【解决方案4】:

        我修改了我的节点类以添加一个 heapIndex 成员。这由堆维护,因为在插入、删除、减少等期间交换节点。

        这会破坏封装(我的节点现在绑定到堆上),但它运行得很快,这在我的情况下更为重要。

        【讨论】:

          【解决方案5】:

          一种方法是将堆拆分为一侧的元素和另一侧的组织。

          要获得完整的功能,您需要两个关系: a)给定一个堆位置(例如根),找到坐在那里的元素。 b) 给定一个元素,找到它的堆位置。

          第二个非常简单:添加一个值“位置”(很可能是基于数组的堆中的索引),每次在堆中移动元素时都会更新该值。

          第一个也很简单:您只需保留一堆指向元素(或数组索引)的指针,而不是存储元素。现在,给定一个位置(例如根),您可以通过取消引用它(或访问向量)找到坐在那里的元素。

          【讨论】:

            【解决方案6】:

            但 DELETE 和 DECREASE-KEY 似乎都要求优先级队列能够在给定项目本身的情况下在堆中找到项目的索引

            实际上,这不是真的。您可以通过前任和后继指针在未索引的图、链表和“传统”搜索树中实现这些操作。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2017-09-07
              • 2017-10-18
              • 2023-04-03
              • 1970-01-01
              • 1970-01-01
              • 2011-10-18
              • 2019-02-25
              • 1970-01-01
              相关资源
              最近更新 更多