数据结构与算法(12): 堆- 二叉堆 发表于 2016-10-31 | 分类于 数据结构与算法 堆有两个性质,即结构性和堆序性。将任意节点不大于(不小于)其子节点的堆叫做最小堆(最大堆)。 结构性 堆中任意节点的值总是不大于(不小于)其子节点的值。 堆序性 堆总是一棵完全树。 二叉堆的结构是一棵完全二叉树。 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 import java.util.ArrayList; import java.util.List; /** * 二叉堆:最小堆 */ public class BinaryHeap<T extends Comparable<? super T>> { private List<T> heap; public BinaryHeap() { this.heap = new ArrayList<>(); } /** * 插入 * * @param ele */ public void insert(T ele) { heap.add(ele); percolateUp(heap.size() - 1); } /** * 删除最小元 * @return */ public T deleteMin() throws Exception { if (isEmpty()){ throw new Exception("堆为空"); } T ele = heap.get(0); heap.set(0, heap.get(size() - 1)); heap.remove(size() - 1); if (size() > 1){ percolateDown(0); } return ele; } /** * 上滤 */ private void percolateUp(int index) { int parentIndex = (index - 1) / 2; T tmpEle = heap.get(index); while (index > 0) { if (tmpEle.compareTo(heap.get(parentIndex)) >= 0) { break; }else { heap.set(index, heap.get(parentIndex)); index = parentIndex; parentIndex = (index - 1)/2; } } heap.set(index, tmpEle); } /** * 下滤 */ private void percolateDown(int index) { // 先设置为左儿子索引 int childIndex = 2 * index + 1; T tmpEle = heap.get(index); while (childIndex < size()){ // 左右儿子大小比较, 选择较小者 if (childIndex < size() - 1){ int cmp = heap.get(childIndex).compareTo(heap.get(childIndex + 1)); if (cmp > 0){ // 右儿子较小 childIndex++; } } int cmp = tmpEle.compareTo(heap.get(childIndex)); if (cmp <= 0){ break; }else { heap.set(index, heap.get(childIndex)); index = childIndex; childIndex = 2 * index + 1; } } heap.set(index, tmpEle); } public boolean isEmpty(){ return heap.size() == 0; } public int size(){ return heap.size(); }}