优先队列

时间:2019-11-18
本文章向大家介绍优先队列,主要包括优先队列使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

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

原文地址:https://www.cnblogs.com/guoyu1/p/11881087.html