堆:1.满足完全二叉树 2. 左右子结点 都小于父节点 或 左右子结点 都大于父节点
大堆:左右子结点 都小于父节点
小堆:左右子结点 都大于父节点
// 堆代码
public class Heap<T extends Comparable<T>> {
//存储堆中的元素
private T[] items;
//记录堆中元素的个数
private int N;
public Heap(int capacity) {
items = (T[]) new Comparable[capacity + 1];
N = 0;
}
//判断堆中索引i处的元素是否小于索引j处的元素
private boolean less(int i, int j) {
return items[i].compareTo(items[j]) < 0;
}
//交换堆中i索引和j索引处的值
private void exch(int i, int j) {
T tmp = items[i];
items[i] = items[j];
items[j] = tmp;
}
//往堆中插入一个元素
public void insert(T t) {
items[++N] = t;
swim(N);
}
//使用上浮算法,使索引k处的元素能在堆中处于一个正确的位置
private void swim(int k) {
//如果已经到了根结点,就不需要循环了
while (k > 1) {
//比较当前结点和其父结点
if (less(k / 2, k)) {
//父结点小于当前结点,需要交换
exch(k / 2, k);
}
k = k / 2;
}
}
//删除堆中最大的元素,并返回这个最大元素
public T delMax(){
T max=items[1];
exch(1,N);
items[N]=null;
N--;
sink(1);
return max;
}
//使用下沉算法,使索引k处的元素能在堆中处于一个正确的位置
private void sink(int k){
while (2*k<=N){
//找到子结点中的较大者
int max;
if (2*k+1<=N){//存在右子结点
if (less(2*k,2*k+1)){
max = 2*k+1;
}else{
max = 2*k;
}
}else{//不存在右子结点
max = 2*k;
}
//比较当前结点和子结点中的较大者,如果当前结点不小,则结束循环
if (!less(k,max)){
break;
}
//当前结点小,则交换,
exch(k,max);
k = max;
}
}
public static void main(String[] args) {
Heap<String> heap = new Heap<String>(20);
heap.insert("S");
heap.insert("G");
heap.insert("I");
heap.insert("E");
heap.insert("N");
heap.insert("H");
heap.insert("O");
heap.insert("A");
heap.insert("T");
heap.insert("P");
heap.insert("R");
String del;
while((del=heap.delMax())!=null){
System.out.print(del+",");
}
}
}