什么是堆
堆是一颗完全被填满的二叉树
形如这样的
而这样则不是完全二叉树
堆序性质
每个节点都要的节点值都要大于(小于)子树的值。
顺序实现特点
对于除0位置以外的,位置i,它的左子为2i,右子为2i+1。父亲为 i/2.
具体实现
排序原理
插入原理
上滤,在下一个位置上创建一个空位,插入值于空位的父亲值对比,若插入值较小,于父亲值交换位置。
删除原理
下滤,将第一个值删去,将最后一个位置的值放在第一个位置,将此值的左,右孩子值比较较小的于此值交换位置,直到到叶子停止。
二叉堆得作用
- 排序
- 事件模拟
public class MyBinaryHeap<AnyType extends Comparable< ? super AnyType>> {
public MyBinaryHeap( ) {
clear(DEFAULT_CAPACITY);
}
public void clear( int capacity ) {
array = (AnyType []) new Comparable[capacity];
}
//使用上滤,这种方法插入值
public void insert(AnyType value ) {
if( currentSize == array.length - 1)
enlargeArray( array.length * 2 + 1);
int hole = ++currentSize;
for ( ; hole > 1 && value.compareTo(array[hole /2]) < 0; hole /= 2)
array[hole] = array[ hole/2];
array[ hole] = value;
}
//返回最小值
public AnyType findMin() {
return array[1];
}
public boolean isEmpty() {
return currentSize == 0;
}
public AnyType deleteMin() {
try {
if (isEmpty() )
throw new UnderflowException("二叉堆为空");
}
catch(UnderflowException e) {
System.out.println(e);
}
AnyType minItem = findMin();
array[1] = array[ currentSize--];
percolateDown( 1 );
return minItem;
}
public void makeEmpty() {
array = (AnyType []) new Comparable[1];
}
private static final int DEFAULT_CAPACITY = 10;
private int currentSize;
private AnyType [] array;
// 使用下潜法将大值放下去,小值放上来。
private void percolateDown( int hole) {
int child;
AnyType temp = array[ hole ];
for ( ; hole * 2 <= currentSize; hole = child) {
child = hole * 2;
if ( child != currentSize &&
array[child + 1].compareTo(array[child]) < 0)
child++;
if ( array[child].compareTo(temp) < 0)
array[hole] = array[child];
else
break;
}
array[hole] = temp;
}
private void enlargeArray( int newSize ) {
AnyType [] newarray;
newarray= (AnyType[]) new Comparable[ newSize ];
int i = 0;
for ( AnyType item : array)
newarray[ i++] = item;
array = newarray;
}
}
测试代码
public static void main(String[] args) {
MyBinaryHeap test = new MyBinaryHeap();
test.insert(4);
test.insert(3);
test.insert(2);
test.insert(1);
test.deleteMin();
System.out.println(test.findMin());
}
测试结果
2