Max Heap with ArrayList

时间:2018-05-01 15:29:49

标签: java sorting insert queue

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

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}。

1 个答案:

答案 0 :(得分:0)

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

二进制堆必须保留两个属性:

  1. 形状属性 - 它是一个完整的二叉树:一个树,其中除了可能的最后一个级别之外的所有级别都已完全填满。如果未满,则最后一级是左边的。
  2. 堆属性 - 在最大堆中,每个节点都大于或等于其子节点。在最小堆中,每个节点都小于或等于其子节点。
  3. 因此所有这些都是4个项目的有效二进制最大堆:

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

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

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

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

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

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