how to build heap tree?

▼魔方 西西 提交于 2021-01-29 06:20:53

问题


I understand the algorithm of building heap tree (max or min) but i don't understand the code of it:

First: How does this loop build a max heap?, why we started the i with n/2-1 ?

// Build heap (rearrange array) 
for (int i = n / 2 - 1; i >= 0; i--) 
    heapify(arr, n, i); 

and this is the Heapify function:

Secondly: how did we assume that largest is "i" ?

Third: why we heapify again in the last line?

// To heapify a subtree rooted with node i which is 
// an index in arr[]. n is size of heap 
void heapify(int arr[], int n, int i) 
{ 
    int largest = i; // Initialize largest as root 
    int l = 2*i + 1; // left = 2*i + 1 
    int r = 2*i + 2; // right = 2*i + 2 

    // If left child is larger than root 
    if (l < n && arr[l] > arr[largest]) 
        largest = l; 

    // If right child is larger than largest so far 
    if (r < n && arr[r] > arr[largest]) 
        largest = r; 

    // If largest is not root 
    if (largest != i) 
    { 
        swap(arr[i], arr[largest]); 

        // Recursively heapify the affected sub-tree 
        heapify(arr, n, largest); 
    } 
} 

The code and the algorithm i got,is from GeeksForGeeks


回答1:


Let's do this with a very simple example of building a max heap, which I think will answer your questions. Imagine you have the array [3, 1, 6, 4, 7, 9]. That corresponds to this binary tree:

     3
  1     6
4   7 9

The idea of the algorithm is to push things down the heap to their proper place. Your first question is why we start at i = n//2. The simple answer is that any node at position greater than i//2 is a leaf; it has no children and therefore cannot be pushed down. Actually, we can start at (n-1)//2, because if n is even then the first non-leaf node is there, and for an odd number, (n-1)//2 == n/2.

So in this case, i=2. Your next question is why we assume that the element at index i is the largest. We don't. We start with that, because we have to find the largest of the three items (the item at i and its two children). So we just default to i. You could, if you want, set largest to the left child, and then do the comparisons. But there's no particular reason to do it that way. You have to start with something, and the item at index i is the easiest.

In this case, the item at index i is 6. We examine the item's children and find that 9 is larger, so we swap. The result is:

     3
  1     9
4   7 6

We decrement i, giving us i=1. Looking at the item there and its children, we see that 7 is the largest, so we swap the two items, giving:

     3
  7     9
4   1 6

And now we're at the root. 9 is the largest among the root and its children, so we swap:

     9
  7     3
4   1 6

And here's the answer to your third question: why the recursive call to heapify? You have to push the item down the heap as far as it will go. Here, 3 is smaller than 6, so we have to swap those items to give:

     9
  7     6
4   1 3



回答2:


1) Consider heap structure

              M
       K            L
   G       H     I     J  
 A  B    C  D   E  F  

Last level contains at most half of all items ((n+1)//2), so item at index n/2-1 always is parent of the last items at the last level. And starting from that index and traversing left we are ordering three-items mini-heaps, then traversing up and left we are ordering 7-items heaps, ans so on.

2) It is simple initialization of conditional task - if we find larger descendant, it replaces parent

3) If parent has been replaced, it moved down, and might be smaller than new decendants, so we must check (small element sinks down)




回答3:


The largest child index ci of a parent node is:

ci = 2*i + 2 < size
i < (size - 2)/2
i < size/2 - 1

but you need to include size/2 - 1, as a node may have just one child and i goes all the way to zero, as all those nodes are parent nodes. As for recursion, you need to enforce the max-heap rule after a swap.



来源:https://stackoverflow.com/questions/52600839/how-to-build-heap-tree

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!