数据结构(一):Java 数组实现环形队列

队列(Queue)

队列是一个有序的列表,可以使用数组或者链表来实现

  • 使用数组来实现的称为:顺序存储
  • 使用链表来实现的称为:链式存储

队列是遵循先进先出的原则,即:存入队列的数据,先存储的数据,会先取出来,后存储的数据,则后取出来
数据结构(一):Java 数组实现环形队列_第1张图片

(一) 思路分析

maxSize:表示该队列中最大的容量
front:队列头,用于指向队列第一个元素,并且初始化为0
rear:队列尾:用于指向队列中最后一个元素的后一个位置,并且初始化也为0
arr:用于存放存储的数据

注意:在环形队列中,需要约定数组中有一个空间不使用

(一)当队列为空时,应该满足front == rear的条件
数据结构(一):Java 数组实现环形队列_第2张图片

(二)当队列已满时,应该满足(rear + 1)% maxSize == front的条件
数据结构(一):Java 数组实现环形队列_第3张图片

(三)队列中有效的个数,应该满足(rear + maxSize - front)% maxSize的条件
数据结构(一):Java 数组实现环形队列_第4张图片

(四)队列头(front)每次移动,应该在队列不为空的情况下满足移动,即 (front + 1) % maxSize,防止数组的下标越界

(五)队列尾(rear)每次移动,应该在队列未满的情况下满足移动,即 (rear + 1) % maxSize,防止数组的下标越界

(二) 代码实现
public class CircleArrayQueue {
    private int maxSize; // 表示队列的最大容量
    private int front;   // 队列头,指队列有效个数的第一个元素
    private int rear;    // 队列尾,指队列最后一个元素的后一个位置
    private int[] arr;   // 该数组用于存放数据

  	// 测试
    public static void main(String[] args) {
        CircleArrayQueue queue = new CircleArrayQueue(5);

        // 1. 存入数据
        queue.addQueue(10);
        queue.addQueue(20);
        queue.addQueue(30);
        queue.addQueue(40);
        queue.addQueue(50);

        // 2. 获取头数据
        System.out.println("头数据:" + queue.getHeadQueue());

        // 3. 取出数据
        System.out.println(queue.getQueue());
        System.out.println(queue.getQueue());
        System.out.println(queue.getQueue());
        System.out.println(queue.getQueue());
        System.out.println(queue.getQueue());
    }

    /**
     * 1. 创建队列构造器,用于初始化队列的参数
     * @param maxSize 队列最大容量
     */
    public CircleArrayQueue(int maxSize) {
        this.maxSize = maxSize;
        arr = new int[maxSize];
    }

    /**
     * 2. 创建判断队列是否已满的方法
     * @return boolean
     */
    public boolean isFull(){
        return (rear + 1) % maxSize == front;
    }

    /**
     * 3. 创建判断队列是否为空的方法
     * @return boolean
     */
    public boolean isEmpty(){
        return rear == front;
    }

    /**
     * 4. 添加队列的方法
     * @param n 数据
     */
    public void addQueue(int n){
        // 判断队列是否已满
        if (isFull()) {
            System.out.println("队列已满,不能加入数据");
            return;
        }

      	// 输出每次添加队列 队列尾的下标
        System.out.println("addQueue rear = " + rear);

        // 直接将数据加入
        arr[rear] = n;
        // 尾指针后移,并且需要考虑取模,防止下标越界
        rear = (rear + 1) % maxSize;
    }

    /**
     * 5. 获取队列数据
     * @return int
     */
    public int getQueue(){
        // 判断队列是否为空
        if (isEmpty()) {
            throw new ArrayIndexOutOfBoundsException("队列为空,不能获取数据");
        }

      	// 输出每次添加队列 队列头的下标
        System.out.println("getQueue front = " + front);

        // front指向队列的第一个元素
        // 1. 将front对应的值保存到临时的变量
        int value = arr[front];
        // 2. 将头指针后移,并且需要考虑取模,防止下标越界
        front = (front + 1) % maxSize;
        return value;
    }

    /**
     * 6. 获取队列的有效个数
     * @return int
     */
    public int getSize(){
        return (rear + maxSize - front) % maxSize;
    }

    /**
     * 7. 显示队列所有数据
     */
    public void showQueue(){
        // 判断队列是否为空
        if (isEmpty()) {
            System.out.println("队列为空");
            return;
        }

        // 遍历队列
        System.out.print("遍历数据:");
        for (int i = front; i < front + getSize(); i++) {
            System.out.print("下标:" + (i % maxSize) + ",值为:" + arr[i % maxSize]);
        }
    }

    /**
     * 8. 获取头数据
     * @return int
     */
    public int getHeadQueue(){
        // // 判断队列是否为空
        if (isEmpty()) {
            throw new ArrayIndexOutOfBoundsException("队列为空,不能获取数据");
        }
        return arr[front];
    }
}

你可能感兴趣的:(JAVA,java,数据结构,算法)