堆
堆的定义:堆是计算机中一种特殊的数据结构的统称,通常是一个可以看做一棵树的数组对象。堆总是满足下列性质:
- 堆中某个节点的值总是总大于或者不小于其父节点的值;
- 堆总是一颗完全二叉树。
将根节点最大的堆叫做最大堆或者大根堆,根节点最小的堆叫做最小堆或者小根堆。常见的堆有二叉堆,斐波那契堆。
二叉堆
二叉堆是一种特殊的堆,二叉堆是完全二叉树或者近似完全二叉堆。二叉堆有两种:最大堆和最小堆。最大堆:父节点的值总是大于或者等于子节点的值;最小堆:父节点的值总是小于或者等于子节点的值。二叉堆有两个性质,即结构性和堆序性。
-
结构性质:一颗高为h的完全二叉树有
到
-1个节点。所以完全二叉树的高为logN,显然它是O(logn)。因为完全二叉树这么有规律,所以它可以用一个数组表示而不需要使用链。
-
堆序性质:在一个堆中,对于每一个节点X,X的父亲中的关键字小于(或等于)X中的关键字,根节点除外(它没有父亲)。
基本堆操作
基本操作包括插入、删除、构建。下面代码演示:
package structures;
import java.util.EmptyStackException;
/**
* 二叉堆的性质
* @param <AnyType>
*/
public class BinaryHeap<AnyType extends Comparable<? super AnyType>> {
private static final int DEFAULT_CAPACITY = 10;
//number of element in heap
private int currentSize;
private AnyType [] array;
public BinaryHeap(AnyType[] items) {
//this.array = array;
currentSize = array.length;
this.array = (AnyType[]) new Comparable[(currentSize+2)*11/10];
int i = 1;
for (AnyType item:items) {
array[i++] = item;
}
buildHeap();
}
/**
* 构建符合堆条件的数组
*/
private void buildHeap() {
for (int i=currentSize/2;i>0;i--){
percolateDown(i);
}
}
/**
* 插入操作
* @param x
*/
public void insert(AnyType x){
if(currentSize==array.length-1){
enlargeArray(array.length*2+1);
}
int hole =++currentSize;
for(array[0]=x;x.compareTo(array[hole/2])<0;hole/=2){
array[hole] = array[hole/2];
}
array[hole]=x;
}
/**
* 取得最小的值
* @return
*/
public AnyType deleteMin(){
if(isEmpty()){
throw new EmptyStackException();
}
AnyType minItem = findMin();
array[1] = array[currentSize--];
percolateDown(1);
return minItem;
}
/**
* 重新构建数组,使数组符合二叉堆结构
*/
private void percolateDown(int num) {
int child = 0;
AnyType tmp = array[num];
for (;num*2<=currentSize;num=child){
child = num * 2;
if(child!=currentSize&&array[child+1].compareTo(array[child])<0){
child++;
}
if(array[child].compareTo(tmp)<0){
array[num] = array[child];
}else{
break;
}
}
array[num] = tmp;
}
/**
* 寻找最小值
* @return
*/
private AnyType findMin() {
}
private boolean isEmpty() {
if(currentSize==0){
return true;
}
return false;
}
/**
* 对数组扩容
* @param i
*/
private void enlargeArray(int i) {
}
}