美文网首页
数组模拟队列和环形队列

数组模拟队列和环形队列

作者: 茧铭 | 来源:发表于2020-05-13 12:55 被阅读0次

    方式均根据先进先出的思想,按照双指针的方式实现;
        首先指针一 rear 代表了队列尾端,每新增一个数据则放置在队列尾部,同时rear的值增加1;
        其次指针二 front 代表了队列的头部,每取出一个数据,则将队列头部的一个值拿出去,并使front的值加1;
        然后是 maxSize ,它代表了数组的长度,限制队列所能承载的数据量。

    1、用数组模拟队列

    分析:
    front 指向队列头的前一个位置
    rear指向队列尾的数据的实际位置。它们的初始值都是 -1
    队列满的条件: rear + 1 = maxSize
    队列空的条件: rear == front

    /**
     * front和rear分别记录队列前后端的下标--双指针标记
     * front随着数据输出而改变,rear随着数据输入而改变
     */
    class ArrQueue implements MyQueue {
        /** 表达数组的最大容量 */
        private int maxSize;
    
        /** 队列头 实际指向队列头的前一个位置*/
        private int front;
    
        /** 队列尾 实际指向队列尾的当前位置*/
        private int rear;
    
        /** 用于存放数据,模拟队列 */
        private int[] arr;
    
        public ArrQueue(int maxSize){
            this.maxSize = maxSize;
            arr = new int[maxSize];
            front = -1;
            rear = -1;
        }
    
        // 判断队列是否满
        public boolean isFull(){
            return rear == maxSize - 1;
        }
    
        // 判断队列是否为空
        public boolean isEmpty(){
            return rear == front;
        }
    
        // 添加数据到队列
        public void addQueue(int n){
            if (isFull()){
                throw new RuntimeException("队列已满,不能加入数据");
            }
            arr[++rear] = n;
        }
    
        // 数据出列
        public int pop(){
            if (isEmpty()){
                throw new RuntimeException("队列为空,没有可以获取的数据");
            }
            return arr[++front];
        }
    
        // 显示队列的所有数据
        public void show(){
            if (isEmpty()){
                System.out.println("队列为空,没有数据展示");
                return;
            }
            for (int i = 0; i < arr.length; i++) {
                System.out.printf("arr[%d]=%d\n", i, arr[i]);
            }
        }
    
        // 显示队列的头数据,不是显示
        public int head(){
            if (isEmpty()){
                throw new RuntimeException("队列是空的喔");
            }
            return arr[front + 1];
        }
    }
    
    

    2、数组实现环形队列

    分析: front的值修改一下,front 指向队列头的数据的实际位置。
    rear 指向队列尾的实际位置的后一个位置。并且rear和front的初始值为0
    并且默认希望空出一个空间不能存放数据,是因为如果不空闲空间,那么队列满和队列为空的条件会发生冲突,因此队列满的条件应该如下:
    队列满: (rear + 1) % maxSize == front
    队列空: rear == front
    队列中有效数据的个数是:( rear + maxSize - front ) % maxSize
    代码如下

    /**
     * front和rear分别记录队列前后端的下标--双指针标记
     * front随着数据输出而改变,rear随着数据输入而改变
     * front和rear的后移需要考虑取模
     */
    class CirCleQueue implements MyQueue{
        /** 表达数组的最大容量 */
        private int maxSize;
    
        /** 队列头 实际指向队列头元素的当前位置*/
        private int front;
    
        /** 队列尾 实际指向队列尾元素的后一个位置*/
        private int rear;
    
        /** 用于存放数据,模拟队列 */
        private int[] arr;
    
        public CirCleQueue(int maxSize){
            this.maxSize = maxSize;
            arr = new int[maxSize];
            front = 0;
            rear = 0;
        }
    
        // 判断队列是否满
        public boolean isFull(){
            return ((rear + 1) % maxSize) == front;
        }
    
        // 判断队列是否为空
        public boolean isEmpty(){
            return rear == front;
        }
    
        // 添加数据到队列
        public void addQueue(int n){
            if (isFull()){
                throw new RuntimeException("队列已满,不能加入数据");
            }
            arr[rear] = n;
            // 此时rear需要后移,可能因为取模到前面来
            rear++;
            rear = rear % maxSize;
            System.out.println("rear的值是:" + rear);
        }
    
        // 数据出列
        public int pop(){
            if (isEmpty()){
                throw new RuntimeException("队列为空,没有可以获取的数据");
            }
            int i = arr[front];
            // 修改 front的值
            front++;
            front = front % maxSize;
            System.out.println("front 的值是:" + front);
            return i;
        }
    
        // 因为可以循环使用,因此显示队列的所有数据是从front开始,遍历剩下的所有元素
        public void show(){
            if (isEmpty()){
                System.out.println("队列为空,没有数据展示");
                return;
            }
            // 遍历有效数据的个数那么多个,如下面的方法
            for (int i = front; i < (front + effective()); i++) {
                int num = i %  maxSize;
                System.out.printf("arr[%d] = %d\n", num, arr[num]);
            }
        }
    
        // 求出有效数据的个数
        public int effective(){
            return (rear + maxSize - front) % maxSize;
        }
    
        // 显示队列的头数据,不是显示
        public int head(){
            if (isEmpty()){
                throw new RuntimeException("队列是空的喔");
            }
            return arr[front];
        }
    }
    

    相关文章

      网友评论

          本文标题:数组模拟队列和环形队列

          本文链接:https://www.haomeiwen.com/subject/dhknnhtx.html