一.堆
一种数据结构
有这么一个二叉树,确保左右节点小于(大于)当前节点,且该二叉树是一个完全二叉树,那么这就是堆了
堆又分为大顶堆和小顶堆,及最大(小)值在最顶上
就像这样(图片来自CSDN)
二.数组实现
讲堆以数组形式存入,若某节点下标为k,则左节点为2*k,右节点为2*k+1
就像这样
很好理解吧
三.代码实现
//大顶堆案例
//堆
class Heap<T extends Comparable<T> >{
private T[] datas;//存放堆数据
private int size;//堆的大小
private int capacity;//堆的起始固定容量
public Heap(int capacity){
this.capacity = capacity;
datas = (T[]) new Object[capacity];
size = 0;
}
//比较datas[i],datas[j]大小
public boolean compare(int i,int j){
return datas[i].compareTo(datas[j])>0;
}
//交换
public void exchange(int i, int j){
T t = datas[i];
datas[i] = datas[j];
datas[j] = t;
}
//插入
public void insert(T t){
size++;
datas[size] = t;
//末尾插入
swim(size);
}
//上浮算法,使最大的数据往上浮
private void swim(int k){
while(k>1){
if(compare(k,k/2)){
exchange(k,k/2);
}
k/=2;
}
}
//删除堆顶
public T delete(){
T max = datas[1];
exchange(1,size);
datas[size] = null;
size--;
sink(1);
return max;
}
//下沉算法
private void sink(int k){
while(k*2<=size){//确保不越界
int max;
if(2*k+1<=size){//确保有右子节点
max = compare(2*k,2*k+1)?2*k:2*k+1;
}else{
max = 2*k;
}
if(compare(k,max)){
break;
}else {
exchange(k,max);
}
//更新数据
k = max;
}
}
}