02--数组模拟队列
1 import java.util.Scanner;
2 //数组模拟队列
3 public class ArrayQueueDemo {
4 public static void main(String[] args) {
5 ArrayQueue arrayQueue = new ArrayQueue(3);
6 Scanner sc = new Scanner(System.in);
7 boolean loop = true;
8 while(loop) {
9 System.out.println("*******a、添加数据*************g、取数据******************");
10 System.out.println("*******s、展示队列*************h、展示头部数据**************");
11 System.out.println("*******************e、退出程序***************");
12 System.out.println("请选择:");
13 char command = sc.next().charAt(0);
14 switch(command) {
15 case 'a':
16 try {
17 System.out.println("请输入您要插入的数据");
18 int n = sc.nextInt();
19 arrayQueue.addQueue(n);
20 } catch (Exception e) {
21 System.out.println(e.getMessage());
22 }
23 break;
24 case 'g':
25 try {
26 System.out.println("取出数据:" + arrayQueue.getQueue());
27 } catch (Exception e) {
28 System.out.println(e.getMessage());
29 }
30 break;
31 case 's':
32 arrayQueue.showQueue();
33 break;
34 case 'h':
35 try {
36 System.out.println("头部数据为:" + arrayQueue.showHeadQueue());
37 } catch (Exception e) {
38 System.out.println(e.getMessage());
39 }
40 break;
41 case 'e':
42 sc.close();
43 loop = false;
44 System.out.println("退出程序");
45 break;
46 default:
47 System.out.println("不支持改选择");
48 break;
49 }
50 }
51 }
52 }
53
54 class ArrayQueue{
55 private int front; //队列头部【指向队列头部元素的上一个元素位置】
56 private int rear; //队列尾部
57 private int[] arr;
58 private int maxSize; //指定数组的大小
59 //构造器:初始化数据
60 public ArrayQueue(int maxSize) {
61 this.maxSize = maxSize;
62 arr = new int[maxSize];
63 front = -1;
64 rear = -1;
65 }
66
67 //判断队列是否为空
68 public boolean isEmpty() {
69 return front == rear;
70 }
71
72 //判断队列是否满
73 public boolean isFull() {
74 return rear == maxSize - 1;
75 }
76
77 //向队列中添加元素
78 public void addQueue(int n) {
79 if(isFull()) {
80 System.out.println("队列满,不能添加数据");
81 return;
82 }
83 //添加元素:即往尾部追加数据
84 arr[++rear] = n;
85 }
86
87 //向队列中取出元素
88 public int getQueue() {
89 if (isEmpty()) {
90 throw new RuntimeException("队列空,无数据");
91 }
92 //取元素即取出索引位置为fron+1元素位置的数据
93 return arr[++front];
94 }
95
96 //展示队列元素,即遍历数组
97 public void showQueue() {
98 if (isEmpty()) {
99 System.out.println("队列空,无数据");
100 return;
101 }
102 for (int i = 0; i < arr.length; i++) {
103 System.out.printf("arr[%d] = %d\n", i, arr[i]);
104 }
105 }
106
107 //展示队列头部数据
108 public int showHeadQueue() {
109 if (isEmpty()) {
110 throw new RuntimeException("队列空,无数据");
111 }
112 //即展示fron+1索引位置的值
113 return arr[front+1];
114 }
115 }
上述过程实现了用数组模拟队列的过程,但是缺点也很明显:就是这个队列不能在有效的空间内复用数据,即每个地方存储的数据都是一次性的。
改进:实现用数组模拟环形队列:
1 import java.util.Scanner;
2
3 /**
4 * 调整:
5 * 1、front变量:arr[front]表示第一个元素,font初始值:0
6 * 2、rear变量:指向队列中最后一个元素的后一个位置,希望空出一个位置作为约定
7 * 3、当队列满时,(rear + 1) % maxSize == front
8 * 4、当队列为空时:front == rear
9 * 5、队列中有效数据的个数为:(rear + maxSize - front) % maxSize
10 * -->至此,可以得到一个环形队列
11 */
12 public class CircleArrayQueueDemo {
13
14 public static void main(String[] args) {
15 System.out.println("测试数组模拟环形队列~~~");
16 CircleArrayQueue arrayQueue = new CircleArrayQueue(4);
17 Scanner sc = new Scanner(System.in);
18 boolean loop = true;
19 while(loop) {
20 System.out.println("*******a、添加数据*************g、取数据******************");
21 System.out.println("*******s、展示队列*************h、展示头部数据**************");
22 System.out.println("*******************e、退出程序***************");
23 System.out.println("请选择:");
24 char command = sc.next().charAt(0);
25 switch(command) {
26 case 'a':
27 try {
28 System.out.println("请输入您要插入的数据");
29 int n = sc.nextInt();
30 arrayQueue.addQueue(n);
31 } catch (Exception e) {
32 System.out.println(e.getMessage());
33 }
34 break;
35 case 'g':
36 try {
37 System.out.println("取出的数据为:" + arrayQueue.getQueue());
38 } catch (Exception e) {
39 System.out.println(e.getMessage());
40 }
41 break;
42 case 's':
43 try {
44 arrayQueue.showQueue();
45 } catch (Exception e) {
46 System.out.println(e.getMessage());
47 }
48 break;
49 case 'h':
50 try {
51 System.out.println("头部数据为:" + arrayQueue.showHeadQueue());
52 } catch (Exception e) {
53 System.out.println(e.getMessage());
54 }
55 break;
56 case 'e':
57 sc.close();
58 loop = false;
59 System.out.println("退出程序");
60 break;
61 default:
62 System.out.println("不支持改选择");
63 break;
64 }
65 }
66 }
67
68 }
69
70 class CircleArrayQueue{
71 private int front; //指向队列中的第一个元素的索引位置
72 private int rear; //指向队列中最后一个元素的索引位置的下一个位置
73 private int maxSize; //队列中最大的元素个数为maxSize - 1【空出一个位置作为约定】
74 private int[] arr; //数组,模拟实现队列
75
76 //创建构造器,用于初始化一些数据
77 public CircleArrayQueue(int maxSize) {
78 this.maxSize = maxSize;
79 arr = new int[maxSize];
80 // front = 0; //默认值为0
81 // rear = 0;
82 }
83
84 //判断队列是否满了
85 public boolean isFull() {
86 return front == (rear + 1) % maxSize;
87 }
88
89 //判断队列是否为空
90 public boolean isEmpty() {
91 return front == rear;
92 }
93
94 //往队列中添加元素
95 public void addQueue(int n) {
96 if (isFull()) {
97 System.out.println("队列已满,不能添加数据~~~");
98 return;
99 }
100 //添加数据,即往队列的尾部追加数据,追加完后rear指向的位置需要后移一位
101 //注:因为是环形队列,不能单纯地rear++,此处需要考虑到取模的情况
102 arr[rear] = n;
103 rear = (rear + 1) % maxSize;
104 }
105
106 //从队列中取出数据
107 public int getQueue() {
108 if (isEmpty()) {
109 throw new RuntimeException("队列为空,不能取出数据");
110 }
111 //取出数据,即从头部front处取,取完后front指向的位置需要后移一位
112 //同添加数据一样,此处也需要考虑到取模的情况
113 /*
114 return arr[front];
115 front = (front + 1) % maxSize; //这样写会导致front指针无法向后移动
116 */
117 //需要定义一个临时变量用于保存当前arr[front]的值
118 int tmp = arr[front];
119 front = (front + 1) % maxSize; //front指针向后移动一位
120 return tmp;
121 }
122
123 //遍历队列中的元素
124 public void showQueue() {
125 if (isEmpty()) {
126 throw new RuntimeException("队列空,无数据");
127 }
128 for (int i = front; i < front + size(); i++) {
129 System.out.printf("arr[%d] = %d\n", i % maxSize,arr[i % maxSize]);
130 }
131 }
132
133 //返回当前队列中有效数字的个数
134 public int size() {
135 return (rear + maxSize - front) % maxSize;
136 }
137
138 //返回队列头部数据
139 public int showHeadQueue() {
140 if (isEmpty()) {
141 throw new RuntimeException("队列空,无头部数据");
142 }
143 return arr[front];
144 }
145 }
如此,便达到了存储空间复用的效果
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
· 提示词工程——AI应用必不可少的技术