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]; // 显示队首元素
       }
    }
    
posted @ 2020-08-27 17:49  xiaokantianse  阅读(67)  评论(0编辑  收藏  举报