利用数组实现队列

 1.简介

队列是一个有序列表,属于线性结构的一种,遵循先进先出原则

示意图:(使用数组模拟队列示意图)
标使用数组模拟队列示意图题

 2.数组模拟队列

第一种实现思路

示意图:(使用数组模拟队列示意图)
标使用数组模拟队列示意图题

如上图所示,MaxSize为我们数组的长度,rear为我们末尾指针,front为我们的头指针,当我们向队列中放数据的时候,我们的rear指针不断向后移动,取数据的时候,front指针向后移动

这样看我们需要四个参数

1.最大容量maxSize 

2.头指针,front

3.尾指针,rear

4.数组,queue

啥时候数组为空,rear==front

啥时候数组为满,maxSize-1 ==rear

代码如下

class ArrayQueue {
    private int maxSize; //数组的最大容量
    private int front; //队列头指针
    private int rear;  //队列尾指针
    private int[] queue; //数组

    //创建队列的构造器
    public ArrayQueue(int maxSize) {
        this.maxSize = maxSize;
        queue = new int[maxSize];
        front = -1; //指向队列头部,分析出front是指向队列头的前一个位置
        rear = -1;  //指向队列尾部,即队列最后一个数据
    }

    // 判断队列是否已满
    public boolean isFull() {
        return rear == maxSize - 1;
    }

    //判断队列是否为空
    public boolean isEmpty() {
        return rear == front;
    }

    //添加数据到队列
    public void addQueue(int n) {
        //判断队列是否已满
        if (isFull()) {
            System.out.println("队列已满,不能加入数据了");
            return;
        }
        rear++; //让rear后移
        queue[rear] = n;
    }

    // 获取队列的数据,出队列
    public int getQueue() {
        //判断队列是否为空
        if (isEmpty()) {
            //跑出异常
            throw new RuntimeException("队列空,不能取数据");
        }
        front++; //front后移
        return queue[front];
    }

}

这样做有什么问题?

一次性队列,使用一次达到maxSize就无法再次入队了,如果我们每出队一个元素,我们就将数组中的元素向前移一位,这样好不好,显然不可取,首先,我们移动数组中元素时候,效率很低,其次移动数组的时候,我们的末尾指针会发生变化,这个时候向数组中放入元素的时候,可能会错位,所以我们用环形数组来优化,是这个队列达到复用的效果。

第二种实现思路

 1.什么时候代表这个队列已满?

头指针在尾指针后面一个时候,代表队列已满 (tail+1)%maxSize==head,因为末尾指针在11的时候,头指针在0的情况

2.什么时候代表这个队列为空?

头指针位置等于尾指针位置时,代表队列为空 head==tail

3.队列有效数字的长度     

(tail+maxSize-head)%maxSize,因为会出现tail比head小的情况

代码如下

class RingQueue{
    //最大容量
    private int maxSize;
    //头指针
    private int head;
    //末尾指针
    private int tail;
    //数组
    private int[] arr;

    public RingQueue(int maxSize){
        this.maxSize=maxSize;
        this.arr = new int[maxSize];
    }

    /**
     * 判断是不是队列是不是空
     * //什么时候代表这个队列为空? 头指针位置等于尾指针位置时,代表队列为空  head==tail
     * @return
     */
    public boolean isEmpty(){
        return head==tail;
    }

    /**
     * 判断队列是否已满
     * //什么时候代表这个队列已满? 头指针在尾指针后面一个时候,代表队列已满  (tail+1)%maxSize==head
     */
    public boolean isFull(){
        return (tail+1)%maxSize==head;
    }

    /**
     * 队列中的有效数组
     * //队列有效数字的长度   (tail+maxSize-head)%maxSize
     */
    public int length(){
        return (tail+maxSize-head)%maxSize;
    }

    /**
     * 添加 先判断是否已满,未满的话移动尾指针
     * @param obj
     * @return
     */
    public boolean add(int obj){
        if(isFull()){
            System.out.println("队列已满");
            return false;
        }
        arr[tail] = obj;
        tail = (tail+1)%maxSize;
        return true;
    }

    /**
     * 获取数据,没有则为空
     * @return
     */
    public Integer get(){
        if(isEmpty()){
            System.out.println("队列为空");
            return null;
        }
        int value = arr[head];
        head = (head+1)%maxSize;
        return value;
    }
}

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值