算法过程分析,参照数据结构(二)-----二叉堆 - 阿里-马云的学习笔记 - 博客园
手写了一遍算法实现如下:
public class HeapUtil {
//demo验证
public static void main(String[] args) {
Heap heap = new Heap(true);
int[] from = {1, 6, 3, 7, 8, 22, 44, 11, 5};
heap.createHeap(from);
heap.insert(15);
System.out.println("移除值为:" + heap.removeMax());
Arrays.asList(heap.elements).subList(1, heap.max).forEach(e -> System.out.println(e + ","));
}
}
class Heap {
/**
* 最大值数量
*/
int max = 2;
public Integer[] getElements() {
return elements;
}
/**
* 所有元素
*/
Integer[] elements = new Integer[2];
/**
* 最大堆还是最小堆,true最大堆
*/
Boolean isMaxHeap = true;
public Heap(Boolean isMaxHeap) {
this.isMaxHeap = isMaxHeap;
}
/**
* 创建堆
*/
void createHeap(int[] from) {
if (from.length < 1) {
return;
} else if (from.length == 1) {
elements[1] = from[0];
return;
}
int max = from.length + 1;
elements = new Integer[max];
elements[1] = from[0];
//遍历插入
for (int i = 1; i < from.length; i++) {
insert(from[i]);
}
}
/**
* 移除堆顶
*/
Integer removeMax() {
int result = elements[1];
if (max == 2) {
elements[1] = null;
return result;
}
int start = 1;
elements[start] = elements[max - 1];
elements[max - 1] = null;
max--;
//下推, 比较交换父子节点
do {
int leftIndex = getLeftChildIndex(start);
int rightIndex = getRightChildIndex(start);
int switchIndex = isMaxHeap ? getMaxIndex(start, leftIndex, rightIndex) : getMinIndex(start, leftIndex, rightIndex);
int tmp = elements[switchIndex];
elements[switchIndex] = elements[start];
elements[start] = tmp;
if (switchIndex == start) {
break;
} else {
start = switchIndex;
}
} while (getRightChildIndex(start) < max);
return result;
}
/**
* 向堆插入元素
*/
void insert(int element) {
max++;
//扩容
synchronized (elements) {
if (max > elements.length) {
Integer[] newArr = new Integer[elements.length * 2];
System.arraycopy(elements, 0, newArr, 0, elements.length);
elements = newArr;
}
}
//把插入值,先放在max下标
int lastIndex = max - 1;
elements[lastIndex] = element;
//同父节点开始比较
int parentIndex = getParentIndex(lastIndex + 1);
do {
//当父节点与子节点满足关系时,进行换位
boolean needExchange = isMaxHeap ? elements[parentIndex] < element : elements[parentIndex] > element;
if (needExchange) {
elements[lastIndex] = elements[parentIndex];
elements[parentIndex] = element;
lastIndex = parentIndex;
parentIndex = getParentIndex(lastIndex + 1);
} else {
break;
}
} while (parentIndex > 0);
}
static int getParentIndex(int index) {
return (index - 1) / 2;
}
static int getLeftChildIndex(int index) {
return 2 * index + 1;
}
static int getRightChildIndex(int index) {
return 2 * index + 2;
}
int getMaxIndex(int... start) {
int result = start[0];
for (int i = 0; i < start.length; i++) {
Integer tmp = elements[start[i]];
if (tmp == null) {
break;
}
if (elements[result] < tmp) {
result = start[i];
}
}
return result;
}
int getMinIndex(int... start) {
int result = start[0];
for (int i = 0; i < start.length; i++) {
Integer tmp = elements[start[i]];
if (tmp == null) {
break;
}
if (elements[result] > tmp) {
result = start[i];
}
}
return result;
}
}