Skip to content
生如风生如风
主页
github icon
  • 队列
    • 队列介绍
      • 数组实现队列
        • 数组环形队列

        数据结构与算法—队列

        author icon生如风calendar icon2023年2月19日category icon
        • 数据结构与算法
        tag icon
        • 队列
        timer icon大约 4 分钟

        此页内容
        • 队列
          • 队列介绍
          • 数组实现队列
          • 数组环形队列

        [TOC]

        # 队列

        # 队列介绍

        有序列表,可以用数组或者链表实现。遵循先进先出原则。

        # 数组实现队列

        public class ArrayQueue {
        
            public static void main(String[] args) {
                ArrayQueue queue = new ArrayQueue(3);
                // 接收用户输入
                char key =' ';
                Scanner sc = 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): 队列头数据");
                    // 返回输入的第一个字符
                    key = sc.next().charAt(0);
                    switch (key) {
                        case 's':
                            queue.showQueue();
                            break;
        
                        case 'a':
                            System.out.println("输出一个数:");
                            queue.addQueue(sc.nextInt());
                            break;
        
                        case 'g':
                            try {
                                int res = queue.getQueue();
                                System.out.printf("取出的数据是:%d\n", res);
                            } catch (Exception e) {
                                System.out.printf(e.getMessage());
                            }
                            break;
        
                        case 'h':
                            try {
                                int res = queue.head();
                                System.out.printf("头数据是:%d\n", res);
                            } catch (Exception e) {
                                System.out.printf(e.getMessage());
                            }
                            break;
                        case 'e':
                            sc.close();
                            loop = false;
                            break;
        
                        default:
                            break;
                    }
        
                    System.out.println("程序退出~~");
                }
            }
        
            // 数组的最大容量
            private int maxSize;
            // 队头
            private int front;
            // 队尾
            private int rear;
            // 存放数据的数组
            private int[] arr;
        
            // 初始化队列
            public ArrayQueue(int maxSize) {
                this.maxSize = maxSize;
                this.arr = new int[this.maxSize];
                // 让front 指向队列头的前一个位置(队列头数据的前一个位置)
                this.front = -1;
                // 让rear 指向队尾的数据(队列的最后一个数据)
                this.rear = -1;
            }
        
            // 判断队列是否满
            public boolean isFull() {
                return rear == maxSize - 1;
            }
        
            // 判断队列是否为空
            public boolean isEmpty() {
                return rear == front;
            }
        
            public void addQueue(int data) {
                if (isFull()) {
                    System.out.println("队列满,不能加数据~");
                    return;
                }
                rear++;
                arr[rear] = data;
            }
        
            public int getQueue() {
                if (isEmpty()) {
                    throw new RuntimeException("队列空,无法取出数据~");
                }
                front++;
                return arr[front];
            }
        
            public void showQueue() {
                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];
        
            }
        }
        
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43
        44
        45
        46
        47
        48
        49
        50
        51
        52
        53
        54
        55
        56
        57
        58
        59
        60
        61
        62
        63
        64
        65
        66
        67
        68
        69
        70
        71
        72
        73
        74
        75
        76
        77
        78
        79
        80
        81
        82
        83
        84
        85
        86
        87
        88
        89
        90
        91
        92
        93
        94
        95
        96
        97
        98
        99
        100
        101
        102
        103
        104
        105
        106
        107
        108
        109
        110
        111
        112
        113
        114
        115
        116
        117
        118
        119
        120
        121

        通过该方法测试

        在这里插入图片描述

        在这里插入图片描述

        添加了:10,20,30 show:arr[0]=10,arr[1]=20,arr[2]=30

        在这里插入图片描述

        取出10后,头数据是20。这时候show一下,可以看到队列为:arr[0]=10,arr[1]=20,arr[2]=30

        在这里插入图片描述

        也就是我们通过g获取到了数据,看到队列数据还是一样。

        为了可以重新使用已经出队的数据所占用的空间,考虑使用环形队列。

        # 数组环形队列

        在这里插入图片描述

        public class CircleArrayQueue {
        
            public static void main(String[] args) {
                CircleArrayQueue queue = new CircleArrayQueue(3);
                // 接收用户输入
                char key =' ';
                Scanner sc = 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): 队列头数据");
                    // 返回输入的第一个字符
                    key = sc.next().charAt(0);
                    switch (key) {
                        case 's':
                            queue.showQueue();
                            break;
        
                        case 'a':
                            System.out.println("输出一个数:");
                            queue.addQueue(sc.nextInt());
                            break;
        
                        case 'g':
                            try {
                                int res = queue.getQueue();
                                System.out.printf("取出的数据是:%d\n", res);
                            } catch (Exception e) {
                                System.out.printf(e.getMessage());
                            }
                            break;
        
                        case 'h':
                            try {
                                int res = queue.head();
                                System.out.printf("头数据是:%d\n", res);
                            } catch (Exception e) {
                                System.out.printf(e.getMessage());
                            }
                            break;
                        case 'e':
                            sc.close();
                            loop = false;
                            break;
        
                        default:
                            break;
                    }
        
                    System.out.println("程序退出~~");
                }
            }
        
            // 数组的最大容量
            private int maxSize;
            // 让front 指向队列的第一个元素
            // front = 0;
            // 让rear 指向队列的最后一个元素的后一个位置,因为希望空出一个空间作为约定
            // rear = 0;
            private int front;
            private int rear;
            // 存放数据的数组
            private int[] arr;
        
            // 初始化队列
            public CircleArrayQueue(int maxSize) {
                this.maxSize = maxSize;
                this.arr = new int[maxSize];
            }
        
            // 判断队列是否满
            public boolean isFull() {
                return (rear + 1) % maxSize == front;
            }
        
            // 判断队列是否为空
            public boolean isEmpty() {
                return rear == front;
            }
        
            // 添加数据
            public void addQueue(int data) {
                if (isFull()) {
                    System.out.println("队列满,不能加数据~");
                    return;
                }
                arr[rear] = data;
                // rear 后移,因为是环形,考虑取模
                rear = (rear + 1) % maxSize;
            }
        
            public int getQueue() {
                if (isEmpty()) {
                    throw new RuntimeException("队列空,无法取出数据~");
                }
                // 因为front 是队列第一个元素,也会后移,考虑取模,以免越界
                // 1.先保存front 指向的值到value
                int value = arr[front];
                // 2.front 后移,并返回value
                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]=%d\n", i % maxSize, arr[i % maxSize]);
                }
            }
        
            // 当前队列的有效数据个数
            public int size() {
                return (rear + maxSize - front) % maxSize;
            }
        
            public int head() {
                if (isEmpty()) {
                    throw new RuntimeException("队列空,没有头数据~");
                }
        
                return arr[front];
        
            }
        }
        
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43
        44
        45
        46
        47
        48
        49
        50
        51
        52
        53
        54
        55
        56
        57
        58
        59
        60
        61
        62
        63
        64
        65
        66
        67
        68
        69
        70
        71
        72
        73
        74
        75
        76
        77
        78
        79
        80
        81
        82
        83
        84
        85
        86
        87
        88
        89
        90
        91
        92
        93
        94
        95
        96
        97
        98
        99
        100
        101
        102
        103
        104
        105
        106
        107
        108
        109
        110
        111
        112
        113
        114
        115
        116
        117
        118
        119
        120
        121
        122
        123
        124
        125
        126
        127
        128
        129
        130
        131

        测试: 添加数据10,20,30,show一下,添加40提示队列满

        在这里插入图片描述

        在这里插入图片描述

        取出arr[0] 后,show一下,可以看到队列还剩两个数据

        在这里插入图片描述

        这时,又可以在arr[0] 的位置插入新数据。

        在这里插入图片描述

        在这里插入图片描述

        这样,就可以利用好了数组空间。

        最近学习的数据结构与算法主要都是根据尚硅谷的学习: https://www.bilibili.com/video/BV1E4411H73v/?p=18&vd_source=8e23c01ff3b88e176530ca2e0f4f18fe

        可以看看我的个人博客: 网站:https://www.fuzm.wangopen in new window / https://liwangc.gitee.ioopen in new window ————————————————————————— 作为初学者,很多知识都没有掌握,见谅,如有错误请指出,以期进步,感谢!。后续有新的学习,继续补充上来。

        默认页脚
        Copyright © 2026 生如风