数据结构 - 队列
概念及特性
- 有序列表
- 数组实现
- 链表实现
- 先进先出 - FIFO
使用场景
- 银行业务排队 等
数组实现
- 初步单向队列
package cn.com;
import java.util.Scanner;
public class ArrayQueQue {
// 队列最大容量
private int maxSize;
// 队头指针
private int front;
// 队尾指针
private int rear;
private int[] array;
public ArrayQueQue(int maxSize){
this.maxSize = maxSize;
this.array = new int[maxSize];
// 起始指针下表也可以是0
// front是队列头的前一位
this.front = -1;
// rear 是 队列尾的数据(注意理解:这里是队列尾的数据,没有前一位哦)
this.rear = -1;
}
public boolean isEmpty(){
return rear == front;
}
public boolean isFull(){
return rear == maxSize-1;
}
public void add(int ele){
if(isFull()){
System.out.println("队列已满, 不能再添加数据");
return;
}
rear ++;
array[rear] = ele;
}
public int get(){
if(isEmpty()){
throw new RuntimeException("队列为空");
}
front ++;
return array[front];
}
public int peek(){
if(isEmpty()){
throw new RuntimeException("队列为空");
}
return array[front + 1];
}
public void show(){
for (int i = 0; i < array.length; i ++){
System.out.printf("array[%d]=%d\n", i, array[i]);
}
}
// 主函数测试
public static void main(String[] args) {
ArrayQueQue arrayQueQue = new ArrayQueQue(3);
System.out.println("操作菜单:");
System.out.println("show : 展示队列数据");
System.out.println("add : 增加数据到队列");
System.out.println("get : 从队列取数据");
System.out.println("peek : 查看当前队列头数据");
System.out.println("exit : 退出");
boolean flag = true;
while (flag){
System.out.println("请输入操作:");
Scanner scanner = new Scanner(System.in);
String operate = scanner.nextLine();
switch (operate){
case "show":
arrayQueQue.show();
break;
case "add":
System.out.println("请输入数字:");
arrayQueQue.add(scanner.nextInt());
break;
case "get":
try {
System.out.println("get 数据为:"+ arrayQueQue.get());
}catch (Exception e){
e.printStackTrace();
System.out.println(e.getMessage());
}
break;
case "peek":
try {
System.out.println("peek 的数据为:" + arrayQueQue.peek());
}catch (Exception e){
e.printStackTrace();
System.out.println(e.getMessage());
}
break;
default:
flag = false;
break;
}
}
System.out.println("已退出···");
}
}
以上队列存在的问题:
队列只能使用一次,不能循环使用,故需要修改为循环队列
- 循环队列 - 队列满的时候没有空值的数组表示
package cn.com;
import java.util.Scanner;
public class CycleArrayQueue {
private int front;
private int rear;
private int[] cycleArr;
private int maxSize;
private boolean isFull;
public CycleArrayQueue(int maxSize){
this.maxSize = maxSize;
cycleArr = new int[maxSize];
// 指针初始值 - 0
// 这个下表如果不赋值 也是默认为零,可以在此不进行赋值
this.front = 0;
this.rear = 0;
this.isFull = false;
}
public boolean isEmpty(){
return !isFull && front == rear;
}
public boolean isFull(){
return isFull;
}
public int get(){
if(isEmpty()){
throw new RuntimeException("队列为空");
}
if(isFull){
this.isFull = false;
}
int temp = cycleArr[front];
front = (front + 1 + maxSize) % maxSize;
return temp;
}
public void add(int a){
if(isFull()){
System.out.println("队列已满");
return;
}
cycleArr[(this.rear + maxSize) % maxSize] = a;
this.rear = (rear + 1 + maxSize) % maxSize;
if(front == rear){
this.isFull = true;
}
}
public int peek(){
return cycleArr[front];
}
public void show(){
int len = maxSize;
if(!isFull){
len = (rear + maxSize - front) % maxSize;
}
for(int i = 0; i < len; i ++){
System.out.printf("cycleArr[%d]=%d\n", (front + i) % maxSize, cycleArr[(front + i) % maxSize]);
}
}
public static void main(String[] args) {
CycleArrayQueue arrayQueQue = new CycleArrayQueue(3);
System.out.println("操作菜单:");
System.out.println("show : 展示队列数据");
System.out.println("add : 增加数据到队列");
System.out.println("get : 从队列取数据");
System.out.println("peek : 查看当前队列头数据");
System.out.println("exit : 退出");
boolean flag = true;
while (flag){
System.out.println("请输入操作:");
Scanner scanner = new Scanner(System.in);
String operate = scanner.nextLine();
switch (operate){
case "show":
arrayQueQue.show();
break;
case "add":
System.out.println("请输入数字:");
arrayQueQue.add(scanner.nextInt());
break;
case "get":
try {
System.out.println("get 数据为:"+ arrayQueQue.get());
}catch (Exception e){
e.printStackTrace();
System.out.println(e.getMessage());
}
break;
case "peek":
try {
System.out.println("peek 的数据为:" + arrayQueQue.peek());
}catch (Exception e){
e.printStackTrace();
System.out.println(e.getMessage());
}
break;
default:
flag = false;
break;
}
}
System.out.println("已退出···");
}
}
- 循环队列 - 队列满的时候存在一个空值的数组表示
package cn.com;
import java.util.Scanner;
public class CycleArrayQueue2 {
// 最大队列数量
private int maxSize;
// 队列取值 指针 - 前指针
private int front;
// 队列赋值 指针 - 后指针
private int rear;
private int[] cycleArray;
public CycleArrayQueue2(int maxSize){
// 初始值
this.maxSize = maxSize;
this.cycleArray = new int[maxSize];
// 前指针默认指向的初始位置:当然可以是任意的值(在maxSize指定的数组的长度范围即可)
this.front = 0;
// 后指针 默认指向后当前赋值的后一个下标,
// 当没有开始没有任何一个值的, 初始应与front一样, 即当front = 2,的时候,rear = 2就行
this.rear = 0;
// 特别说明:
// 这里的 front 和 rear 的赋值只是0.所以可以不写,因为int型,默认为0
}
// 判断是否为空
public boolean isEmpty(){
// 如果正常的情况下,这个判断可以判断为空,同样也符合,队列数组满的情况,因为满的时候,rear指向的是下一个,即rear 等于 front
// 所以 这里当满的时候需要空一个位置,即 只有最后一个空的位置的时候,判定为满,以此区分空和满的判断条件
return front == rear;
}
public boolean isFull(){
return (rear + 1 + maxSize) % maxSize == front;
}
public void add(int a){
if(isFull()){
System.out.println("队列已满");
return;
}
cycleArray[rear % maxSize] = a;
rear = (rear + 1) % maxSize;
}
public int get(){
if(isEmpty()){
throw new RuntimeException("队列为空");
}
int temp = cycleArray[front];
front = (front + 1) % maxSize;
return temp;
}
public int peek(){
return cycleArray[front];
}
public void show(){
for(int i = 0; i < (rear + maxSize - front)% maxSize; i++){
System.out.printf("cycleArray[%d]=%d\n", (front + i) % maxSize, cycleArray[(front + i) % maxSize] );
}
}
public static void main(String[] args) {
CycleArrayQueue2 arrayQueQue = new CycleArrayQueue2(3);
System.out.println("操作菜单:");
System.out.println("show : 展示队列数据");
System.out.println("add : 增加数据到队列");
System.out.println("get : 从队列取数据");
System.out.println("peek : 查看当前队列头数据");
System.out.println("exit : 退出");
boolean flag = true;
while (flag){
System.out.println("请输入操作:");
Scanner scanner = new Scanner(System.in);
String operate = scanner.nextLine();
switch (operate){
case "show":
arrayQueQue.show();
break;
case "add":
System.out.println("请输入数字:");
arrayQueQue.add(scanner.nextInt());
break;
case "get":
try {
System.out.println("get 数据为:"+ arrayQueQue.get());
}catch (Exception e){
e.printStackTrace();
System.out.println(e.getMessage());
}
break;
case "peek":
try {
System.out.println("peek 的数据为:" + arrayQueQue.peek());
}catch (Exception e){
e.printStackTrace();
System.out.println(e.getMessage());
}
break;
default:
flag = false;
break;
}
}
System.out.println("已退出···");
}
}