基于堆的优先队列

优先队列由一个基于堆的完全二叉树表示,存储与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);
    }  
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值