堆(优先队列)
二叉堆
二叉堆常常用于优先队列的实现。
堆是一个被完全填满的二叉树,有可能的例外是在底层,底层上的元素从左到右填入。
因为二叉堆是完全二叉树,所以可以使用数组表示,而不需要使用链表。(使用链表似乎代码实现方便点)
堆序性质
任意节点的值都小于它所有字节点的值
代码实现
/** * 二叉堆 * 将堆数据存放在数组内,对自上而下,自左而右的数据依次放到数组中,数组索引从1开始,即array[0]不存放数据 */ public class BinaryHeap { public BinaryHeap(){} public BinaryHeap(int x){ currentSize++; array[currentSize]=x; } public BinaryHeap(int[] items){ currentSize=items.length; array = new int[(currentSize+2)*11/10]; int i=1; for(int item:items){ array[i++]=item; } buildHeap(); } public void insert(int x){ if(currentSize==array.length-1) enlargeHeap(array.length*2+1); //hole代表空穴的位置 int hole = ++currentSize; //空穴的位置上浮 for(;hole>1 && x<(array[hole/2]);hole/=2){ array[hole]=array[hole/2]; } //最后空穴的位置为hole //将x放入空穴 array[hole]=x; } public int findMin() throws Exception{ if(isEmpty()) throw new Exception("堆为空"); return array[1]; } public int deleteMin()throws Exception{ if(isEmpty()) throw new Exception("无法对空堆作删除操作"); int min = findMin(); //把最后一个元素放在首位,并减小堆大小currentSize array[1]=array[currentSize--]; //然后调整堆第一个元素的位置 percolateDown(1); return min; } public boolean isEmpty(){ return currentSize==0; } public void makeEmpty(){ currentSize=0; } private static final int DEFAULT_CAPCITY=10; private int currentSize=0; private int[] array; //对hole位置的元素做下沉操作 private void percolateDown(int hole){ int child=0; int tmp = array[hole]; for(;hole*2<=currentSize;hole=child){ child=hole*2; if(child!=currentSize && array[child+1]<array[child]) child++; if(array[child]<tmp) array[hole]=array[child]; else break; } array[hole]=tmp; } private void buildHeap(){ for (int i=currentSize/2;i>0;i--){ percolateDown(i); } } private void enlargeHeap(int newSize){ if(newSize<=array.length) return; int[] tmp = new int[newSize]; for(int i=1;i<=currentSize;i++){ tmp[i]=array[i]; } array=tmp; } }
联系方式:wuchaodzxx@126.com