• 优先队列


    剑指offer面试题40 最小k个数:https://www.cnblogs.com/guoyu1/p/12164785.html

    剑指offer面试题41 数据流中的中位数:https://www.cnblogs.com/guoyu1/p/12274753.html

    1、优先队列的基本概念:

    在说明优先队列之前,先回顾普通队列,普通队列就是先插入的元素,先出队。

    优先队列和普通队列相比,允许元素插入后,并不按照插入的顺序弹出,而是按照优先级的顺序进行弹出,一般是先弹出最小元素。

    2、优先队列的基本操作:

    insert(插入)

    deleteMin(删除最小者):找到、返回、删除优先队列中的最小元素。

    3、优先队列的实现:

         优先队列有三种实现方式,分别是,正常数组、排序数组、二叉堆。其时间复杂度如下图

     (1)顺序数组实现:每次插入元素,都要对进行排序,删除元素只需要拿出数组第一个元素即可。时间复杂度:入队O(n),出队O(1)

    import javax.swing.plaf.synth.SynthOptionPaneUI;
    
    public class PriorityQueue {
        private int[] arr;
        //优先队列的长度,用于初始化数组
        private int Queuesize;
        //记录当前优先队列中存储的元素的个数,因为数组已经初始化长度就固定了,
        // 无法用.length方法去判断当前队列存了几个元素
        private int itemNum;
    
        //构造方法,给队列赋初始值
        public PriorityQueue(int size) {
            this.Queuesize = size;
            this.itemNum = 0;
            this.arr = new int[size];
        }
    
        //元素出队
        public int deleteMin() {
            int result;
            if (isEmpty()) {
                result = -1;
                System.out.println("队列为空,没有元素");
            } else {
                //队列非空,返回第一个元素,并删除
                result = arr[0];
                for (int i = 0; i < itemNum - 1; i++) {
                    arr[i] = arr[i + 1];
                }
                itemNum--;
            }
            return result;
        }
    
        //元素入队
        public void insert(int value) {
            //元素入队前先要检查优先队列是否已满
            if (isFull()) {
                //如果优先队列满了,就直接返回,不能插入
                System.out.println("优先队列已满");
            } else {
                //优先队列没有满,分两种情况:空队列,已有元素队列
                if (itemNum == 0) {
                    //空队列,直接添加元素即可
                    arr[0]=value;
                    itemNum++;
                } else {
                    //提前定义
                    int i;
                    //非空队列,对数组进行排序,从小到大排序,{1,2,3,5,6,7,0,0,0},插入元素4
                    for (i = itemNum - 1; i >= 0; i--) {
                        if (value < arr[i]) {
                            //如果发现value的值比队列已存元素小,说明当前值应该插入到已存元素之前,
                            // 因此,将arr[i]后的元素移位,{1,2,3,5,6,7,7,0,0}
                            arr[i + 1] = arr[i];
                        } else {
                            //比已存元素大,说明找对位置了{1,2,3,5,5,6,7,0,0}
                            //此时要停止循环,不然所有比value小的元素都被操作了
                            break;
                        }
                    }
                    arr[i + 1] = value;
                    itemNum++;
                }
            }
        }
    
        //检查优先队列已满方法
        public Boolean isFull() {
            return (itemNum == Queuesize);
        }
    
        //检查队列为空方法
        public Boolean isEmpty() {
            return (itemNum == 0);
        }
    
        public void display() {
            if(itemNum==0){
                System.out.println("空队列");
            }else{
                for (int i = 0; i < itemNum; i++) {
                    System.out.print(arr[i]+" ");
                }
                System.out.println();
            }
        }
    
        //测试队列是否正确
        public static void main(String[] args) {
            PriorityQueue p = new PriorityQueue(5);
            p.insert(1);
            p.insert(2);
            p.insert(7);
            p.insert(5);
            p.insert(4);
            p.display();
            p.insert(8);
            p.display();
            for (int i=0;i<6;i++){
                int value=p.deleteMin();
                System.out.println("出队元素"+value);
            }
            p.display();
        }
    }
    

     (2)二叉堆实现://TODO

    4、Java API

    import java.util.PriorityQueue;
    import java.util.Comparator;
    PriorityQueue<Integer> maxHeap = new PriorityQueue<Integer>(k, new Comparator<Integer>() {
    @Override
    public int compare(Integer o1, Integer o2) { return o2.compareTo(o1); } });
    peek()//返回队首元素
    poll()//返回队首元素,队首元素出队列
    add()//添加元素
    size()//返回队列元素个数
    isEmpty()//判断队列是否为空,为空返回true,不空返回false

    PriorityQueue的常用方法有:poll(),offer(Object),size(),peek()等。

    •   插入方法(offer()、poll()、remove() 、add() 方法)时间复杂度为O(log(n)) ;
    •   remove(Object) 和 contains(Object) 时间复杂度为O(n);
    •   检索方法(peek、element 和 size)时间复杂度为常量。
  • 相关阅读:
    Windows系统安装Anaconda
    python的下载及安装
    VMware的虚拟网络编辑器,在配置的过程中没有桥接模式!(虚拟机卸载)
    常见端口查询
    《网络攻防实践》第三次作业实践二
    用ssh方式在kali与Windows之间传输文件
    oracle常用函数汇总
    JSON 日期格式带 T 问题
    sql远程连接卡死解决方法
    DropdownList的处理总结
  • 原文地址:https://www.cnblogs.com/guoyu1/p/11881087.html
Copyright © 2020-2023  润新知