堆(优先级队列)的实现(Java)


前言

      堆,优先级队列,底层为一维数组,逻辑上是一个完全二叉树。

      以下均以小顶堆为例:父节点为 p,两个子节点为 l 和 r 。下标转换关系:(画出即可得到该转换关系)
      l = 2 * p + 1 ,r = l + 1;
      p = ( l - 1 ) / 2 或者 p = ( r - 1 ) / 2;

      堆中重要的两个方法:push() 和 pop()
      push() :向堆中添加一个新元素,新元素添加至数组末尾,然后呢,向上调整堆,调整采用的方法为交换。
      pop() :获取堆顶元素,然后将堆顶元素的值置为末尾元素值,删除末尾元素,然后向下调整堆。

      具体的 Java 实现如下,可供参考:

代码实现

import java.util.*;
public class MyPriortyQueue {
    private List<Integer> arr;
    MyPriortyQueue(){
        arr=new ArrayList<>();
    }
    public boolean isEmpty(){
        return arr.size()==0;
    }
    public void push(int val){
        arr.add(val);
        adjustUp();
    }
    private void adjustUp(){
        int cur=arr.size()-1;
        int p=(cur-1)/2;
        while(p>=0){
            if(arr.get(p)>arr.get(cur)){
                Collections.swap(arr,p,cur);
                cur=p;
                p=(cur-1)/2;
            }
            else
                break;
        }
    }
    public int pop(){
        if(isEmpty())
            return -1;
        int tmp=arr.get(0);
        adjustDown();
        return tmp;
    }
    private void adjustDown(){
        Collections.swap(arr,0,arr.size()-1);
        arr.remove(arr.size()-1);
        int cur=0,l=2*cur+1,r=l+1;
        while(l<arr.size()){
            if(r>=arr.size()){
                if(arr.get(cur)>arr.get(l))
                    Collections.swap(arr,cur,l);
                break; // 堆为一个完全二叉树,此时直接 break;
            }
            int min=arr.get(l)<arr.get(r)?l:r;
            if(arr.get(cur)>arr.get(min)){ //只需要和最小的比较即可
                Collections.swap(arr,cur,min);
                cur=min;
                l=2*cur+1;
                r=l+1;
            }
            else
                break;
        }
    }
    public int size(){
        return arr.size();
    }

    public static void main(String[] args) {
        MyPriortyQueue p=new MyPriortyQueue();
        p.push(4);
        p.push(9);
        p.push(3);
        p.push(7);
        p.push(2);
        while(!p.isEmpty())
            System.out.print(p.pop()+" ");
        System.out.println();
        PriorityQueue<Integer> pp=new PriorityQueue<>();
        pp.add(4);
        pp.add(9);
        pp.add(3);
        pp.add(7);
        pp.add(2);
        while(!pp.isEmpty())
            System.out.print(pp.poll()+" ");
    }
}


总结

      大顶堆的实现参照小顶堆即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值