-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCircleQueueDemo.java
More file actions
175 lines (136 loc) · 5.21 KB
/
Copy pathCircleQueueDemo.java
File metadata and controls
175 lines (136 loc) · 5.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
package com.CodeRoot.queue.CircleArrayQueueDemo;
import java.util.Scanner;
public class CircleQueueDemo {
public static void main(String[] args) {
/**
* 数组 模拟 环形队列
*/
CircleQueue queue = new CircleQueue(4);//说明: 数组容量为4,而队列 容量为3
char key = ' ';
Scanner scanner = new Scanner(System.in);//接收输入
boolean loop = true;
while (loop) {
System.out.println("s(show):显示队列");
System.out.println("e(exit):退出程序");
System.out.println("a(add):添加数据到队列");
System.out.println("g(get):从队列取出数据");
System.out.println("h(head):查看队列头数据");
System.out.printf("选择操作:");
key = scanner.next().charAt(0);//接收一个字符
switch (key) {
case 's':
queue.showQueue();
break;
case 'a':
System.out.println("输入一个数:");
int value = scanner.nextInt();
queue.addQueue(value);
break;
case 'g':
/**
* 在try里执行时,遇到异常,则直接进入catch,用e.getMessage()打印错误信息
*/
try {
int res = queue.getQueue();
System.out.println("取出的数是:" + res + "\n");
} catch (Exception e) {
System.out.println(e.getMessage());//自动打印错误信息
}
break;
case 'h':
try {
int res = queue.headQueue();
System.out.println("队列头部的数是:" + res + "\n");
} catch (Exception e) {
System.out.println(e.getMessage());//自动打印错误信息
}
break;
case 'e':
scanner.close();
loop = false;
break;
default:
break;
}
}
System.out.println("程序退出");
}
}
class CircleQueue {
//1.
private int maxSize;//最大容量
private int front;// front指向队列的第一个元素,arr[front]就是数组的第一个元素
private int rear;// rear指向队列的最后一个元素 的后一个位置 ,因为希望预留出一个空间,便于 判断环形队列为满时的条件
//举例说,如果maxSize=3,那么当环形队列 状态为满时,rear指向 [2]的位置,也就是数组最后一位,但这一位实际上 并没有数据,
//更重要的是,预留的这个位置,始终在发生变化
private int[] arr;//存放数据,模拟队列
//2.
public CircleQueue(int maxSize) {
this.maxSize = maxSize;
front=0;
rear=0;
arr=new int[maxSize];//浪费了我好几个小时,这个 限定队列 容量
}
//3.判断环形队列 是否 为满
public boolean isFull() {
return(rear + 1)%maxSize == front;
}
//4.判断是否为空队列
public boolean isEmpty() {
return front == rear;
}
//5.添加数据到队列
public void addQueue(int n) {
if (isFull()) {
System.out.println("不能再添加数据了");
return;
}
arr[rear] = n;
//rear后移,此时必须考虑 取模,因为是环形队列
rear = (rear + 1) % maxSize;//满时,rear从 [最后一位]-->[0]
}
//6.出队列
public int getQueue() {
if (isEmpty()) {
throw new RuntimeException("队列为空,不能取数据");//throw就相当于打印这句话然后return
}
/** 这里需要分析出 front是指向环形队列的第一个元素,直接返回front则无法 将front后移
* 1.先把front的值保存到一个临时变量里
* 2.将front后移,考虑取模,因为仍然是环形
* 3.将临时变量返回
*/
int value = arr[front];
front = (front + 1) % maxSize;
return value;
}
//7.显示队列
public void showQueue() {
if (isEmpty()) {
System.out.println("队列为空无法显示");
return;
}
//从front开始遍历,
for (int i = front; i < front + size(); i++) {
System.out.printf("arr[%d]=%d\n", i % maxSize, arr[i % maxSize]);
/**
* 这里用 i%maxSize,因为当 front在上,而rear在下的时候,遍历时,从front到顶部,再由底部往上到rear
*/
}
}
//求当前队列有效数据的个数
public int size() {
/*
front=0
rear=0
maxSize=10
*/
return (rear + maxSize - front) % maxSize;
}
//显示队列头部元素
public int headQueue() {
if (isEmpty()) {
throw new RuntimeException("队列为空无法显示");
}
return arr[front];
}
}