java数据结构——队列

1.概述

上一篇博客我们拒了羽毛球筒的例子来类比栈这种数据结构,这次我们用排队这种模型来类比我们接下来要说的数据结构——队列。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。

队列的数据元素又称为队列元素。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除,故队列又称为先进先出(FIFO—first in first out)线性表。

我们拿单向队列举例。
入队示例:
在这里插入图片描述
出队示例:

在这里插入图片描述
队列分为:
①、单向队列(Queue):只能在一端插入数据,另一端删除数据。
②、双向队列(Deque):每一端都可以进行插入数据和删除数据操作。
③、优先级队列(Priority):优先级队列是比栈和队列更专用的数据结构,在优先级队列中,数据项按照关键字进行排序,关键字最小(或者最大)的数据项往往在队列的最前面,而数据项在插入的时候都会插入到合适的位置以确保队列的有序。

2.数组实现简单的单向队列


public class ArrayQueue {

    private final Object[] data;

    private final int maxSize;

    private int currentSize;

    private int front;

    private int tail;

    public ArrayQueue(int maxSize){
         if (maxSize <= 0) {
            throw new IllegalArgumentException("容量应该大于0 : " + maxSize);
        }
        this.maxSize = maxSize;
        data = new Object[this.maxSize];
        this.front = -1;
        this.tail = -1;
        this.currentSize = 0;
    }

    public void insert(Object obj){
        if(currentSize == maxSize){
            throw new IllegalArgumentException("队列已经满了,不能插入数据");
        }else{
            if(tail == -1 && front == -1 ){  //为空的时候,当remove掉最后一个元素的时候将front和tail都重置
                front ++;
                tail ++;
                currentSize++;
                data[front] = obj;
            }else{
                tail = (tail+1)%maxSize;
                currentSize++;
                data[tail] = obj;
            }
        }
    }

    public Object remove(){
        Object rtn = null;
        if(currentSize == 1){
            currentSize--;
            rtn = data[front];   /*先取值*/
            data[front] = null;
            front = -1;
            tail = -1;
        }else if(currentSize >1){
            currentSize--;
            rtn = data[front];
            data[front] = null;
            front = (front+1)%maxSize;

        }
        return rtn;
    }

    public boolean isEmpty(){
        return currentSize ==0;
    }

    public boolean isFull(){
        return currentSize == maxSize;
    }

    public void display(){
        if(isEmpty()){
            System.out.print("队列为空");
        }else{
            System.out.print("[ ");
            for(Object o : data){
                System.out.print(o+" ");
            }
            System.out.print(" ]");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        ArrayQueue arrayQueue = new ArrayQueue(5);
        arrayQueue.insert("0");
        arrayQueue.insert("1");
        arrayQueue.insert("2");
        arrayQueue.insert("3");
        arrayQueue.insert("4");
        arrayQueue.display();

        System.out.println("//");
        System.out.println(arrayQueue.remove());
        System.out.println(arrayQueue.remove());
        arrayQueue.display();

        System.out.println("//");
        arrayQueue.insert("5");
        arrayQueue.display();

        System.out.println("//");
        System.out.println(arrayQueue.remove());
        System.out.println(arrayQueue.remove());
        System.out.println(arrayQueue.remove());
        arrayQueue.display();

        System.out.println("//");
        arrayQueue.insert("6");
        arrayQueue.display();

    }


}

输出
[ 0 1 2 3 4 ]
//
0
1
[ null null 2 3 4 ]
//
[ 5 null 2 3 4 ]
//
2
3
4
[ 5 null null null null ]
//
[ 5 6 null null null ]

3.双端队列

双端队列就是一个两端都是结尾或者开头的队列, 队列的每一端都可以进行插入数据项和移除数据项,这些方法可以叫做:insertRight()、insertLeft()、removeLeft()、removeRight()
1)如果严格禁止调用insertLeft()和removeLeft()(或禁用右端操作),那么双端队列的功能就和前面讲的栈功能一样。
2)如果严格禁止调用insertLeft()和removeRight(或相反的另一对方法),那么双端队列的功能就和单向队列一样了。

4.数组实现简单的优先级队列(数字越大优先级越高,优先remove最大的)

public class PriorityArrayQueue {

    private final int size;

    private final int[] data;

    private int currentSize;

    public PriorityArrayQueue(int size){
        if(size <=0){
            throw new IllegalArgumentException("容量应该大于0 : " + size);
        }
        this.size = size;
        data = new int[this.size];
        currentSize = 0;
    }

    public void insert(int value){
        if(value < 0){
            System.out.println("不允许添加小于0的数");
        }
        if(currentSize == size){
            System.out.println("队列已经满了");
        }else if(currentSize == 0){
            data[0] = value;
            currentSize++;
        }else{
            data[currentSize] = value;
            for (int i = 0; i < currentSize; i++) {
                if(data[currentSize]<data[i]){
                    int tmp = data[currentSize];
                    data[currentSize] = data[i];
                    data[i] = tmp;
                }
            }
            currentSize++;
        }
    }


    public int remove(){
        int rtn = -1;
        if(currentSize > 0){
            rtn = data[currentSize-1];
            data[currentSize-1] = -1;
            currentSize--;
        }
        return rtn;
    }

    public void display(){
        if(currentSize == 0){
            System.out.println("队列为空");
        }
        System.out.print("[ ");
        for(int i : data){
            System.out.print(i+" ");
        }
        System.out.print(" ]");
                System.out.println();
    }


    public static void main(String[] args) {
        PriorityArrayQueue priorityArrayQueue = new PriorityArrayQueue(3);

        priorityArrayQueue.insert(4);
        priorityArrayQueue.insert(2);
        priorityArrayQueue.insert(1);
        priorityArrayQueue.display();
        System.out.println("/");

        priorityArrayQueue.remove();
        priorityArrayQueue.display();
        System.out.println("/");
    }
}

输出
[ 1 2 4 ]
/
[ 1 2 -1 ]
/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值