优先队列

一、优先队列

      定义:优先队列出队时,时根据优先级的高低出队,优先级高的先出,优先队列实现原理根据堆实现

      分类:最大优先队列,可以获取并删除队列中最大的元素 (大根堆)

                  最小优先队列,可以获取并删除队列中最小的元素(小根堆)

 

1.例:最大优先队列

public class MaxPriorityQueue<T extends Comparable<T>> {
    //存储堆中的元素
    private T[] items;
    //记录元素的个数
    int N;
    //初始化
    public MaxPriorityQueue(int capacity) {
        this.items= (T[]) new Comparable[capacity+1];
        this.N=0;
    }
    //获取队中元素的个数
    public int size(){
        return N;
    }
    //判断队是否为空
    public boolean isEmpty(){
        return N==0;
    }
    //判断索引i和j处值的大小
    public boolean less(int i,int j){
        return items[i].compareTo(items[j])<0;
    }
    //交换索引i和j处的zhi
    public void exch(int i,int j){
        T temp=items[i];
        items[i]=items[j];
        items[j]=temp;
    }
    //在堆中插入一个元素
    public void insert(T t){
        //元素直接插入最大索引处
        items[++N]=t;
        //上浮操作
        swim(N);
    }
    //上浮调整
    private void swim(int k) {
        while (k>1){
            if (less(k/2,k)){
                exch(k/2,k);
            }
            k=k/2;
        }
    }
    //从堆中删除一个元素,并返回
    public T delete(){
        //获得最大元素,为根处的元素
        T max= items[1];
        //将根处的元素于最大索引处的元素交换
        exch(1,N);
        //删除最大元素
        N--;
        //进行下沉调整,使得最大元素到根位置。
        sink(1);
        return max;
    }
    //下沉操作
    private void sink(int k) {
        while (2*k<=N){
            int max;
            if (2*k+1<=N){
                if (less(2*k,2*k+1)){
                    max=2*k+1;
                }else {
                    max=2*k;
                }
            }else {
                max=2*k;
            }

            if (!less(k,max)){
                break;
            }
            exch(k,max);
            k=max;
        }
    }
}

2.例:最小优先队列

public class MinPriorityQueue<T extends Comparable<T>> {
    //存储元素
    private T[] items;
    //元素的个数
    private int N;
    //初始化
    public MinPriorityQueue(int capacity) {
        this.items= (T[]) new Comparable[capacity+1];
        this.N=0;
    }
    //判断队列是否为空
    public boolean isEmpty(){
        return N==0;
    }
    //队列的大小
    public int size(){
        return N;
    }
    //比较索引i和j处的值的大小
    public boolean less(int i,int j){
        return items[i].compareTo(items[j])<0;
    }
    //交换索引i和j处的值
    public void exch(int i,int j){
        T temp =items[i];
        items[i]=items[j];
        items[j]=temp;
    }
    //向队列中插入元素
    public void insert(T t){
        items[++N]=t;
        //上浮调整
        swin(N);
    }
     //上浮操作
    private void swin(int k) {
        while (k>1){
            if (less(k,k/2)){
                exch(k,k/2);
            }
            k=k/2;
        }
    }

    //删除队列中的最小元素,并返回
    public T delete(){
        T min=items[1];
        exch(1,N);
        N--;
        sink(1);
        return min;
    }

    private void sink(int k) {

        while (2*k<=N){
            int min;
            if (2*k+1<=N){
                if (less(2*k,2*k+1)){
                    min=2*k;
                }else {
                    min=2*k+1;
                }
            }else {
                min=2*k;
            }

            if (less(k,min)){
                break;
            }
            exch(k,min);
            k=min;
        }
    }
}

 

posted @ 2020-03-29 13:20  撑起一片阳光  阅读(255)  评论(0编辑  收藏  举报