[数据结构02]JAVA语言 队列、环形队列概述

转载自CSDN博主「飒飒蝴蝶谷」的原创文章
原文链接:https://blog.csdn.net/qq_42435377/article/details/107430578

队列

概述

有序列表,可以用数组、链表实现。先进先出原则。

队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。进行插入操作的端称为队尾,进行删除操作的端称为队头。(百度百科)

数组实现

需要一个maxSize来表示队列的长度

需要front、rear 记录队列的头和尾的数据的下标

数据加入队列

需要rear尾指针向后移,raer++

当raer = front 时,队列为空

当rear = maxSize - 1 时,队列满

数据出队列

先判断是否为空,然后弹出下标为 front+1 的下标的数据

代码实现

public class ArrayQueue {
    private int maxSize;
    private int front;
    private int rear;
    private int array[];

    public ArrayQueue(int maxSize) {
        this.maxSize = maxSize;
        front = -1;
        rear = -1;
        array = new int[maxSize];
    }
    //判断队列是否为空
    public boolean isEmpty(){
        return front == rear;
    }
    //判断队列是否满
    public boolean isFull(){
        return rear == maxSize - 1;
    }
    //向队列中添加数据
    public void addQueue(int num){
        if (isFull()){
            System.out.println("队列已满");
            return;
        }
        rear++;
        array[rear] = num;
    }
    //取出头部数据
    public int getQueue(){
        if (isEmpty()){
            throw new RuntimeException("队列为空");
        }
        front++;
        return array[front];
    }
    //展示所有数据
    public void showQueue() {
        if (isEmpty()){
            System.out.println("队列为空");
            return;
        }
        for (int i = 0; i < array.length; i++) {
            System.out.print(array[i]+"\t");
        }
        System.out.println();
    }
}

环形队列

上面的实现方法其实是有问题的,因为队列满了以后把数据取出来以后,后面的数据不会前移,这就会导致rear一直也不会前移,rear和maxSize一直相等,则不能再向其中添加数据

解决方法

maxsize: 预留一个位置出来作为缓冲区,可存储的数据数量 会比 实际数组的大小 减1

rear:指向最后一个元素的后一个位置,当超过maxsize的时候就指向0

front:始终指向第一个元素

满的条件:(rear+1)%maxsize == front

空的条件:rear == front

有效个数的计算: (rear +maxSize - front)%maxSize

代码实现

public class ArrayCircleQueue {
    private int maxSize;
    private int front;
    private int rear;
    private int array[];

    public ArrayCircleQueue(int maxSize) {
        this.maxSize = maxSize + 1;//因为“可存储的数据数量 会比 实际数组的大小 减1”,所以这里数组大小比你希望存储的数据的maxSize加1,后面用到maxSize的地方都是数组的maxSize
        front = 0;
        rear = 0;
        array = new int[this.maxSize];
    }
    //判断队列是否为空
    public boolean isEmpty(){
        return front == rear;
    }
    //判断队列是否满
    public boolean isFull(){
        return (rear + 1) % maxSize == front;
    }
    //向队列中添加数据
    public void addQueue(int num){
        if (isFull()){
            System.out.println("队列已满");
            return;
        }
        array[rear] = num;
        rear = (rear+1) % maxSize;
    }
    //取出头部数据
    public int getQueue(){
        if (isEmpty()){
            throw new RuntimeException("队列为空");
        }
        int f = array[front];
        front = (front+1)%maxSize;
        return f;
    }
    //展示所有数据
    public void showQueue() {
        if (isEmpty()){
            System.out.println("队列为空");
            return;
        }
        //循环从front即头部开始,循环getSize()次,即 有效数据的个数次
        for (int i = front; i < front + getSize(); i++) {
            //这里的输出数组的下标为 i % maxSize,,这样如果front为maxSize的情况下,取余之后,取得的下标即是0,也就是下一个元素
            System.out.print(array[i%maxSize]+"\t");
        }
        System.out.println();
    }
    //返回有效数据的个数
    public int getSize(){
        return (rear +maxSize - front) % maxSize;
    }
    public int getHead() {
        if (isEmpty()){
            throw new RuntimeException("队列为空");
        }
        return array[front];
    }
}

代码测试

public class QueueTest {
    public static void main(String[] args) {
        ArrayQueue arrayQueue = new ArrayQueue(3);
        arrayQueue.addQueue(1);
        arrayQueue.addQueue(2);
        arrayQueue.addQueue(3);
        arrayQueue.showQueue();
        System.out.println(arrayQueue.getQueue());
        System.out.println(arrayQueue.getQueue());
        System.out.println(arrayQueue.getQueue());
        arrayQueue.showQueue();
        System.out.println("================================");
        ArrayCircleQueue circleQueue = new ArrayCircleQueue(3);
        circleQueue.addQueue(1);
        circleQueue.addQueue(2);
        circleQueue.addQueue(3);
        circleQueue.showQueue();
        circleQueue.getQueue();
        circleQueue.addQueue(4);
        circleQueue.showQueue();

    }
}

执行结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值