堆
大顶堆:父节点的值大于左右子节点
小顶堆:父节点的值小于左右子节点
堆的存储使用数组结构,数组第0号位空出来
如果当前节点的索引是i,那么父节点的索引是i / 2,左孩子节点的索引是 2 * i,右孩子的节点是2 * i + 1
以下都以大顶堆为例
插入
插入到数组尾部,如果父节点的值大于当前值则交换父节点值和当前值
删除(堆顶元素)
堆中最后一个值赋给堆顶元素,然后从上往下堆化。把父节点值赋给左右子孩子中大的一个(n/2 + 1到n个子节点不用堆化,因为是叶子节点)
public class Heap {
public int[] array;
/**
* 堆中已经存储的元素数量
*/
public int count;
/**
* 堆的最大容量
*/
public int capacity;
public Heap(int capacity) {
array = new int[capacity + 1];
count = 0;
this.capacity = capacity;
}
/**
* 插入
*/
public void insert(int val) {
if (count >= capacity) {
return;
}
count++;
array[count] = val;
int i = count;
while (i / 2 > 0 && array[i] > array[i / 2]) {
swap(array, i, i / 2);
i = i / 2;
}
}
private void swap(int[] array, int p, int q) {
int temp = array[p];
array[p] = array[q];
array[q] = temp;
}
/**
* 删除
*/
public void removeMax() {
if (count == 0) return ; // 堆中没有数据
array[1] = array[count];
--count;
heapify(array, count, 1);
}
private void heapify(int[] a, int n, int i) { // 自上往下堆化
while (true) {
int maxPos = i;
if (i*2 <= n && a[i] < a[i*2]) maxPos = i*2;
if (i*2+1 <= n && a[maxPos] < a[i*2+1]) maxPos = i*2+1;
if (maxPos == i) break;
swap(a, i, maxPos);
i = maxPos;
}
}
}