微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

1.3 环形队列

  • 基本介绍

    • 在上述队列的基础上进行改动,使这个队列可以重复使用,从而实现环形队列,数组中可预留一个空间?队列的实际长度是数组的长度-1
    • front 指向队列头元素 rear 执行队列尾元素的后一个位置
    • 队列满的条件 (rear+ 1) % maxSize == front 取模可以防止索引越界
    • 队列空的条件 rear == front
    • 队列中有效元素的个数 (rear + maxSize - front) % maxSize 取模的作用相当于加取绝对值 随着指针重置,rear - front 可能为负数
  • 代码实现

  • public class CircleArrayQueueDemo {
       public static void main(String[] args) {
          CircleArrayQueue circleArrayQueue = new CircleArrayQueue(5);
          char key;
          Scanner scanner = new Scanner(system.in);
          a:while (true) {
              try {
                  System.out.println("q:退出程序");
                  System.out.println("s:查看队列");
                  System.out.println("a:向队列中加值");
                  System.out.println("g:从队列中取值");
                  System.out.println("h:查看队首元素");
                  key = scanner.next().charat(0);
                  switch (key) {
                      case 's':
                          circleArrayQueue.showQueue();
                          break;
                      case 'a':
                          System.out.println("输入一个值");
                          circleArrayQueue.addQueue(scanner.nextInt());
                          break;
                      case 'g':
                          System.out.println("从队列中取出的值为" + circleArrayQueue.getQueue());
                          break;
                      case 'h':
                          System.out.println("队首元素为" + circleArrayQueue.queueHead());
                          break;
                      case 'q':
                          scanner.close();
                          System.out.println("退出程序");
                          break a;
                      default:
                          System.out.println("命令错误");
                  }
              } catch (Exception e) {
                  System.out.println(e.getMessage());
              }
          }
       }
    }
    
    class CircleArrayQueue {
    
       private int maxSize; // 队列的最大容量(此处预留出一个空间,所以队列实际元素数量-1)
    
       private int front; // 队列头指针 指向队列头元素
    
       private int rear; // 队列尾指针 指向队列尾元素的后一个位置
    
       private int[] array; // 数组
    
       public CircleArrayQueue(int arrayMaxSize) {
          // 初始化队列
          this.maxSize = arrayMaxSize;
          this.array = new int[maxSize];
          this.front = 0; // 指向队列头元素
          this.rear = 0; // 指向队列尾元素的后一个位置
       }
    
       public boolean isFull() {
          // 判断队列是否已满(由于队列尾指针指向数组中最后一个位置并且预留出一个空间,所以+1取模)
          // 取模还不会超出最大索引,相当于重置索引
          return (rear + 1) % maxSize == front;
       }
    
       public boolean isEmpty() {
          return front == rear; // 判断队列是否为空
       }
    
       public void addQueue(int value) {
          if (this.isFull()) {
              throw new RuntimeException("队列已满");
          }
          // 先在队列尾赋值 ,再增加指针的值 取模还不会超出最大索引,相当于重置索引
          array[this.rear] = value;
          this.rear = (this.rear + 1) % maxSize;
       }
    
       public int getQueue() {
          if (this.isEmpty()) {
              throw new RuntimeException("队列为空");
          }
          // 先取值 再增加指针的值 所以不能直接返回 需要临时变量
          int temp = array[front];
          this.front = (this.front + 1) % maxSize;;
          return temp;
       }
    
       public void showQueue() {
          if (this.isEmpty()) {
              throw new RuntimeException("队列为空");
          }
          // 数组中有效数据的个数(也就是队列中有多少元素)(rear + maxSize - front) % maxSize
          // 展示队列中元素 需要展示从头元素开始 ,遍历多少个(队列中有效元素的个数)
          // 此处 % 为了计算在数组中的实际位置
          for (int i = this.front; i < this.front + size(); i++) {
              System.out.printf("arr[%d]=%d\t\n",i % maxSize,this.array[i % maxSize]);
          }
       }
    
       public int size() {
          // 数组中有效数据的个数(也就是队列中有多少元素)
          // 此处 使用maxSize 相当于 去绝对值 因为指针重置后 rear - front 可能为负数
          return (rear + maxSize - front) % maxSize;
       }
    
       public int queueHead() {
          if (this.isEmpty()) {
              throw new RuntimeException("队列为空");
          }
          return this.array[front]; // 显示队首元素
       }
    }
    

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐