admin管理员组

文章数量:1794759

数据结构之环形队列

数组模拟环形队列

对前面的数组模拟队列的优化,充分利用数组,因此将数组看做是一个环形的。(通过取模的方式来实现即可)

  • 分析说明:
    1. 尾索引的下一个为头索引时表示队列满,即将队列容量空出一个作为约定,这个在做判断队列满的时候需要注意 (rear + 1) % maxSize == front 满]
    2. rear == front [空]
    3. 测试示意图:

代码实现

代码语言:javascript代码运行次数:0运行复制
package cn.tedu.queue;

import java.util.Scanner;

/**
 * @author keke
 * @version 1.0
 * @className CircleArrayQueueDemo
 * @description
 * @time 2023/5/30 21:55
 */
public class CircleArrayQueueDemo {

    public static void main(String[] args) {
        // 创建一个队列
        // 说明设置4,其队列的有效数据最大是3
        CircleArrayQueue<Integer> circleArrayQueue = new CircleArrayQueue<>(4);
        char key = ' ';
        Scanner scanner = new Scanner(System.in);
        boolean loop = true;
        while (loop){
            System.out.println("s(show):显示队列");
            System.out.println("e(exit):退出程序");
            System.out.println("a(add):添加数据到队列");
            System.out.println("g(get):从队列取出数据");
            System.out.println("h(head):查看队列头的数据");
            System.out.print("请输入菜单首字母:");
            key = scanner.next().charAt(0);
            switch (key){
                case 's':
                    circleArrayQueue.showQueue();
                    break;
                case 'a':
                    System.out.print("请输入一个数:");
                    circleArrayQueue.addQueue(scanner.nextInt());
                    break;
                case 'g':
                    try {
                        System.out.println("取出的数据是:" + circleArrayQueue.getQueue());
                    } catch (Exception e){
                        System.out.println(e.getMessage());
                    }
                    break;
                case 'h':
                    try {
                        System.out.println("队列头的数据是:" + circleArrayQueue.headQueue());
                    } catch (Exception e){
                        System.out.println(e.getMessage());
                    }
                    break;
                case 'e':
                    scanner.close();
                    loop = false;
                    break;
            }
        }
        System.out.println("程序退出");
    }
}

class CircleArrayQueue<T>{

    /**
     * 数组的最大容量
     */
    private final int maxSize;

    /**
     * 队列头:
     * front 变量的含义做一个调整: front 就指向队列的第一个元素,
     * 也就是说 arr[front] 就是队列的第一个元素,front 的初始值 = 0
     *
     */
    private int front;

    /**
     * 队列尾:
     * rear 变量的含义做一个调整:rear 指向队列的最后一个元素的后一个位置.
     * 因为希望空出一个空间做为约定,rear 的初始值 = 0
     */
    private int rear;

    /**
     * 用于存放数据,模拟队列
     */
    private T[] arr;

    public CircleArrayQueue(int maxSize) {
        this.maxSize = maxSize;
        arr = (T[]) new Object[maxSize];
    }

    /**
     * 判断队列是否满
     */
    public boolean isFull() {
        return (rear + 1) % maxSize == front;
    }

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

    /**
     * 添加数据到队列
     *
     * @param n
     */
    public void addQueue(T n) {
        // 判断队列是否满
        if (isFull()) {
            System.out.println("队列满,不能加入数据");
            return;
        }
        // 直接将数据加入
        arr[rear] = n;
        // 将 rear 后移,必须考虑取模
        rear = (rear + 1) % maxSize;
    }

    /**
     * 获取队列的数据,出队列
     * @return
     */
    public T getQueue() {
        // 判断队列是否为空
        if (isEmpty()) {
            // 通过异常抛出
            throw new RuntimeException("队列空,不能取数据");
        }
        // 这里分析出 front 是指向队列的第一个元素
        // 1.先把 front 对应的保留到一个临时变量
        T value = arr[front];
        // 2.将 front 后移,考虑取模
        front = (front + 1) % maxSize;
        // 将临时变量返回
        return value;
    }

    /**
     * 显示队列的所有数据
     */
    public void showQueue() {
        // 遍历
        if (isEmpty()) {
            System.out.println("队列空的,没有数据");
            return;
        }
        // 从 front 开始遍历,遍历多少个元素
        for (int i = front; i < front + size(); i++){
            System.out.printf("arr[%d] = %s\n", i % maxSize, arr[i % maxSize]);
        }
    }

    /**
     * 当前队列有效数据的个数
     * @return
     */
    public int size(){
        return (rear + maxSize - front) % maxSize;
    }

    /**
     * 显示队列的头部,注意不是取出数据
     *
     * @return
     */
    public T headQueue() {
        // 判断
        if (isEmpty()) {
            throw new RuntimeException("队列空的,没有数据");
        }
        return arr[front];
    }

}

截图

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2023-05-30,如有侵权请联系 cloudcommunity@tencent 删除数据数组数据结构变量队列

本文标签: 数据结构之环形队列