队列queue
队列是一个有序列表,可以用数组或者是链表实现 原则: 先入先出
应用:取号排队
数组实现队列示例
java
package com.demo;
import java.util.Scanner;
/**
* 数组实现队列
*/
class ArrayQueue {
private int size; // 队列大小
private int[] arr; // 队列数组实现
private int rear = -1; // 队尾
private int front = -1; // 队首
public ArrayQueue(int size) {
this.size = size;
this.arr = new int[this.size];
}
/**
* 判断对垒是否满
*/
public boolean isFull() {
return this.size == this.rear + 1;
}
/**
* 判断队列是否空
*/
public boolean isEmpty() {
return this.front == this.rear;
}
/**
* 数据入队
*/
public boolean add(int data) {
if (this.isFull()) {
return false;
}
this.rear++;
this.arr[this.rear] = data;
return true;
}
/**
* 数据出队
*/
public int get() {
if (this.isEmpty()) {
throw new RuntimeException("Queue is Empty");
}
this.front++;
return this.arr[this.front];
}
/**
* 队首元素
*/
public int head() {
if (this.isEmpty()) {
throw new RuntimeException("Queue is Empty");
}
return this.arr[this.front + 1];
}
/**
* 显示队列全部元素
*/
public void show() {
for (int i = 0; i < this.size; i++) {
System.out.printf("arr[%d] = %d\n", i, this.arr[i]);
}
}
}
public class ArrayQueueDemo {
public static void main(String[] args) {
ArrayQueue queue = new ArrayQueue(3);
// 接收用户输入
Scanner scanner = new Scanner(System.in);
char key;
boolean loop = true;
while (loop) {
// 菜单
System.out.println("s(show): show queue");
System.out.println("a(add): add data into queue");
System.out.println("g(get): get data from queue");
System.out.println("e(exit): exit");
System.out.println("h(head): get head of queue");
key = scanner.next().charAt(0);
switch (key) {
case 's':
queue.show();
break;
case 'a':
int value = scanner.nextInt();
queue.add(value);
break;
case 'g':
try {
System.out.println(queue.get());
} catch (RuntimeException e) {
System.out.println(e.getMessage());
}
break;
case 'h':
try {
System.out.println(queue.head());
} catch (RuntimeException e) {
System.out.println(e.getMessage());
}
break;
case 'e':
loop = false;
scanner.close();
break;
default:
break;
}
}
System.out.println("已退出");
}
}
问题 1、目前数组不能被复用 2、改进成环形数组,取模实现
数组实现环形队列
思路分析
size = 3
=========================
0 <- front rear
1
2
total = rear - front = 0
=========================
add
0 <- front
1 <- rear
2
total = rear - front = 1
=========================
add
0 <- front
1
2 <- rear
total = rear - front = 2
=========================
get
0
1 <- front
2 <- rear
total = rear - front = 1
=========================
add (rear + 1) % 3 = 0
0 <- rear
1 <- front
2
total = [3 + (rear - front)] % 3 = 2
=========================
front 指向队首
rear 指向队尾下一个元素位置
empty: rear == front
计算rear 与front 距离,留出一个空位不存,和empty区分
full: (rear + 1) % 3 == front
将复数转为正数
(size + (rear - front)) % size
(10 + 5 - 2) % 10 = 3
(10 + 2 - 5) % 10 = 7
-2 -1 0 1 2
代码实现
java
package com.demo;
import java.util.Scanner;
/**
* 环形数组队列
*/
class CircleArrayQueue {
private int size;
private int front = 0; // 指向队首
private int rear = 0; // 指向队尾下一个元素, 最后一个地址不存值
private int[] arr;
public CircleArrayQueue(int size) {
this.size = size;
this.arr = new int[this.size];
}
public boolean isFull() {
return (this.rear + 1) % this.size == this.front;
}
public boolean isEmpty() {
return this.front == this.rear;
}
public boolean add(int data) {
if (this.isFull()) {
return false;
}
this.arr[this.rear] = data;
this.rear = (this.rear + 1) % this.size;
return true;
}
public int get() {
if (this.isEmpty()) {
throw new RuntimeException("queue is empty");
}
int value = this.arr[this.front];
this.front = (this.front + 1) % this.size;
return value;
}
public int head() {
if (this.isEmpty()) {
throw new RuntimeException("queue is empty");
}
return this.arr[this.front];
}
public int total() {
return (this.size + (this.rear - this.front)) % this.size;
}
public void show() {
for (int i = this.front; i < this.front + this.total(); i++) {
int point = i % this.size;
System.out.printf("arr[%d] = %d\n", point, this.arr[point]);
}
}
}
public class CircleArrayQueueDemo {
public static void main(String[] args) {
CircleArrayQueue queue = new CircleArrayQueue(4);
// 接收用户输入
Scanner scanner = new Scanner(System.in);
char key;
boolean loop = true;
while (loop) {
// 菜单
System.out.println("s(show): show queue");
System.out.println("a(add): add data into queue");
System.out.println("g(get): get data from queue");
System.out.println("e(exit): exit");
System.out.println("h(head): get head of queue");
key = scanner.next().charAt(0);
switch (key) {
case 's':
queue.show();
break;
case 'a':
int value = scanner.nextInt();
queue.add(value);
break;
case 'g':
try {
System.out.println(queue.get());
} catch (RuntimeException e) {
System.out.println(e.getMessage());
}
break;
case 'h':
try {
System.out.println(queue.head());
} catch (RuntimeException e) {
System.out.println(e.getMessage());
}
break;
case 'e':
loop = false;
scanner.close();
break;
default:
break;
}
}
System.out.println("已退出");
}
}