基于数组的循环队列

基于数组的循环队列关键点在于:当元素总数达到队列的阈值后,出队、入队等行为如何避免数组越界问题

循环数组的逻辑结构可以类比时钟,当指针走到最后一个刻度(比如12小时制的12点),再往前走时,指针会回到最开始的刻度(即1点),而不是继续前进到一个不存在的位置。

 

12 小时制 时钟为例,时钟的循环特性可以通过 线性取余 来类比,取余操作有效地实现了“溢出之后重新开始”的效果。下面是如何通过线性取余来类比时钟循环下一个 12 小时的步骤。

时钟与线性取余的类比:

  1. 时钟的循环特性
    • 12 小时制时钟从 1 点到 12 点循环。当到达 12 点后,再前进一个小时,它会回到 1 点,而不是 13 点。
    • 对于任何时刻,时钟上的下一个时间点可以通过 当前时间 + 1 来计算,但如果超过 12 点,需要回绕到 1 点。
  2. 取余的数学表示
    • 如果当前时间是 h,我们可以使用 (h + 1) % 12 来计算下一个小时。取余操作保证了时间在 1 到 12 之间循环。

 

由此可知,循环数组的head指针tail指针,都可以通过取余的方式实现循环步进。

 

查看代码
 public class Main {
    public static void main(String[] args) {
        System.out.println("pop 出队");
        System.out.println("push 入队");
        System.out.println("show 展示队列数据");
        System.out.println("exit 结束程序");
        CycleQueue queue = new CycleQueue(5);
        Scanner outer = new Scanner(System.in);
        Scanner inner = new Scanner(System.in);
        System.out.println("------------------  read?  go!  ------------------");
        while (true) {
            String command = outer.nextLine();
            if ("pop".equals(command)) {
                try {
                    int value = queue.pop();
                    System.out.println(value);
                } catch (Exception e) {
                    System.out.println(e.getMessage());
                }
            } else if ("push".equals(command)) {
                int value = inner.nextInt();
                queue.push(value);
            } else if ("show".equals(command)) {
                queue.show();
            } else if ("exit".equals(command)) {
                break;
            } else {
                System.out.println("不支持的操作");
            }
        }
        System.out.println("------------------over------------------");
    }

    static class CycleQueue {
        // 头指针
        private int head;
        // 尾指针
        private int tail;
        private int size;
        private int[] arr;

        public CycleQueue(int i) {
            size = i;
            arr = new int[size];
        }

        public boolean isFull() {
            return (tail + 1) % size == head;
        }

        public boolean isEmpty() {
            return head == tail;
        }

        /**
         * 出队
         */
        public int pop() {
            if (isEmpty()) {
                throw new RuntimeException("队列为空~");
            }
            int res = arr[head];
            head = (head + 1) % size;
            return res;
        }

        /**
         * 入队
         */
        public void push(int i) {
            if (isFull()) {
                System.out.println("队列已满~");
                return;
            }
            arr[tail] = i;
            tail = (tail + 1) % size;
        }

        public void show() {
            if (isEmpty()) {
                System.out.println("队列为空,无数据~");
                return;
            }

//            System.out.println("队列中的数据为:");
            // 计算队列中的元素数量
            int count = (tail - head + size) % size;

            // 通过循环展示所有数据
            for (int i = 0; i < count; i++) {
                int index = (head + i) % size;
                System.out.printf("arr[%d] = %d\n", index, arr[index]);
            }
        }

    }
}

 

posted @ 2024-09-10 19:02  Ashe|||^_^  阅读(7)  评论(0编辑  收藏  举报