##For starters lets have few macros and methods
Since we are implementing a heap with arrays, for a node i
, we can have a parent
, a left child
and a right child
The calculations
PARENT(i):
return FLOOR(i/2)
LEFT(i):
return (2*i)
RIGHT(i):
return (2*i + 1)
Some method definations
heap_size(array) # returns the current heap size
set_heap_size(array) # set the heap size to some supplied parameters
##The main algorithm can be further divided into three modules.
###MAX_HEAPIFY :: Makes sure that the heap starting from index i
follows the Max-Heap Property
i.e. the element at root will be the maximum. The childrens will be smaller than the root, also implying the grand childrens will be smaller than its children .. and so on.
MAX_HEAPIFY(array, i):
l = LEFT(i)
r = RIGHT(i)
IF l <= heap_size(array) AND array[l] > array[i]:
largest = l
ELSE:
largest = i
END IF
IF r <= heap_size(array) AND array[r] > array[largest]:
largest = r
END IF
IF largest != i
swap(array[i], array[largest])
MAX_HEAPIFY(array, largest)
END IF
END MAX_HEAPIFY
The method is supplied with an array
and index i
.
Store the index of left child of i
in l
.
And that of right child in r
.
If the value at index l
is greater than the value at index i
, or in other words, if the value of left child array[l]
is greater than the rootarray[i]
, set largest = l
. If not, set largest = i
. Now largest
has the index of greater element out of root and its left child.
Now compare the value at largest
with that of right child. If the value of right child is greater than the value of largest
, it can be concluded that the value of right child is greater than the value of root as well as the left child. In such case set largest = r
.
Now largest
contains the index that hold the maximum value out of root, left child and right child.
Our next step will be to check if the present setup contradicts the Max-Heap Property.
According to the statement, root must be the largest one, i.e. after going through above mentioned conditional assignments, largest
must be equal to i
in order to hold Max-Heap Property.
If thats the case, we can end our algo with an assumption of the heap being in state according to the property. But if largest
is not equal to i
, that means the property has been violated and must be corrected. Swap the largest value with the value at root and call MAX_HEAPIFY with the largest
as index to correct the decending heap.
Hence if a smaller value is at the root, it will be floated down to the bottom of heap by recursive call on MAX_HEAPIFY.
###BUILD_MAX_HEAP :: Uses MAX_HEAPIFY to build Max-Heaps
BUILD_MAX_HEAP(array):
set_heap_size(array) = length(array)
FOR i = FLOOR(length(array) / 2) DOWNTO 1:
MAX_HEAPIFY(array, i)
If we notice PARENT calculation, we can see PARENT(i) = FLOOR(i/2)
. Hence, if our array
is of length n
, the last parent which can be calculated is located at index FLOOR(n/2)
.
Speaking english (reminds me how poor I am :P) the elements of array
which are located after FLOOR(n/2)
, are all leaf nodes and do not have further children.
So while building Max-Heap for first time, we iterate a loop from FLOOR(n/2) down to 1
, where n = length(array)
.
Starting from leaves, the loop heads toward the root when i = 1
and in each iteration, it makes a call to MAX_HEAP with index i
which makes sure that the decendents are always satisfying Max-Heap Property.
###HEAP_SORT :: Initiates the heap by calling BUILD_MAX_HEAP and then sorts the array with the help of MAX_HEAPIFY
HEAP_SORT(array):
BUILD_MAX_HEAP(array)
FOR i = length(array) DOWNTO 2:
swap(array[1], array[i])
set_heap_size(array) = heap_size(array) - 1
MAX_HEAPIFY(array, 1)
Initiates Max Heap by calling BUILD_MAX_HEAP
.
Since a heap satisfying Max-Heap Property has the maximum element as root, swap the root (here it will be always 1) with last element
Call MAX_HEAPIFY
again over the heap, (leaving the last element by decreasing the heap size) to ensure the maximum at top.
Decrease the value of i
and hence now swaping takes place with the second last element.
The loop continues and ultimately produces a sorted array.
- Best Case: O(n log(n))
- Average Case: O(n log(n))
- Worst Case: O(n log(n))