堆(英语:heap)是计算机科学中一类特殊的数据结构的统称。堆通常是一个可以被看做一棵树的数组对象。堆总是满足下列性质:
-
堆中某个节点的值总是不大于或不小于其父节点的值;
-
堆总是一棵完全二叉树
首先我们要知道用数组表示堆的一些要点。若数组中节点的索引为x,则:
节点的左子节点是 2*index+1,
节点的右子节点是 2*index+2,
节点的父节点是 (index-1)/2。
删除:
删除堆顶后把最后一个元素移到堆顶,然后向下筛选:和子节点比,如果小于子节点,则交换,一直到它的子节点都大于它为止
插入:
把要插入的数据插入到数组最后。然后向上筛选:和父节点比,如果大于父节点,则交换,一直到父节点大于它为止
package heap;
//大根堆类
public class Heap {
private int [] heap;
private int maxSize;
private int currentSize;
//构造函数
public Heap(int max){
maxSize = max;
currentSize = 0;
heap = new int[maxSize];
}
//判断堆是否为空
public boolean isEmpty(){
return (currentSize == 0) ? true : false;
}
//判断堆是否已满
public boolean isFull(){
return (maxSize == currentSize) ? true : false;
}
//插入数据,插入后向上筛选
public boolean insert(int data){
if(isFull()){
return false;
}
heap[currentSize] = data;
tinkerUp(currentSize++);
return true;
}
//向上筛选
public void tinkerUp(int index){
int fatherIndex = (index - 1) / 2;
while((fatherIndex >= 0)&&(heap[index] > heap[fatherIndex])){
int temp = heap[index];
heap[index] = heap[fatherIndex];
heap[fatherIndex] = temp;
index = fatherIndex;
fatherIndex = (index - 1) / 2;
}
}
//向下筛选
public void tinkerDown(int index){
int leftIndex = index * 2 + 1;
int rightIndex = index *2 + 2;
while((leftIndex < currentSize || rightIndex < currentSize)&&(heap[index] < heap[leftIndex] || heap[index] < heap[rightIndex])){
if(rightIndex < currentSize){
if(heap[index] < heap[leftIndex]){
int temp = heap[index];
heap[index] = heap[leftIndex];
heap[leftIndex] = temp;
index = leftIndex;
leftIndex = index * 2 + 1;
rightIndex = index *2 + 2;
}else if(heap[index] < heap[rightIndex]){
int temp = heap[index];
heap[index] = heap[rightIndex];
heap[rightIndex] = temp;
index = rightIndex;
leftIndex = index * 2 + 1;
rightIndex = index *2 + 2;
}
}else{
if(heap[index] < heap[leftIndex]){
int temp = heap[index];
heap[index] = heap[leftIndex];
heap[leftIndex] = temp;
index = leftIndex;
leftIndex = index * 2 + 1;
rightIndex = index *2 + 2;
}
}
}
}
//移除堆顶最大元素
public int remove(){
int root = heap[0];
heap[0] = heap[--currentSize];
tinkerDown(0);
return root;
}
//遍历输出堆
public void display(){
if(isFull()){
System.out.println("空堆。");
return;
}
for(int i=0;i<currentSize;i++){
System.out.println(heap[i]);
}
}
//获得堆顶元素
public int get(){
if(isFull()){
System.out.println("空堆。");
return -1;
}
return heap[0];
}
}