基于堆的优先队列

来源:互联网 发布:mac上安装android sdk 编辑:程序博客网 时间:2024/04/28 14:58

优先队列由一个基于堆的完全二叉树表示,存储与a[1~N]中,a[0]没有使用。

插入元素:将新元素加到数组末尾,增加堆的大小,并让元素上浮到合适的位置。
删除最大元素:我们将最后一个元素与第一个元素(最大元素)交换,并将最后一个(最大元素的)位置设为空。然后使用sink方法,将交换到第一位的元素放置到正确位置。
注:根据可需求添加reSize()方法,扩展数组的大小。
/*
通过创建一个temp的数组,大小为数组的两倍。然后通过for循环将所有元素复制。最后,原数组 = temp;即可。
*/

具体代码如下:

package algorithm;public class MaxPQ<Key extends Comparable<Key>> {    private int N = 0;//基于堆的完全二叉树    private Key[] pq;//存储于pq[1...N]中,pq[0]没有使用    public MaxPQ(int maxN) {        pq = (Key[])new Comparable[maxN+1];    }    //将元素插在最后,并使用swim方法将其排序    public void Insert(Key v) {         pq[++N] =  v;        swim(N);    }    public boolean isEmpty() {        return N==0;    }    public int size() {        return N;    }    public Key delMax() {        Key max =pq[1];//从根结点得到最大元素        exch(1,N--);   //将其和最后一个结点交换        pq[N+1] =null; //将最后一个结点设为null(删除),防止对象的游离        sink(1);       //恢复堆的有序性        return max;    }    //上升    private void swim(int k) {        /*         * 由于k为int类型,故无论是哪个子节点,除以2都会得到其父节点         * 如第二层:k=2及k=3,2/2=1,3/2=1(强制转化为int类型)         */        while(k>1&&less(k/2,k)){            exch(k/2,k);            k = k/2;        }    }    //下沉    private void sink(int k) {        while(2*k<=N) {            int j = 2*k;            if(j<N&&less(j,j+1)) j++;//比较k下边的两个子节点,取大的那个,j>j+1时,取j,否则,j++            if(!less(k,j)) break;//如果k小于相对较大的那个子节点,则说明不用再移动,退出循环            exch(k,j);//如果k大于相对较大的子节点,则交换位置            k = j;        }    }    private boolean less(int i,int j) {        return pq[i].compareTo(pq[j])<0;    }    private void exch(int i, int j) {        Key temp =pq[i];        pq[i] = pq[j];        pq[j] = temp;    }    public static void main(String[] args) {        int maxN =2;        MaxPQ<Integer> pq = new MaxPQ<Integer>(maxN);    }  }
原创粉丝点击