• 数组模拟实现环形队列


    目录

    前言

    一、什么是队列?

    二、数组模拟非环形队列的实现

    三 . 数组模拟环形队列

    总结


    前言 

    笔者: 最爱吃兽奶

    博文内容: 数据结构队列的模拟实现

    这篇博客理解起来或许没有那么简单,我尽力讲的容易理解一点,接下来跟我一起去看看吧!


    一、什么是队列?

    队列是一种特殊的线性数据结构,它遵循先进先出(First In First Out,FIFO)的原则。队列可以看作是一种排队的数据结构,类似于现实生活中的排队。在队列中,新元素被添加到队列的末尾,而从队列中移除元素的操作只能从队列的前端进行。

    上图八个小球按序号依次入队列 

    队列有两个基本操作:入队(enqueue)和出队(dequeue)。入队操作将一个元素添加到队列的末尾,而出队操作则从队列的前端移除一个元素。除了入队和出队操作,队列还可以支持其他操作,如获取队列的长度、判断队列是否为空等。

    队列的应用场景:银行排队案例

    二、数组模拟非环形队列的实现

    图解:

    分析: 队列本身是有序列表,若使用数组的结构来存储队列的数据,则队列数组的声明如上图, 其中 maxSize 是该队列的最大容量。因为队列的输出、输入是分别从前后端来处理,因此需要两个变量 front及 rear分别记录队列前后端的下标,front 会随着数据输出而改变,而 rear则是随着数据输入而改变

    代码实现:

    下面给出基础代码,入队列/出队列的方法我们单独来实现

    public class QueueDemo {
        private int capacity;
        private int front;
        private int rear;
        private int[] Queue;
        
        public QueueDemo(int capacity){
            this.capacity = capacity;
            Queue = new int[capacity];
            front = -1;
            rear = -1;
        }
    }
    // 判断队列是否已满
    private Boolean IsFull(){
        return rear == capacity-1;
    }
    
    // 判断队列是否为空
    private Boolean IsEmpty(){
        return rear == front;
    }

    入队列

    public void addQueue(int data) throws Exception {
        if(IsFull()){
            throw new RuntimeException("队列已满,无法插入新的数据");
        }
        arr[++rear] = data;
    }

    出队列

    public void getQueue(){
        if(IsEmpty()){
            throw new RuntimeException("队列为空,无法出队列!");
        }
        front++;// front 后移
    }

     问题分析: 可以清楚地看到上面队列并不是可重复利用队列,而实际上的队列则是可以重复利用的,在这里引出环形队列。

    三 . 数组模拟环形队列

    思路如下:

    1.  front 变量的含义做一个调整: front 就指向队列的第一个元素, 也就是说 arr[front] 就是队列的第一个元素

    front 的初始值 = 0

    2.  rear 变量的含义做一个调整:rear 指向队列的最后一个元素的后一个位置. 因为希望空出一个空间做为约定.

    rear 的初始值 = 0

    3. 当队列满时,条件是  (rear  + 1) % maxSize == front 【

    4. 对队列为空的条件, rear == front

    5. 当我们这样分析, 队列中有效的数据的个数   (rear + maxSize - front) % maxSize   // rear = 1 front = 0

    为什么要留出一个空间作为约定?

    如果不留一个空间作为约定,队满和队空的条件就一样了,我们无法区分队满还是队空,所以要留出一个空间作为约定

     

    下面给出代码具体实现
    1. public class circleQueue {
    2. private int QueueSize;// 队列容量
    3. private int front;// 队列首部
    4. private int rear;// 队列尾部
    5. private int[] arr;// 该数组用于存放数据,模拟队列
    6. // 构造器
    7. public circleQueue(int maxSize){
    8. QueueSize = maxSize;
    9. front = 0;// 指向队列头部,指向队列头的第一个位置
    10. rear = 0;// 指向队列尾部,指向队列尾部最后一个元素的下一个位置
    11. // 约定预留一个空间,如果不预留空间,满和空的条件将会重合
    12. arr = new int[maxSize];
    13. }
    14. // 判断是否为空
    15. public boolean isNull(){
    16. return rear == front;
    17. }
    18. // 判断是否已满
    19. public boolean isFull(){
    20. return (rear+1)% QueueSize == front;
    21. }
    22. // 入队列
    23. public void addQueue(int n){
    24. if(isFull()){
    25. throw new RuntimeException("队列已满,不能在增加数据");
    26. }
    27. arr[rear] = n;
    28. rear = (rear+1)%QueueSize;
    29. }
    30. // 出队列
    31. public int getQueue(){
    32. if(isNull()){
    33. throw new RuntimeException("队列为空,不能取数据");
    34. }
    35. int value = arr[front];
    36. front = (front+1)%QueueSize;
    37. return value;
    38. }
    39. // 显示队列
    40. public void showQueue(){
    41. if(isNull()){
    42. throw new RuntimeException("队列为空");
    43. }
    44. for (int i = front; i
    45. System.out.printf("arr[%d] = %d ",i%QueueSize,arr[i%QueueSize]);
    46. }
    47. }
    48. // 显示队列的头数据(不是取数据)
    49. public void showHead(){
    50. if(isNull()){
    51. throw new RuntimeException("队列为空");
    52. }
    53. System.out.println("头数据为"+arr[front]);
    54. }
    55. public int getSize(){
    56. return (rear-front+QueueSize)%QueueSize;
    57. }
    58. }

    总结

    大家有条件还是敲一敲比较好,能看明白是一回事,敲出来又是另一回事。

    其中%是关键,这一点需要自己理解,光打字解释解释不清楚,大家重点理解一下。

  • 相关阅读:
    阿里云服务器全方位介绍——看这一篇就够了
    Java代码审计-Filter核心技术
    基于Minimax&Alpha-Beta剪枝和强化学习的播棋(Mancala)AI
    天翼云Web应用防火墙(边缘云版)支持检测和拦截Apache Spark shell命令注入漏洞
    kubernetes集群编排(7)
    接口自动化中如何完成接口加密与解密?
    python实现ModBusTCP协议的client
    【剑指offr--C/C++】JZ55 二叉树的深度
    Java基础(1)——ThreadLocal
    Leetcode—2609.最长平衡子字符串【简单】
  • 原文地址:https://blog.csdn.net/weixin_73869209/article/details/132675876