Java实现循环队列

什么是循环队列

顺序队列在操作时容易暴露假溢出现象,为了解决假溢出现象,我们引入了循环队列,那我们应该怎么理解循环队列呢?

  1. 循环队列是把顺序队列首尾相连,把存储队列元素的表从逻辑上看成一个环,称为循环队列
    在这里插入图片描述

2.添加一个元素:(queue.rear+1) % queue.length //为什么取余?
3.删除一个元素:(queue.front+1) % queue.length
4.判断队列是否满:(queue.rear+1) % queue.length == queue.front
5.判断队列是否为空:queue.front == queue.rear


我们仔细观察一下图,当rear指针在下标6时,如果放在顺序队列是无法操作的,在循环队列中我们可以让他重新返回下标为1的位置,当read=6时,rear+1 = 7 % 7 = 0,我们这样操作只会让头尾指针在索引为6时跳转到0,并不会影响其他索引,比如front + 1 = 4 % 7 = 4,所以说取模操作可以方便快捷的使其成环


那么判断队列是否已满为什么那么操作呢?
在顺序队列中判空操作的是 if(头指针==尾指针),判断是否已满操作是if(头指针-尾指针 == 数组长度 ),但是在循环数组中可能会出现尾指针在头指针前,这是再相减不能返回正确的结果,因此我们这里采用当队列添加元素到rear的下一个元素是head的时候,也就是转圈子要碰头了,我们就认为队列满了


循环队列操作

1.自定义循环队列结构

class Queue{
    public int[] arr;
    int front;//头指针
    int rear;//尾指针
    int length;//记录数组长度
}

2.队列初始化

    public Queue InitQueue(int maxsize){
        Queue queue = new Queue();
        queue.arr = new int[maxsize];
        queue.front = 0;
        queue.rear = 0;
        queue.length = maxsize;
        return queue;
    }

3.判断队列是否为空

	/*
    * 判断队列是否为空,只需要判断头尾指针是否相同即可
    * 1为空,0不为空
    * */
    public int emptyQueue(Queue queue){
        if (queue.front == queue.rear){
            return 1;
        }
        return 0;
    }

4.判断队列长度

    /*
    * 在顺序队列时,我们要获取队列所有数据的长度,只要使头指针减尾指针即可
    * 但是在循环队列时,无法判断是头指针在前还是尾指针在前
    * 因此我们只要使两个指针相减,加上数组长度后取模即可得到数据长度
    * 如图所示
    * (6-3+7)%7 = 3
    * */
    public int length(Queue queue){
        return ((queue.rear - queue.front + queue.length) % queue.length);
    }

5.队列入队

    /*
    * 首先判断队列是否已满,如果满返回0
    * 使rear所指索引=data
    * rear移向下一位,如果移动到下一位后取余数组长度为0,相当于转了一圈从头开始
    * */
    public int EnQueue(Queue queue,int data){
        if ((queue.rear+1) % queue.length == queue.front) return 0;

        queue.arr[queue.rear] = data;
        queue.rear = (queue.rear+1) % queue.length;
        return 1;
    }

6.队列出队

    /*
    * 首先判断队列是否为空,如果空返回0
    * 和入队是语句一样,如果移动到下一位后取余数组长度为0,相当于转了一圈从头开始
    * 返回出队的值
    * */
    public int DeQueue(Queue queue){
        if (queue.rear == queue.front) return 0;
        int x = queue.arr[queue.front];
        queue.front = (queue.front+1) % queue.length;
        return x;
    }

7.取队头元素

    /*
    * 先判断队列是否为空,如果队列不为空,返回头指针所指元素
    * 因为不移动头指针,所以只会返回头指针的值,不会改变队列的值
    * */
    public int GetHead(Queue queue){
        if (queue.front != queue.rear) return queue.arr[queue.front];
        return 0;
    }

QueueDemoTest

public class QueueDemoTest {

    public static void main(String[] args) {
        QueueDemo queueDemo = new QueueDemo();
        Queue queue = queueDemo.InitQueue(7);
        queueDemo.EnQueue(queue,10);
        queueDemo.EnQueue(queue,20);
        queueDemo.EnQueue(queue,30);
        queueDemo.EnQueue(queue,40);
        System.out.println(queueDemo.length(queue));
        System.out.println(queueDemo.GetHead(queue));
        System.out.println(queueDemo.emptyQueue(queue));
        queueDemo.DeQueue(queue);
        System.out.println(queueDemo.length(queue));
        System.out.println(queueDemo.GetHead(queue));
    }
}
class QueueDemo{

    /*
    * 初始化队列
    * 头指针与尾指针相同,length属性记录数组长度
    * */
    public Queue InitQueue(int maxsize){
        Queue queue = new Queue();
        queue.arr = new int[maxsize];
        queue.front = 0;
        queue.rear = 0;
        queue.length = maxsize;
        return queue;
    }

    /*
    * 判断队列是否为空,只需要判断头尾指针是否相同即可
    * 1为空,0不为空
    * */
    public int emptyQueue(Queue queue){
        if (queue.front == queue.rear){
            return 1;
        }
        return 0;
    }

    /*
    * 在顺序队列时,我们要获取队列所有数据的长度,只要使头指针减尾指针即可
    * 但是在循环队列时,无法判断是头指针在前还是尾指针在前
    * 因此我们只要使两个指针相减,加上数组长度后取模即可得到数据长度
    * 如图所示
    * (6-3+7)%7 = 3
    * */
    public int length(Queue queue){
        return ((queue.rear - queue.front + queue.length) % queue.length);
    }

    /*
    * 首先判断队列是否已满,如果满返回0
    * 使rear所指索引=data
    * rear移向下一位,如果移动到下一位后取余数组长度为0,相当于转了一圈从头开始
    * */
    public int EnQueue(Queue queue,int data){
        if ((queue.rear+1) % queue.length == queue.front) return 0;

        queue.arr[queue.rear] = data;
        queue.rear = (queue.rear+1) % queue.length;
        return 1;
    }

    /*
    * 首先判断队列是否为空,如果空返回0
    * 和入队是语句一样,如果移动到下一位后取余数组长度为0,相当于转了一圈从头开始
    * 返回出队的值
    * */
    public int DeQueue(Queue queue){
        if (queue.rear == queue.front) return 0;
        int x = queue.arr[queue.front];
        queue.front = (queue.front+1) % queue.length;
        return x;
    }

    /*
    * 先判断队列是否为空,如果队列不为空,返回头指针所指元素
    * 因为不移动头指针,所以只会返回头指针的值,不会改变队列的值
    * */
    public int GetHead(Queue queue){
        if (queue.front != queue.rear) return queue.arr[queue.front];
        return 0;
    }
}
class Queue{
    public int[] arr;
    int front;//头指针
    int rear;//尾指针
    int length;
}
  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值