1、它是完全二叉树,除了树的最后一层结点不需要是满的,其它的每一层从左到右都是满的,如果最后一层结点不 是满的,那么要求左满右不满。
2、通常用数组来实现,将二叉树的结点按照层级顺序放入数组中,根结点在位置1,它的子结点在位置2和3,而子结点的子 结点则分别在位置4,5,6和7,以此类推。
如果一个结点在数组中的索引为k,则它的父结点的索引为k/2,它的左右子结点的索引分别为2k和2k+1。这样,在不使用指针的情况下,我们可以通过计算元素在数组中的索引来实现结点在树中上下移动
3、每个结点的值都大于等于它的两个子结点。
堆的API设计 堆的代码实现public class Heap> { //存储堆中的元素 private final T[] items; //记录堆中元素个数 private int number; //构造方法 public Heap(int capacity) { this.items = (T[]) new Comparable[capacity + 1]; this.number = 0; } //判断堆中索引i处的值是否小于索引j处的值 public boolean less(int i, int j) { return items[i].compareTo(items[j]) < 0; } //交换堆中i索引和j索引的值 public void exch(int i, int j) { T temp = items[i]; items[i] = items[j]; items[j] = temp; } //往队中插入一个元素 public void insert(T t){ //往数组中添加一个元素 items[++number] = t; //元素上浮 swim(number); } //使用上浮算法,使索引k处的元素能在堆中处于一个正确的位置 private void swim(int k) { while (k > 1){ //如果k结点的值大于父结点的值,则交换 if (less(k/2,k)){ exch(k/2,k); } //变换k k = k/2; } } //删除堆中最大的元素,并返回这个最大的元素 public T delMax(){ //堆中第一个元素即为最大的元素 T max = items[1]; //交换索引1处和最大索引处的元素,让完全二叉树最后一个元素变为临时根结点 //items[1] = items[number]; //此方式也可行 exch(1,number); //删除掉最大索引处的值 items[number] = null; number--; //使用下沉算法,让临时根结点处于合适的位置 sink(1); return max; } //使用下沉算法,让索引k处的元素处于合适的位置 private void sink(int k) { //循环比较索引k处元素与其左右子结点的元素大小,让k索引处元素与较大者交换位置 while (2*k<=number){ //记录较大者元素所在的索引值 int max; //如果存在右子结点 if (2*k+1<=number){ //比较左右子结点元素大小,将较大者的索引给max if (less(2*k,2*k+1)){ max = 2*k+1; }else { max = 2*k; } }else { max = 2*k; } //比较当前索引k处元素与索引max处元素大小 if (!less(k,max)){ break; } //交换索引k与索引max处的元素位置 exch(k,max); //变换k的值 k = max; } } //获取堆中元素个数 public int size(){ return number; } //判断堆是否为空 public boolean isEmpty(){ return number==0; } public static void main(String[] args) { Heap heap = new Heap<>(20); heap.insert("A"); heap.insert("B"); heap.insert("C"); heap.insert("D"); heap.insert("E"); heap.insert("F"); heap.insert("G"); String max; while ((max = heap.delMax())!=null){ System.out.println(max); } } }
测试结果
以上仅个人学习时随手敲的demo,如有不正确的地方,可以在下方留言指正,谢谢。与各位CSDN的伙伴们共勉,每天记录一点点,每天进步一点点。



