Lab 08 - Heaps

Heaps

Binary Heaps are binary trees with the following properties:

I. Any node's $ n$ value is greater then his child's value $ c$ . ($ n.value \geq c.value$ )

II. The tree is almost complete (missing elements are possible only on the last level)

       15
     /    \
    9      5
   / \    / 
  2   3  1  

Heap representation using an array:

 15 9 5 2 3 1

This corresponds to a BF traversal of the tree, and it guarantees that the children nodes corresponding to v[i] are v[2i + 1] and v[2i + 2]


1. Basic operations. Implement and analyse the complexity for the following operations:

1.1 empty_heap() - creates an empty heap.

1.2 insert(v, h) - inserts $ v$ in $ h$ . At the end of the procedure , $ h$ is the updated heap.

1.3 get_max(h) - return the maximum value from the heap.

1.4 delete(pos,h) - deletes element at position $ pos$ from the heap.

     algorithm:
        swap the last element with the element whose position is to be deleted
        the resulting tree may no longer be a heap
        (!!) make sure the heap property is preserved 

Deleting 9:

      15
    /    \
   9      5
  / \    /
 2   3  1  

9 is swapped with 1, then deleted

      15
    /    \
   1      5
  / \    /
 2   3  9  

Here, we make sure the heap property is preserved by swapping the largest of the children to be with the current root and repeating the process all over for the modified subtree:

      15
    /    \
   1      5
  / \ 
 2   3  
      15
    /    \
   3      5
  / \ 
 2   1 

2. Using heaps:

2.1 Implement a procedure which constructs a heap from an arbitrary array, using the insert operation.

2.2 Implement heapsort using the previous procedure. What's the complexity?

     algorithm(v):
        build a heap from the array
        extract the top and insert it at the end of the array
        repeat the previous step until the heap is empty

2.3 Implement the following heap-creation procedure, due to Robert W. Floyd:

Suppose we have an unsorted array:

 n = 10
 5 3 2 1 4 8 6 7 0 9

which we treat as a tree, not yet a heap:

                   5
                 /   \
               2      3
             /   \   /  \
            1     9 8    6
           / \   /
          7   0 4

We start from the last level, which in this case is $ ceil(log(10)) = 4$ from $ j = 2^{(4-1)}$ (which is 8) to n-1. On the last level, each tree is a heap.

We now move to a previous level. Say the level is i:

from $ j = 2^{(i-1)}$ to $ 2^i-1$ :

we send-down each value on this level, just like in the deletion algorithm, by keeping as the current root, the largest between the two children. The sending down procedure repeats recursively, until we have heaps on level i. Example:

                   5
                 /   \
               2      3
             /   \   /  \
            7     9 8    6
           / \   /
          1   0 4

we repeat the process on the next level:

                   5
                 /   \
               9      8
             /   \   /  \
            7     4 3    6
           / \   /
          1   0 2

until we reach the first level:

                   9
                 /   \
               7      8
             /   \   /  \
            5     4 3    6
           / \   /
          1   0 2

Notice that 5 is sent-down on its respective level.

Analyse the complexity.