用环形数组实现队列

Posted spinoza

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用环形数组实现队列相关的知识,希望对你有一定的参考价值。

技术图片

 

 

  1 package com.atguigu.queue;
  2 
  3 import java.util.Scanner;
  4 
  5 public class CircleArrayQueueDemo {
  6 
  7     public static void main(String[] args) {
  8         
  9         //测试一把
 10         System.out.println("测试数组模拟环形队列的案例~~~");
 11         
 12         // 创建一个环形队列
 13         CircleArray queue = new CircleArray(4); //说明设置4, 其队列的有效数据最大是3
 14         char key = ‘ ‘; // 接收用户输入
 15         Scanner scanner = new Scanner(System.in);//
 16         boolean loop = true;
 17         // 输出一个菜单
 18         while (loop) {
 19             System.out.println("s(show): 显示队列");
 20             System.out.println("e(exit): 退出程序");
 21             System.out.println("a(add): 添加数据到队列");
 22             System.out.println("g(get): 从队列取出数据");
 23             System.out.println("h(head): 查看队列头的数据");
 24             key = scanner.next().charAt(0);// 接收一个字符
 25             switch (key) {
 26             case ‘s‘:
 27                 queue.showQueue();
 28                 break;
 29             case ‘a‘:
 30                 System.out.println("输出一个数");
 31                 int value = scanner.nextInt();
 32                 queue.addQueue(value);
 33                 break;
 34             case ‘g‘: // 取出数据
 35                 try {
 36                     int res = queue.getQueue();
 37                     System.out.printf("取出的数据是%d
", res);
 38                 } catch (Exception e) {
 39                     // TODO: handle exception
 40                     System.out.println(e.getMessage());
 41                 }
 42                 break;
 43             case ‘h‘: // 查看队列头的数据
 44                 try {
 45                     int res = queue.headQueue();
 46                     System.out.printf("队列头的数据是%d
", res);
 47                 } catch (Exception e) {
 48                     // TODO: handle exception
 49                     System.out.println(e.getMessage());
 50                 }
 51                 break;
 52             case ‘e‘: // 退出
 53                 scanner.close();
 54                 loop = false;
 55                 break;
 56             default:
 57                 break;
 58             }
 59         }
 60         System.out.println("程序退出~~");
 61     }
 62 
 63 }
 64 
 65 
 66 class CircleArray {
 67     private int maxSize; // 表示数组的最大容量
 68     //front 变量的含义做一个调整: front 就指向队列的第一个元素, 也就是说 arr[front] 就是队列的第一个元素 
 69     //front 的初始值 = 0
 70     private int front; 
 71     //rear 变量的含义做一个调整:rear 指向队列的最后一个元素的后一个位置. 因为希望空出一个空间做为约定.
 72     //rear 的初始值 = 0
 73     private int rear; // 队列尾
 74     private int[] arr; // 该数据用于存放数据, 模拟队列
 75     
 76     public CircleArray(int arrMaxSize) {
 77         maxSize = arrMaxSize;
 78         arr = new int[maxSize];
 79     }
 80     
 81     // 判断队列是否满
 82     public boolean isFull() {
 83         return (rear  + 1) % maxSize == front;
 84     }
 85     
 86     // 判断队列是否为空
 87     public boolean isEmpty() {
 88         return rear == front;
 89     }
 90     
 91     // 添加数据到队列
 92     public void addQueue(int n) {
 93         // 判断队列是否满
 94         if (isFull()) {
 95             System.out.println("队列满,不能加入数据~");
 96             return;
 97         }
 98         //直接将数据加入
 99         arr[rear] = n;
100         //将 rear 后移, 这里必须考虑取模
101         rear = (rear + 1) % maxSize;
102     }
103     
104     // 获取队列的数据, 出队列
105     public int getQueue() {
106         // 判断队列是否空
107         if (isEmpty()) {
108             // 通过抛出异常
109             throw new RuntimeException("队列空,不能取数据");
110         }
111         // 这里需要分析出 front是指向队列的第一个元素
112         // 1. 先把 front 对应的值保留到一个临时变量
113         // 2. 将 front 后移, 考虑取模
114         // 3. 将临时保存的变量返回
115         int value = arr[front];
116         front = (front + 1) % maxSize;
117         return value;
118 
119     }
120     
121     // 显示队列的所有数据
122     public void showQueue() {
123         // 遍历
124         if (isEmpty()) {
125             System.out.println("队列空的,没有数据~~");
126             return;
127         }
128         // 思路:从front开始遍历,遍历多少个元素
129         // 动脑筋
130         for (int i = front; i < front + size() ; i++) {
131             System.out.printf("arr[%d]=%d
", i % maxSize, arr[i % maxSize]);
132         }
133     }
134     
135     // 求出当前队列有效数据的个数
136     public int size() {
137         // rear = 2
138         // front = 1
139         // maxSize = 3 
140         return (rear + maxSize - front) % maxSize;   
141     }
142     
143     // 显示队列的头数据, 注意不是取出数据
144     public int headQueue() {
145         // 判断
146         if (isEmpty()) {
147             throw new RuntimeException("队列空的,没有数据~~");
148         }
149         return arr[front];
150     }
151 }

一开始没看明白,但是画一下图就好了,

 

 

技术图片

 

以上是关于用环形数组实现队列的主要内容,如果未能解决你的问题,请参考以下文章

用环形数组实现队列

数组模拟环形队列

java数据结构与算法:单向队列与环形队列详解(图片+代码)

java实现环形队列

java数据结构,一个案例带你用数组模拟队列,环形队列!

2-环形队列-Scala实现