数据结构与算法之环形队列

数据结构和算法之队列基本概念
数据结构和算法之数组队列

一、什么是环形队列

还记得我们之前数组队列存在的空间浪费问题吗?简单来讲就是:元素出队后的空间无法被二次利用。因为数组队列一直是队尾++。环形队列正是解决此问题的,他存在固定大小,且当队尾指针指向到队列最后位置的时候,再有新元素进来的话会重新放到前面出队的时候预留的空间上。

二、图解环形队列

1、空队列

在这里插入图片描述

2、元素A入队

在这里插入图片描述

3、元素BCD入队

在这里插入图片描述

4、元素AB出队

在这里插入图片描述

到目前位置一切正常,也一切如我们所愿,很简单粗暴。那么接下来E元素入队呢?tail指针该何去何从?

5、元素E入队

![在这里插入图片描述](https://img-blog.csdnimg.cn/20191216163804573.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2N0d2N0dw==,size_16,color_FFFFFF,t_70

注意tail指针指向的是索引为0的位置,计算公式为:(tail + 1) % 队列容量

6、元素F入队

在这里插入图片描述

7、环形队列总结

  • front指向当前队首元素,tail指向最后一个元素的下一个位置
  • 入队公式:(tail + 1) % 队列容量
  • 出队公式: (front + 1) % 队列容量
  • 队空条件:front == tail
  • 队满条件:(tail + 1) % 队列容量 == front
  • 当前队列有效元素个数:(tail+ 队列容量 - front) % 队列容量;

三、coding

class CircleArray {
    // 数组最大容量
    private int maxSize;
    // front指向队列的第一个元素,也就是说arr[front],初始值为0
    private int front;
    // rear指向队列的最后一个元素的后一个位置,因为希望空出一个位置作为约定,初始值为0
    private int rear;
    // 存放数据
    private int arr[];

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

    // isFull
    public boolean isFull() {
        return (rear + 1) % maxSize == front;
    }

    // isEmpty
    public boolean isEmpty() {
        return front == rear;
    }

    // addQueue
    public void addQueue(int data) {
        if (isFull()) {
            throw new RuntimeException("full");
        }
        // 直接将数据加入即可
        arr[rear] = data;
        // 将rear后移一位,这里必须考虑取模,因为如果rear到最后一位了,但是前面还有空间,所以需要取模,否则数组越界
        rear = (rear + 1) % maxSize;
    }

    // getQueue
    public int getQueue() {
        if (isEmpty()) {
            throw new RuntimeException("empty");
        }
        // 这里需要分析出front是指向队列的第一个元素
        // 1.先把front对应的值保存到一个临时变量
        // 2.将front后移,取模,否则数组越界
        // 3.将临时保存的变量返回
        int value = arr[front];
        front = (front + 1) % maxSize;
        return value;
    }

    // showQueue
    public void showQueue() {
        if (isEmpty()) {
            return;
        }
        // 从front开始遍历,遍历多少个元素?
        for (int i = front; i < front + size(); i++) {
            System.out.printf("arr[%d]=%d\n", i % maxSize, arr[i]);
        }
    }

    // 获取当前队列有效数据的个数
    public int size() {
        // 1, 3, 0    =   1
        return (rear + maxSize - front) % maxSize;
    }

    // headQueue
    public int headQueue() {
        if (isEmpty()) {
            throw new RuntimeException("empty");
        }
        return arr[front];
    }
}
发布了28 篇原创文章 · 获赞 33 · 访问量 8302

猜你喜欢

转载自blog.csdn.net/ctwctw/article/details/103564478