优先队列

一. 简介

  • 队列:先进先出,将新元素置于队尾,出队时,队头元素最先被移除。
  • 优先队列
    (1)最大优先队列:不管入队顺序如何,都是当前最大的元素优先出队;
    (1)最小优先队列:不管入队顺序如何,都是当前最小的元素优先出队。

二. 优先队列的实现

  • 二叉堆是实现堆排序和优先队列的基础。点此回顾二叉堆

  • 因二叉堆的“上浮”、“下沉”时间复杂度均为O(logn),所以优先队列的时间复杂度也是O(logn)。

  • 代码

    import java.util.Arrays;
    
    public class PriorityQueue {
        private int[] array;
        private int size;
        public PriorityQueue() {
            //队列的初始长度为32
            array = new int[32];
        }
    
        //队列扩容
        private void resize() {
            //队列扩容翻倍
            int newSize = this.size * 2;
            this.array = Arrays.copyOf(this.array, newSize);
        }
    
        //入队
        public void enQueue(int key) {
            //队列长度超出范围则扩容
            if (size >= array.length) {
                resize();
            }
            array[size++] = key;
            upAdjust();
        }
    
        //出队
        public int deQueue() throws Exception {
            if (size <= 0) {
                throw new Exception("队列是空的!");
            }
            //获取堆顶元素
            int head = array[0];
            //让最后一个元素移动到堆顶
            array[0] = array[--size];
            downAdjust();
            return head;
        }
    
        //"上浮"调整
        private void upAdjust() {
            int childIndex = size - 1;
            int parentIndex = (childIndex - 1) / 2;
            int temp = array[childIndex];
            while (childIndex > 0 && temp > array[parentIndex]) {
                array[childIndex] = array[parentIndex];
                childIndex = parentIndex;
                parentIndex = (parentIndex - 1) / 2;
            }
            array[childIndex] = temp;
        }
    
        //"下沉"调整
        private void downAdjust() {
            int parentIndex = 0;
            int temp = array[parentIndex];
            int childIndex = 1;
            while (childIndex < size) {
                //如果有右孩子,且右孩子的值大于左孩子的值,则定位到右haizi
                if (childIndex + 1 < size && array[childIndex+1] > array[childIndex]) {
                    childIndex++;
                }
                //如果父节点大于任何一个孩子的值,直接跳出
                if (temp >= array[childIndex]) {
                    break;
                }
                array[parentIndex] = array[childIndex];
                parentIndex = childIndex;
                childIndex = 2 * childIndex + 1;
            }
            array[parentIndex] = temp;
        }
    
        public static void main(String[] args) throws Exception {
            PriorityQueue priorityQueue = new PriorityQueue();
            priorityQueue.enQueue(3);
            priorityQueue.enQueue(5);
            priorityQueue.enQueue(10);
            priorityQueue.enQueue(2);
            priorityQueue.enQueue(7);
            System.out.println("出队元素:" + priorityQueue.deQueue());
            System.out.println("出队元素:" + priorityQueue.deQueue());
        }
    }
    
  • 运行结果

    出队元素:10
    出队元素:7
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值