队列:
- 队列是一个有序列表,可以用数组或是链表来实现。
- 遵循先入先出的原则。即:先存入队列的数据,要先取出。后存入的要后取出
单向队列:
front:指向队列头部,front是指向队列头部的前一个位置
rear:指向队列尾的数据
当我们将数据存入队列时称为”addQueue”,addQueue 的处理需要有两个步骤:思路分析
- 将尾指针往后移:rear+1 , 当 front == rear 【空】
- 若尾指针 rear 小于队列的最大下标 maxSize-1,则将数据存入 rear 所指的数组元素中,否则无法存入数据。
rear == maxSize - 1[队列满]
单向队列实现
public class ArrayQueue {
/**
* 队列头
*/
private int front;
/**
* 队列尾
*/
private int rear;
/**
* 数组最大容量
*/
private int maxsize;
/**
* 该数据用于存放数据,模拟队列
*/
private int [] arr;
public int getFront() {
return front;
}
public void setFront(int front) {
this.front = front;
}
public int getRear() {
return rear;
}
public void setRear(int rear) {
this.rear = rear;
}
public int getMaxsize() {
return maxsize;
}
public void setMaxsize(int maxsize) {
this.maxsize = maxsize;
}
public int[] getArr() {
return arr;
}
public void setArr(int[] arr) {
this.arr = arr;
}
/**
* @Description: ArrayQueue 队列构造器
* @param: [maxsize]
* @return:
* @auther: zqq
* @date: 20/5/18 18:13
*/
public ArrayQueue(int maxsize) {
// 指向队列头部,front是指向队列头部的前一个位置
this.front = -1;
// 指向队列尾的数据
this.rear = -1;
this.maxsize = maxsize;
this.arr = new int[maxsize];
}
/**
* @Description: isEmpty 判断是否为空
* @param: []
* @return: boolean
* @auther: zqq
* @date: 20/5/18 18:36
*/
public boolean isEmpty(){
return this.getFront() == this.getRear();
}
/**
* @Description: isFull 判断队列是否已满
* @param: []
* @return: boolean
* @auther: zqq
* @date: 20/5/18 18:36
*/
public boolean isFull(){
return this.getRear() == this.getMaxsize() - 1;
}
/**
* @Description: addQueue 向队列添加数据
* @param: [n]
* @return: void
* @auther: zqq
* @date: 20/5/18 18:21
*/
public void addQueue(int n){
if (isFull()){
System.out.println("队列已满");
return;
}
this.setRear(this.getRear()+1);
this.arr[this.getRear()] = n;
}
/**
* @Description: getQueue 出队列
* @param: []
* @return: int
* @auther: zqq
* @date: 20/5/18 18:37
*/
public int getQueue() throws Exception {
if (isEmpty()){
System.out.println("队列为空");
throw new RuntimeException("队列为空");
}
this.setFront(this.getFront()+1);
return this.getArr()[this.getFront()];
}
/**
* @Description: showQueue 展示队列
* @param: []
* @return: void
* @auther: zqq
* @date: 20/5/18 18:37
*/
public void showQueue(){
if (isEmpty()){
System.out.println("队列为空");
return;
}
for (int i = 0; i < this.getArr().length; i++) {
System.out.printf("arr[%d] = %d\n", i, this.getArr()[i]);
}
}
/**
* @Description: headQueue 查看队列头部
* @param: []
* @return: int
* @auther: zqq
* @date: 20/5/18 18:37
*/
public int headQueue(){
if (isEmpty()){
System.out.println("队列为空,没有任何数据");
throw new RuntimeException("对内为空");
}
int i = this.getArr()[this.getFront()+1];
return i;
}
}
测试代码
public class TestQueue {
public static void main(String[] args) {
ArrayQueue arrayQueue = new ArrayQueue(3);
char key = ' ';
Scanner scanner = new Scanner(System.in);
boolean bool = true;
while (bool){
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):查看队列头的数据");
key = scanner.next().charAt(0);
switch (key){
case 's':
arrayQueue.showQueue();
break;
case 'a':
System.out.println("请输入一个数");
int v = scanner.nextInt();
arrayQueue.addQueue(v);
break;
case 'g':
try {
int queue = arrayQueue.getQueue();
System.out.printf("取出来的数据是 %d\n ", queue);
} catch (Exception e) {
e.printStackTrace();
}
break;
case 'h':
try {
int queue = arrayQueue.headQueue();
System.out.printf("队列头数据是 %d\n ", queue);
} catch (Exception e) {
e.printStackTrace();
}
break;
case 'e':
scanner.close();
bool = false;
break;
default:
break;
}
}
System.out.println("程序退出~~~");
}
}
循环队列
单向队列出队之后有空间浪费,解决方法是让队列进行循环。
思路:
思路如下:
- front 变量的含义做一个调整: front 就指向队列的第一个元素, 也就是说 arr[front] 就是队列的第一个元素
front 的初始值 = 0 - rear 变量的含义做一个调整:rear 指向队列的最后一个元素的后一个位置. 因为希望空出一个空间做为约定.
rear 的初始值 = 0 - 当队列满时,条件是 (rear + 1) % maxSize == front 【满】
- 对队列为空的条件, rear == front 空
- 当我们这样分析, 队列中有效的数据的个数 (rear + maxSize - front) % maxSize // rear = 1 front = 0
- 我们就可以在原来的队列上修改得到,一个环形队列
代码实现:
public class CircleArrayQueue {
/**
* 队列头
*/
private int front;
/**
* 队列尾
*/
private int rear;
/**
* 数组最大容量
*/
private int maxsize;
/**
* 该数据用于存放数据,模拟队列
*/
private int [] arr;
public int getFront() {
return front;
}
public void setFront(int front) {
this.front = front;
}
public int getRear() {
return rear;
}
public void setRear(int rear) {
this.rear = rear;
}
public int getMaxsize() {
return maxsize;
}
public void setMaxsize(int maxsize) {
this.maxsize = maxsize;
}
public int[] getArr() {
return arr;
}
public void setArr(int[] arr) {
this.arr = arr;
}
/**
* @Description: ArrayQueue 队列构造器
* @param: [maxsize]
* @return:
* @auther: zqq
* @date: 20/5/18 18:13
*/
public CircleArrayQueue(int maxsize) {
// front 变量的含义做一个调整: front 就指向队列的第一个元素, 也就是说 arr[front] 就是队列的第一个元素
this.front = 0;
// rear 变量的含义做一个调整:rear 指向队列的最后一个元素的后一个位置. 因为希望空出一个空间做为约定.
this.rear = 0;
this.maxsize = maxsize;
this.arr = new int[maxsize];
}
/**
* @Description: isEmpty 判断是否为空
* @param: []
* @return: boolean
* @auther: zqq
* @date: 20/5/18 18:36
*/
public boolean isEmpty(){
return this.getFront() == this.getRear();
}
/**
* @Description: isFull 判断队列是否已满
* @param: []
* @return: boolean
* @auther: zqq
* @date: 20/5/18 18:36
*/
public boolean isFull(){
return (this.getRear() +1) % this.getMaxsize() == this.getFront();
}
public void addQueue(int n){
if (isFull()){
System.out.println("队列已满");
return;
}
this.getArr()[this.getRear()] = n;
this.setRear((this.getRear()+1) % this.getMaxsize());
}
public int getQueue() throws Exception {
if (isEmpty()){
System.out.println("队列为空");
throw new RuntimeException("队列为空");
}
int value = this.getArr()[this.getFront()];
this.setFront(this.getFront()+1 % this.getMaxsize());
return value;
}
public void showQueue(){
if (isEmpty()){
System.out.println("队列为空");
return;
}
for (int i = this.getFront(); i < this.getFront()+size(); i++) {
System.out.printf("arr[%d] = %d\n", i % (this.getMaxsize()-1), this.getArr()[i % (this.getMaxsize()-1)]);
}
}
public int size(){
return (this.getRear() + this.getMaxsize() - this.getFront()) % this.getMaxsize();
}
public int headQueue(){
if (isEmpty()){
System.out.println("队列为空,没有任何数据");
throw new RuntimeException("对内为空");
}
int i = this.getArr()[this.getFront()];
return i;
}
}