1. Heap definition
The (binary) heap data structure is an array object that can be viewed as a nearly complete binary tree .
就是说 堆 是一近乎 完全二叉树 的 结构,堆可以用来排序(称为堆排序 )。
2. Relationship between array index and tree’s nodes
A heap can be stored as an array A.
堆可以用 数组 来存储。
We simply number the nodes in the heap from top to bottom, numbering the nodes on each level from left to right and store the ith node in the ith location of the array. (of course remembering that array indexing in Java starts at zero).
就是说我们 从上到下 从左到右 的标识这个 二叉树,并和数组中的下标对应起来,如下图所示:
关系:
• Root of tree is A[1].
• Parent of A[i ] = A[i/2].
• Left child of A[i ] = A[2i ].
• Right child of A[i ] = A[2i + 1].
注意:在java中数组的下标从 0 开始 。
3. Bulid Heap
算法流程:
Begin:
Build-Heap (A[]) { // takes in an array to be heapified
A.heap-size = A.length; // heap size is number of elements in the array
for i = A.length/2 downto 1 // starting at first subtree up to root full tree
{
Heapify(A, i); // Heapify the current subtree
}
}
End
heapify-----堆化过程
Begin
Heapify(A[], i) // Heapify takes in our heap and index of current root node of subtree to be heapified
{
left = LeftChild(i); // index of left child
right = RightChild(i); // index of right child
// if still within bounds AND left child
if left ≤ A.heap-size AND A[left] > A[i] {
// greather than parent – remember largest as left child
largest = left;
} else {
largest = i; // else parent still has largest value for now
}
// if still within bounds AND right child
if right ≤ A.heap-size AND A[right] > A[largest] {
// greather than parent – remember largest as right child
largest = right
}
if largest NOT EQUAL i { // if parent does not hold largest value
// greather than parent – remember largest as right child
swap A[i] and A[largest] x
Heapify(A, largest) // Percolate down and Heapify next subtree
}
}
End
4. code in java
下面是java实现的构造最大堆的代码:
/**
* bulid heap with array
*
* @author hahakubile
*/
public class Heap {
// 未作数据校验,假设 数据源ok
public void buildHeap(int[] a) {
int index = new Double(Math.floor(a.length/2)).intValue()-1;
// 打印 未堆化前
printArray(a);
while(index>=0) {
heapify(a, index);
index--;
}
// 打印 堆化后
printArray(a);
}
private void heapify(int[] a, int i) {
int heapSize = a.length;
int left = leftChild(i);
int right = rightChild(i);
int largest = 0;
if(left<heapSize && a[left]>a[i]) {
largest = left;
} else {
largest = i;
}
if(right<heapSize && a[right]>a[largest]) {
largest = right;
}
if(largest!=i) {
// 交换 a[i] 与 a[largest]
int temp = a[i];
a[i] = a[largest];
a[largest] = temp;
heapify(a, largest);
}
}
/**
* 堆的特性,注意这里 root的下标从零开始
*/
public int leftChild(int i) {
return 2*i + 1;
}
public int rightChild(int i) {
return 2*i + 2;
}
// 辅助函数,打印 数组内容
public void printArray(int[] a) {
StringBuilder sb = new StringBuilder();
sb.append("[");
for(int i : a) {
sb.append(i).append(",");
}
String temp = sb.substring(0, sb.length()-1);
System.out.println(temp + "]");
}
public static void main(String[] args) {
Heap h = new Heap();
int[] A = new int[]{4,1,3,2,16,9,10,14,8,7};
h.buildHeap(A);
}
}