There two methods to construct a heap from a unordered set of array.
If a array has size n, it can be seen as a complete binary tree, in which the element indexed by i has its left children 2*i+1(if 2*i+1<n) and its right children 2*i+2(if 2*i+2<n), noting that the index of the array is from 0 to n-1.
First let us introduce two subprocessed:
sift_down and
sift-up
sift-down
sift-down is a recursive procedure. Aussming that we start from node i, compare i with the smaller(denoted by j) between it's left children i+1 and it's right children i+2. If value of i is bigger than value of j(in min heap), we change the value of i and j, and then do the same procidure to j. Do like this until j is a leaf node. Note that the subtree rooted by left children of i and the subtree rooted by the right children of i are both minheap(satisfy the property of min heap). The code for sift-down can be written as follows:
void siftdown(int a[],int i, int n) //n is the size of array a
{
while(2*i+1<n)
{
int j=2*i+1;
if(j+1<n&&a[j+1]<a[j])
j++;
if(a[j]<a[i])
swap(a,i,j); //exchange value of i and j
i=j;
}
}
sift-up
sift-up is also a recursive procidure. Assuming that we start from node i, compare i with its parent p((i-1)/2). If value of i is smaller than value of p, exchange value of i and p, and then do the same thing to p until p is the root of this tree. Note that all the nodes before node i make up a minheap. The code for sift-up can be written like follows:
void siftup(int a[],int i, int n) //n is the size of array a
{
while(i>0)
{
int p=(i-1)>>1;
if(a[i]<a[p])
swap(a,i,p);
i=p;
}
}
1、process using sift-down
The last element who has a children is indexed by (n-1)/2. Starting from i=(n-1)/2, Do sift-down to i until the root. After this, a minheap is constructed. The pseudo code for this procedure can be written like follows:
void heap_create_1(int a[],int n)
{
if(n<=1)
return;
int i=(n-1)/2;
while(i>0)
siftdown(a,i,n);
}
The time cost using only sift-down to create a heap is O(n).(Actrually, the compare times during creating a minheap from a unordered array, whose size is n, is not greater than 4*n.)
Note that in this method, when siftdown node i, all the subtree under i is minheap.
2、process using sift-up
This method go through from node indexed by 0 to node indexed by n-1. When processing node i, the nodes before i make up a minheap. So processing node i can be seen as inserting a new node to a minheap. For each i, we sift up from i to root. The pseudo code for this method can be written like follows:
void heap_create_2(int a[],int n)
{
int i;
for(i=1;i<n;i++)
siftup(a,i,n);
}
The time cost using sift-up to create a heap is O(nlogn).