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

数组模拟队列和环形队列

作者: 茧铭 | 来源:发表于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];
    }
}

相关文章

  • 数据结构之队列

    什么是队列 队列是一个有序列表, 可以用数组或链表实现 先入先出 使用数组模拟队列和环形队列 用数组模拟队列 思路...

  • 数组模拟队列和环形队列

    方式均根据先进先出的思想,按照双指针的方式实现;首先指针一 rear 代表了队列尾端,每新增一个数据则放置在队列尾...

  • 数组模拟环形队列

    思路 代码 package com.atguigu.queue; import java.util.Scanner...

  • 数组模拟环形队列

  • 数组实现环形队列

    利用数组结构在队列的基础下用取模算法来实现环形队列。 环形队列拥有复用功能。 主要算法思想:1)front指向队列...

  • HDUOJ-1026 Ignatius and the Prin

    解题思路 广搜 使用队列来模拟广搜 数组模拟队列 使用1维数组来模拟队列,head为当前队列头,tail-1为当前...

  • 2020-11-10-数据结构与算法-14(队列scala版)

    1.队列 非环形实现 2.队列环形版 核心思想: 用%来模拟循环(rear +1) /maxsize = firs...

  • 循环队列

    顺序存储实现循环队列 使用数组模拟环形结构,数组大小为MAXQSIZE front表示队头元素 rear表示队尾元...

  • 数据结构

    稀疏数组 代码实现: 队列 代码实现: 环形队列 什么时候队列满:(rear+1)%maxsize == fron...

  • 数组环形队列

    规定: head 指向队列第一个元素;tail 指向队列最后一个元素的后一个位置。 几个问题 1. 为什么计算指针...

网友评论

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

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