堆(二)(Java)

优先级队列

1、概念

优先级队列应当提供两个操作:
(1)返回最高优先级对象;
(2)添加新的对象

2、内部原理

实现优先级队列的方式很多,但最常见的是用来构建

3、操作 - 入队列

过程(以大堆为例)
(1)首先按尾插方式放入数组
(2)比较其和其双亲的值的大小,如果双亲的值大,则满足堆的性质,插入结束
(3)否则,交换其和双亲位置的值,重新进行 (2)(3)步骤
(4)直到根结点

4、操作 - 出队列(优先级最高)

为了防止破坏堆的结构,删除时并不是直接将堆顶元素删除,而是用数组的最后一个元素替换堆顶元素,然后通过向下调整方式重新调整成堆

5、返回队首元素(优先级最高)

返回堆顶元素即可

6、代码实现

public class MyPriorityQueue {

    private int[] array = new int[100];
    private int size = 0;

    //向上调整,建一个大堆
    private static void shiftUp(int[] array,int index){
        int child = index;
        //根据孩子结点,找到双亲节点
        int parent = (child - 1)/2;
        while(child > 0){
             //若孩子结点大于双亲节点,就交换两个结点的值
            if(array[child] >array[parent]){
                int temp = array[child];
                array[child] = array[parent];
                array[parent] = temp;
            }
            //更新结点
            child = parent;
            parent = (child -1)/2;
        }
    }
    
    //向下调整,建一个大堆
    private static void shiftDown(int[] array,int size,int index){
        int parent = index;
        //根据双亲节点,找到孩子结点
        int child = parent * 2 + 1;
        while(child<size){
            //找到孩子结点中比较大的一个
            if( child+1 < size && array[child+1]>array[child]){
                child++;
            }
            //若孩子结点大于双亲节点,就交换两个结点的值
            if(array[child] >array[parent]){
                int temp = array[child];
                array[child] = array[parent];
                array[parent] = temp;
            }
            //更新结点
            parent = child;
            child = parent * 2 + 1;
        }
    }
    
    //入队
    public void offer(int x){
        array[size] = x;
        size ++;
        shiftUp(array,size-1);
    }
    
    //出队
    public int poll(){
        int pollValue = array[0];
        array[0] = array[size -1];
        size --;
        shiftDown(array,size,0);
        return pollValue;
    }
    
    //取队首元素
    public int peek(){
        return array[0];
    }
    
    //判断队是否为空
    public boolean isEmpty(){
        return size == 0;
    }
}

7、java中的优先级队列

代码演示:

import java.util.PriorityQueue;

public class TestPriorityQueue {
    public static void main(String[] args) {
       //创建一个优先级队列
        PriorityQueue<Integer> queue = new PriorityQueue<>();
        //入队
        queue.offer(9);
        queue.offer(5);
        queue.offer(2);
        queue.offer(7);
        queue.offer(3);
        queue.offer(6);
        queue.offer(8);

        //出队、取队首元素、判断队是否为空
        /*
        在这里,每出队一次,取一次队首元素、判断一次队是否为空;
        直到队为空
        */
        System.out.print("出队:");
        while(!queue.isEmpty()){
            System.out.println();
            int cur = queue.poll();
            System.out.print(cur);
            System.out.println();
            System.out.print("取队首元素:");
            System.out.print(queue.peek());
            System.out.println();
            System.out.print("判断队是否为空:");
            System.out.print(queue.isEmpty());
            System.out.println("\n");
        }  
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值