This section will introduce how to take out an element from a maximum heap, which is called shift down. Only the element with the highest priority can be taken out, that is, the root node. After taking out the original 62, the following describes how to fill the maximum heap.
In the first step, we put the last digit of the array into the root node, which does not meet the definition of the maximum heap at this time.
The process of adjustment is to move down the root node 16 step by step. 16 is smaller than the child nodes. First, compare the child nodes 52 and 30, which one is larger, and exchange positions with the larger one.
Continue to compare 16's child nodes 28 and 41, 41 is larger, so 16 and 41 exchange positions.
Continue to compare 16 with the child node 15, 16 is larger, so there is no need to exchange now, and finally our shift down operation is completed, maintaining the nature of a maximum heap.
4. Java example code
src/runoob/heap/HeapShiftDown.java file code:
package runoob.heap;
/**
* Take out an element from the largest heap
*/
public class HeapShiftDown<T extends Comparable> { protected T[] data; protected int count; protected int capacity; // Constructor, construct an empty heap , can hold capacity elements public HeapShiftDown(int capacity){ //Adding 1 here refers to the number of elements that can be loaded originally, then remove 0, and only capacity elements can be loaded data = (T[])new Comparable[capacity +1]; count = 0; this.capacity = capacity; } // returns the number of elements in the heap public int size(){ return count; } // returns a Boolean value indicating whether the heap is empty public boolean isEmpty (){ return count == 0;
}
// Insert a new element into the max heap item
public void insert(T item){ assert count + 1 <= capacity; data[count+1] = item; count ++; shiftUp(count); } // Take out the top element from the maximum heap, that is, the maximum data stored in the heap public T extractMax(){ assert count > 0; T ret = data[1]; swap( 1 , count ); count --; shiftDown(1 ); return ret; } // Get the top element in the maximum heap public T getMax(){ assert( count > 0 ); return data[1]; } // Exchange the two elements with indexes i and j in the heap
private void swap(int i, int j){ T t = data[i]; data[i] = data[j]; data[j] = t; } //********** ********* //* Maximum heap core helper function //******************** private void shiftUp(int k){ while( k > 1 && data[k/2].compareTo(data[k]) < 0 ){ swap(k, k/2); k /= 2; } } //shiftDown operation private void shiftDown(int k){ while ( 2*k <= count ){ int j = 2*k; // In this cycle, data[k] and data[j] exchange positions if( j+1 <= count && data[j+1] .compareTo(data[j]) > 0 ) j ++;
// data[j] is the maximum value of data[2*k] and data[2*k+1]
if( data[k].compareTo(data[j]) >= 0 ) break;
swap(k, j);
k = j;
}
System.out.println("end of shiftDown");
}
// Test HeapShiftDown
public static void main(String[] args) { HeapShiftDown<Integer> heapShiftDown = new HeapShiftDown<Integer>(100) ; // Number of elements in the heap int N = 100; // Value range of elements in the heap [0, M) int M = 100; for( int i = 0 ; i < N ; i ++ ) heapShiftDown.insert( new Integer((int)(Math. random() * M)) ); Integer[] arr = new Integer[N];
// Gradually extract the data in the maximum heap using extractMax
// The order of extraction should be from large to small
for( int i = 0 ; i < N ; i ++ ){ arr[i ] = heapShiftDown.extractMax(); System.out.print(arr[i] + " "); } // Make sure the arr array is arranged from largest to smallest for( int i = 1 ; i < N ; i ++ ) assert arr[i-1] >= arr[i]; } }