java语言程序设计(进阶篇)读书笔记 之 数据结构每天一小练--堆(一)
2012-03-14 22:50 尔 阅读(252) 评论(0) 收藏 举报堆是一种特殊的完全二叉树,它要求每个节点都大于或等于它的一个子节点
由于二叉树的性质可知
1,一个节点的父节点(i)的位置在:(i-1) / 2
2,一个节点的坐子节点(i)的位置为:2i + 1
3,一个节点的右子节点(i)的位置为:2i + 2
由于堆的特殊要求,所以我们插入一个新节点,和删除根节点(这俩种操作在堆中的执行效率很高),需要对堆进行重建。
可以借助数组,或列表实现堆的基本数据结构。
以ArrayList为例
1,插入一个新节点时,首先把新节点插入集合末尾,然后判断其和其父节点的大小,如果大于父节点,那么将它与它的父节点交换,交换列表中索引位置,依次循环,如果不再大于父节点,则堆已经重建完成。
2,删除根节点,删除后,先把列表的最后一个元素作为堆的跟节点,然后将它和它的子节点中大的节点做比较,交换列表中索引位置,依次循环,如果不再小于任何一个它的子节点。那么堆则构建完成。
package 堆; public class Heap<E extends Comparable> { private java.util.ArrayList<E> list = new java.util.ArrayList<E>(); public Heap() { } public Heap(E[] objects) { for(int i = 0; i<objects.length; i++) { add(objects[i]); } } public void add(E newObject) { list.add(newObject); int currentIndex = list.size() - 1; while(currentIndex > 0) { int parentIndex = (currentIndex - 1)/2; if(list.get(currentIndex).compareTo(list.get(parentIndex)) > 0) { E temp = list.get(currentIndex); list.set(currentIndex, list.get(parentIndex)); list.set(parentIndex, temp); } else { break; } currentIndex = parentIndex; } } public E remove() { if(list.size() == 0) { return null; } E removedObject = list.get(0); list.set(0, list.get(list.size() - 1)); list.remove(list.get(list.size() - 1)); int currentIndex = 0; while(currentIndex < list.size()) { int leftChildIndex = 2 * currentIndex + 1; int rightChildIndex = 2*currentIndex + 2; if(leftChildIndex >=list.size()) break; int maxIndex = leftChildIndex; if(rightChildIndex < list.size()) { if(list.get(maxIndex).compareTo(list.get(rightChildIndex)) < 0) { maxIndex = rightChildIndex; } } if(list.get(currentIndex).compareTo(list.get(maxIndex)) < 0) { E temp = list.get(maxIndex); list.set(maxIndex, list.get(currentIndex)); list.set(currentIndex, temp); } else { break; } } return removedObject; } public int getSize() { return list.size(); } }