【问题标题】:Max Heap with ArrayList使用 ArrayList 的最大堆
【发布时间】:2018-05-01 15:29:48
【问题描述】:

我创建了一个类来管理一个以 ArrayList 作为参数的优先级队列。我需要做一个最大堆,所以如果我执行以下插入:16、9、7、8、4、14、1、3、2、10,我需要在这些位置获得一个包含这些元素的 ArrayList:{16 , 9, 14, 7, 4, 8, 10, 3, 2, 1}。问题是我的插入方法看起来没有对元素进行排序:

public void insert(T elem) {
    int i = queue.size();
    int parentIndex = (int) Math.floor((i - 1) / 2);
    while (i > 0 && elem.compareTo(queue.get(parentIndex)) == 1) {
      queue.set(i, queue.get(parentIndex));
      i = parentIndex;
      parentIndex = (int) Math.floor((i - 1) / 2);
    }
    queue.add(i, elem);
  }

示例:插入(16)、插入(14)、插入(9)。预期数组:{16,9,14}。结果:{16,14,9}。

【问题讨论】:

  • 那么你得到了什么输出?编辑您的问题以显示输入、预期输出和实际输出。
  • 问题已编辑。

标签: java sorting insert queue


【解决方案1】:

您的期望不切实际。 {16, 14, 9} 是一个完全有效的二进制堆。

二叉堆必须维护两个属性:

  1. 形状属性 - 它是一棵完全二叉树:除了可能的最后一层之外,所有层都完全满的树。如果未满,则最后一层为左满。
  2. 堆属性 - 在最大堆中,每个节点都大于或等于其子节点。在最小堆中,每个节点都小于或等于其子节点。

所以所有这些都是 4 项的有效二进制最大堆:

      4          4          4
    2   3      3   2      3   1
   1          1          2

这里的关键是,在每种情况下,最大值都在根处,并且孩子总是小于他们的父母。

二叉堆中节点的顺序取决于插入顺序。在您的示例中,如果广告订单是 {16, 9, 14},那么您将获得您期望的订单。

有关二进制堆的更多信息,请参阅https://en.wikipedia.org/wiki/Binary_heap

我认为您正在努力解决的问题是期望优先级队列维护一个排序列表。它没有。优先级队列只是允许插入和删除最高优先级项的数据结构的名称。您可以使用排序列表实现优先级队列,但这样做会非常昂贵。就性能而言,二叉堆是更好的选择。

如果在将所有项目添加到优先级队列后,您重复调用 remove 方法(或任何您调用的获取最大项目的方法),您会看到项目以正确的顺序被删除。

【讨论】:

  • 在我的公式中,我必须考虑到 2i 位置是给左儿子的,而 2i+1 位置是给右儿子的。这就是为什么我期望 {16, 9, 14}
  • 您的公式仍然适用于 [16, 14, 9] 排列。没有要求左孩子小于右孩子。
猜你喜欢
  • 2021-08-11
  • 1970-01-01
  • 1970-01-01
  • 2012-04-02
  • 2020-06-27
  • 2021-11-27
  • 1970-01-01
  • 2013-03-29
  • 1970-01-01
相关资源
最近更新 更多