这里写的是环形队列和非环形队列。
非环形队列:只可以使用一次,且存在“假溢出”问题。一种情况是删除元素时,front后移,再添加元素时rear后移,当rear移到最后一个元素时,根据条件,队列已满,但是数组前面移除元素的空位并没有被用,并不是真正的队列满。
-
非环形数组模拟队列:
import java.util.Scanner; import javax.management.RuntimeErrorException; public class Queue { public static void main(String[] args) { // 测试 ArrayQueue aq = new ArrayQueue(3); char key = 0; Scanner sc = new Scanner(System.in); boolean loop = true; while (loop) { System.out.println("s:显示队列"); System.out.println("e:退出程序"); System.out.println("a:添加元素"); System.out.println("g:取出数据"); System.out.println("h:查看队首元素"); key=sc.next().charAt(0); switch (key) { case 's': aq.showQueue();break; case 'e': sc.close(); loop=false; break; case 'a': System.out.println("请输入要加的数"); int res=sc.nextInt(); aq.addQueue(res); break; case 'g': if(aq.isEmpty()) { System.out.println("没有元素"); break; } System.out.printf("取出的数是%d", aq.outQueue()); break; case 'h': if(aq.isEmpty()) { System.out.println("没有元素"); break; } System.out.printf("队列头的数据是%d",aq.peek()); break; default:break; } } System.out.println("程序退出"); } } class ArrayQueue { private int maxSize;// 最大容量 private int front;// 指向队首元素的前一个 private int rear;// 指向队尾元素,包括队尾元素 private int[] arr;// 存放数据 // 创建队列 public ArrayQueue(int maxSize1) { maxSize = maxSize1; arr = new int[maxSize]; front = -1; rear = -1; } // 是否满 public boolean ifFull() { return rear == maxSize - 1; } // 是否为空 public boolean isEmpty() { return rear == front; } // 添加数据到队列 public void addQueue(Integer data) { if (ifFull()) { System.out.println("已满"); return; } ++rear; arr[rear] = data; } // 出队列 public Integer outQueue() { if (isEmpty()) { System.out.println("队列为空"); } front++; return arr[front]; } // 显示队列的所有数据 public void showQueue() { if (isEmpty()) { System.out.println("队列为空"); return; } for (int i = 0; i < arr.length; i++) { System.out.printf("arr[%d]=%d\n",i, arr[i]); } } // 显示头部数据 public int peek() { if (isEmpty()) { System.out.println("队列为空"); throw new RuntimeException("队列为空"); } return arr[front + 1]; } }
`
-
环形队列
/*
* 由于前面非环形队列只可以用一次,无法重复使用
* 于是有了环形队列
* 根据前面,而判空和判满都是rear==front;
* 为了解决这个问题
* 有3种解决办法
* 1.设标志位
* 与前面不同的时这里rear时指向队尾元素的下一个元素
* front指向队首元素,利用tag=1&&rear==front为满,tag==0&&rear==front为空
* 2.计数法
* 设置属性size;当加入size+1;当出队,size-1;再判断size=0时,为空,size=maxsize时,为满
* 3.预留空间
* 满(rear+1)%maxSize=front
* 空rear=front
* size个数为maxSize-1
* */
/*标志位法*/
public class CircleQueueByTag{
public static void main(String[] args) {
// 测试
CircueQueue2 aq = new CircueQueue2(4);//预留位置只能放maxSize-1个
char key = 0;
Scanner sc = new Scanner(System.in);
boolean loop = true;
while (loop) {
System.out.println("s:显示队列");
System.out.println("e:退出程序");
System.out.println("a:添加元素");
System.out.println("g:取出数据");
System.out.println("h:查看队首元素");
key=sc.next().charAt(0);
switch (key) {
case 's':
aq.showQueue();
break;
case 'e':
sc.close();
loop=false;
break;
case 'a':
System.out.println("请输入要加的数");
int res=sc.nextInt();
aq.addQueue(res);
break;
case 'g':
if(aq.isEmpty()) {
System.out.println("没有元素");
break;
}
System.out.printf("取出的数是%d", aq.outQueue());
System.out.println();
break;
case 'h':
if(aq.isEmpty()) {
System.out.println("没有元素");
break;
}
System.out.printf("队列头的数据是%d\n",aq.peek());
break;
default:
break;
}
}
System.out.println("程序退出");
}
}
class CircueQueue2 {
private int maxSize;// 最大容量
private int front;// 指向队首元素arr[front]
private int rear;// 指向队尾元素的下一个
private int[] arr;// 存放数据
private int size;//元素个数
private int tag;//是否满的标志
// 创建队列
public CircueQueue2(int maxSize1) {
maxSize = maxSize1;
arr = new int[maxSize];
front = 0;
rear = 0;
size=0;
tag=0;
}
// 是否满
public boolean ifFull() {
return tag ==1&&front==rear;
}
// 是否为空
public boolean isEmpty() {
return tag ==0&&front==rear;
}
// 添加数据到队列
public void addQueue(Integer data) {
if (ifFull()) {
System.out.println("已满");
return;
}
arr[rear] = data;//rear指向的是空的位置
rear=(rear+1)%maxSize;
size++;
if(size==maxSize) {
tag=1;
}
}
// 出队列
public Integer outQueue() {
if (isEmpty()) {
System.out.println("队列为空");
}
int ans=arr[front];//保存值
front=(front+1)%maxSize;//front后移,不能超出数组索引
size--;
if(size==0) {
tag=0;
}
return ans;
}
// 显示队列的所有数据
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=front
}
}
// 显示头部数据
public int peek() {
if (isEmpty()) {
System.out.println("队列为空");
throw new RuntimeException("队列为空");
}
return arr[front];
}
}
/*计数法*/
import java.util.Scanner;
public class CircleQueueByCount {
public static void main(String[] args) {
// 测试
CircueQueue1 aq = new CircueQueue1(4);
char key = 0;
Scanner sc = new Scanner(System.in);
boolean loop = true;
while (loop) {
System.out.println("s:显示队列");
System.out.println("e:退出程序");
System.out.println("a:添加元素");
System.out.println("g:取出数据");
System.out.println("h:查看队首元素");
key=sc.next().charAt(0);
switch (key) {
case 's':
aq.showQueue();
break;
case 'e':
sc.close();
loop=false;
break;
case 'a':
System.out.println("请输入要加的数");
int res=sc.nextInt();
aq.addQueue(res);
break;
case 'g':
if(aq.isEmpty()) {
System.out.println("没有元素");
break;
}
System.out.printf("取出的数是%d", aq.outQueue());
System.out.println();
break;
case 'h':
if(aq.isEmpty()) {
System.out.println("没有元素");
break;
}
System.out.printf("队列头的数据是%d\n",aq.peek());
break;
default:
break;
}
}
System.out.println("程序退出");
}
}
class CircueQueue1 {
private int maxSize;// 最大容量
private int front;// 指向队首元素arr[front]
private int rear;// 指向队尾元素的下一个
private int[] arr;// 存放数据
private int size;//元素个数
private int p;//指针
// 创建队列
public CircueQueue1(int maxSize1) {
maxSize = maxSize1;
arr = new int[maxSize];
front = 0;
rear = 0;
size=0;
p=front;
}
// 是否满
public boolean ifFull() {
return size ==maxSize;
}
// 是否为空
public boolean isEmpty() {
return size == 0;
}
// 添加数据到队列
public void addQueue(Integer data) {
if (ifFull()) {
System.out.println("已满");
return;
}
arr[rear] = data;
rear=(rear+1)%maxSize;
size++;
}
// 出队列
public Integer outQueue() {
if (isEmpty()) {
System.out.println("队列为空");
}
int ans=arr[front];//保存值
front=(front+1)%maxSize;//front后移,不能超出数组索引
size--;
return ans;
}
// 显示队列的所有数据
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=front
}
}
// 显示头部数据
public int peek() {
if (isEmpty()) {
System.out.println("队列为空");
throw new RuntimeException("队列为空");
}
return arr[front];
}
}
/*预留空间*/
package 队列;
import java.util.Scanner;
public class CircleQueueByRoom {
public static void main(String[] args) {
// 测试
CircueQueue aq = new CircueQueue(4);//预留位置只能放maxSize-1个
char key = 0;
Scanner sc = new Scanner(System.in);
boolean loop = true;
while (loop) {
System.out.println("s:显示队列");
System.out.println("e:退出程序");
System.out.println("a:添加元素");
System.out.println("g:取出数据");
System.out.println("h:查看队首元素");
key=sc.next().charAt(0);
switch (key) {
case 's':
aq.showQueue();
break;
case 'e':
sc.close();
loop=false;
break;
case 'a':
System.out.println("请输入要加的数");
int res=sc.nextInt();
aq.addQueue(res);
break;
case 'g':
if(aq.isEmpty()) {
System.out.println("没有元素");
break;
}
System.out.printf("取出的数是%d", aq.outQueue());
break;
case 'h':
if(aq.isEmpty()) {
System.out.println("没有元素");
break;
}
System.out.printf("队列头的数据是%d",aq.peek());
break;
default:
break;
}
}
System.out.println("程序退出");
}
}
class CircueQueue {
private int maxSize;// 最大容量
private int front;// 指向队首元素arr[front]
private int rear;// 指向队尾元素的下一个
private int[] arr;// 存放数据
// 创建队列
public CircueQueue(int maxSize1) {
maxSize = maxSize1;
arr = new int[maxSize];
front = 0;
rear = 0;
}
// 是否满
public boolean ifFull() {
return (rear +1)% maxSize ==front;
}
// 是否为空
public boolean isEmpty() {
return rear == front;
}
//个数
public int getSize() {
return (rear-front+maxSize)%maxSize;//这里加maxSize的原因我的理解是当front指向最后一个元素,rear则指向第一个元素,rear与front索引距离为它们之间的元素个数
//取模是因为rear>front时+maxsize后可能大于maxsize
}
// 添加数据到队列
public void addQueue(Integer data) {
if (ifFull()) {
System.out.println("已满");
return;
}
arr[rear] = data;
rear=(rear+1)%maxSize;
}
// 出队列
public Integer outQueue() {
if (isEmpty()) {
System.out.println("队列为空");
}
int ans=arr[front];//保存值
front=(front+1)%maxSize;//front后移,不能超出数组索引
return ans;
}
// 显示队列的所有数据
public void showQueue() {
if (isEmpty()) {
System.out.println("队列为空");
return;
}
//从front开始遍历,遍历多少的元素
for (int i = front; i < front+getSize(); i++) {
System.out.printf("arr[%d]=%d\n",i%maxSize, arr[i%maxSize]);//这里的i=front
}
}
// 显示头部数据
public int peek() {
if (isEmpty()) {
System.out.println("队列为空");
throw new RuntimeException("队列为空");
}
return arr[front];
}
}
`