是否可以在不重建堆的情况下从两个堆构建最大堆?

Is it possible to build a max heap from two heap without rebuilding the heap?

我最近参加了计算机科学考试,出现了这样的一道题。

There are two max-heaps (array implemented). You need to come up with an algorithm that merges these two max-heaps and creates a new max-heap (array implemented)

题解很直观就是:

  1. 合并两个数组
  2. 调用堆重建

我在 Internet 上查找并遇到了相同类型的解决方案。

然而,我写了一个我无法反驳自己的解决方案。

我的算法

  1. Create index1 and index2 which points first element of heapArr1 and heapArr2
  2. Create a new heap array which has size of heapArr1.size + heapArr2.size
  3. In while loop
  4. compare index1 element of heapArr1 and index2 element of heapArr2
  5. Whichever is greater, write the result array and increment the index of the array that element taken until two arrays all traversed.

例如

Heap1: 12-5 -6-2-3

Heap2: 15-13-4-1-0

我们先比较15和12,写15

结果堆:15

现在比较 13 和 12

结果堆:15 - 13

比较 4 和 12

resultHeap: 15 - 13 - 12

比较 4 和 5

结果堆:15 - 13 - 12 - 4

如果我们继续这样下去,我们有

resultHeap: 15 - 13 - 12 - 5 - 6 - 4 - 2 - 3 - 1 - 0。而且还是堆

这个算法正确吗?或者谁能​​给出反驳数据集?

对于相同大小的堆,这可能是一种可能的解决方案。

  1. 假设 2 个最大(或最小)二进制堆(A 和 B)。
  2. 首先比较根,较小的那个(假设A)可以安全地假设为另一个(B)的子树的候选者,因此将其分配为B的任何一个child (假设左边)
  3. 由于 B 的 children 现在被替换了,你有 2 个新堆需要考虑,即 B 的原始 children
  4. 现在你有一个空的space,即B的右边child。关注 此过程递归地合并 B 的子节点并将生成的堆分配为 B 的右 child。

这只是花哨的指针操作,它实际上并不是在构建堆,而是利用您已经拥有堆这一事实。

抱歉无法更正式地表达。如果您发现错误,请纠正我。这只是总体思路,并未考虑具体实施细节。

Is this algorithm correct?

没有

can someone gave the refutation data set?

接受这个输入:

  • 第一个堆:10、2、9

        10
       /  \
      2    9
    
  • 第二堆:8、1、4

        8
       / \
      1   4
    

应用算法--括号中表示每个堆中的current索引:

Heap 1 Heap 2 Result heap
[10],2,9 [8],1,4 10
10,[2],9 [8],1,4 10,8
10,[2],9 8,[1],4 10,8,2
10,2,[9] 8,[1],4 10,8,2,9 (violation)
10,2,9[] 8,[1],4 10,8,2,9,1
10,2,9[] 8,1,[4] 10,8,2,9,1,4 (violation)
      10
     /   \
    8     2
   / \   /
  9   1 4 

结果不是有效堆,因为 9 不应该是 8 的 child,因为 9 更大。并且 4 不应该是 2 的 child,因为 4 更大。