簡體   English   中英

合並兩個二進制最大堆,其中一個堆中的所有元素都大於另一個堆中的所有元素?

[英]Merging two binary max heaps in which all the elements in one heap is greater than all the elements in the other?

我遇到了這個編程面試問題,但不確定我的答案是否正確。 我找不到這個問題的正確答案。 這是問題

令H1和H2為分別具有n1和n2個元素的兩個(二進制)最大堆。 如果H1中的每個元素都大於H2中的每個元素,請設計一種算法,將這兩個堆在O(n2)時間內合並為一個(二進制)最大堆(假設H1和H2都足夠大以容納n1 + n2元素)

因此,我在想,由於H1中的每個元素都大於H2中的每個元素,因此我們可以將合並的最大堆存儲在H1中。 因此,我們要做的就是簡單地從H2中獲取第一個元素,在H2數組中的位置0,然后將該元素插入H1中,追加到H1數組的末尾,使其成為H1中的葉子。 我們可以連續地對H2中的每個元素執行此操作。 我想一旦我們開始將H2中的元素作為子元素添加到H2元素中,那么我們將必須開始檢查該子元素是否小於父元素,如果不是,則交換它們。 我假設由於添加元素而不調用heapify,並且在必要時進行交換將給我們帶來O(n2)的復雜性。

那么,我的解決方案准確嗎? 如果沒有任何幫助,將不勝感激。 請告訴我解決方案的任何部分不清楚,以便我澄清。

通常,不能僅將H2附加到H1上,因為正如注釋中指出的那樣,這樣做會產生無效的堆。 這種情況並不罕見。

例如,想象兩個最大堆:

h1 = [100]
h2 = [6,3,5,1,2,4]

    h1        h2

   100        6
            3   5
           1 2 4

如果僅將h2附加到h1,則會得到:

    100
  6    3
 5 1  2 4

這顯然是無效的,因為4是3的子代。

如果h1 = [100,98] ,則可能發生相同的事情:

       100
    99     6
   3  5  1   2
 4

您要做的是將h2附加到h1,然后運行一個簡短的build-heap ,重新排列h2中的項目以反映它們在堆中的新位置。 您已經知道從h2添加的所有項目都小於h1中的最小項目,因此您無需觸摸h1中的任何項目。

此和標准構建堆之間的唯一區別是開始位置和結束位置。 基本上,您從h2的中間開始,然后倒退到h2的開始。

h1_length = h1.length
h2_length = h2.length
h1.array.append(h2.array)  // copies items from h2 to h1
// rearrange h2 items
start = h1_length + (h2_length/2)
for (item = start; item > h1_length; --item)
{
    i = item
    // This assumes that the root of the heap is at 0.
    // If the root is at 1, then the left child is at i*2
    while (i*2+1 < h1.length)
    {
        // get the largest child of this item
        leftChildIndex = i*2+1
        rightChildIndex = leftChildIndex + 1
        largestChildIndex = leftChildIndex
        if (rightChildIndex < h1.length &&
            h1.array[rightChildIndex] > h1.array[leftChildIndex)
        {
            largestChildIndex = rightChildIndex
        }
        // if the item is greater than or equal to its largest child,
        // then the item is where it belongs.
        if (h1.array[i] >= h1.array[largestChildIndex])
        {
            break;
        }
        // swap the item with its child, and check again
        swap(h1.array[i], h1.array[largestChildIndex])
        i = largestChildIndex
    }
}

事實證明, 構建堆算法為O(n),其中n是要構建的堆中的項目數。 由於您僅使用h2.length項目,因此將花費O(h2.length)個時間。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM