堆
堆有两个特性
- 用数组表示的完全二叉树
- 任一结点的关键(root)字是其所有子树所有结点的最大值(最大值)
- 最大堆:最大值,下图
- 最小堆:最小值,下图
- 特性: 路径有序
- 目的,实现优先队列,取出元素按优先级,而非插入的顺序;
插入操作理解:插入这个数组表达的完全二叉树的最末尾,然后对比其父结点,是否大于,大于则互换位置,小于则break;
删除操作理解:如图删除max即index=1时的元素,
- 最末尾元素替换index=1的元素,然后最末尾替换它;
- 调整最末尾的数字的位置;如图示;
public class Heap {
int[] elements; //存储数组
int size; //当前元素数量
int capacity; //最大容量
public Heap(int capacity) {
this.capacity = capacity;
elements = new int[capacity + 1]; //从index =1 开始存储, 0 为稍定
elements[0] = Integer.MAX_VALUE;
size = 0;
}
public void insert(int element) {
if (isFull()) throw new RuntimeException("full");
int index = ++size; // 实际存储从1 开始存入数组;
for (; elements[index / 2] < element; index /= 2) {
elements[index] = elements[index / 2];
}
elements[index] = element;
}
public int deleteMax() {
if (isEmpty())
throw new RuntimeException("empty");
int maxItem = elements[1];
int temp = elements[size--];
int parent = 1;
for (int child = 0; parent * 2 < size; parent=child) {
child = parent*2;
if (parent!=size && elements[child]<elements[child+1])
child++;
if (temp>elements[child]) break;
else
elements[parent] = elements[child];
}
elements[parent] = temp;
return maxItem;
}
}
哨兵的意义:
哨兵取最大值,在insert方法中,i=1时,i/2=0,elements[i] = max_int;可以增加for循环的效率;
堆的建立
思想理解:
若图所述的数组(完全二叉树)并非一个堆,从最后一个开始慢慢构建一个堆,利用删除的思想,逐步调整,找最大的值/最小值,放入结点中;即可构架最大堆/最小堆;