环形队列
思路
- front指向队列第一个元素初始值为0
- real指向队列的最后一个元素的后一个位置,因为希望空出空间作为约定,初始值为0
- (real+1)%MaxSize=front(满)
牺牲了一个动态空间,并且real指向他,为了使再次为空时real=front
- real=front(空)
- 队列中有效的数据个数:(real+MaxSize-frout)%MaxSize
程序
import java.util.Scanner;
public class CircleQueueDemo{
public static void main(String[] args){
//创建队列,大小为3
ArrayQueue aq=new ArrayQueue(4);
Scanner ss=new Scanner(System.in);
//用来接收输入的字符
char c=' ';
boolean loop=true;
while(loop){
//界面
System.out.println("s(showQueue):显示队列");
System.out.println("a(addQueue):插入队列");
System.out.println("g(getQueue):出队列");
System.out.println("h(headQueue):显示队列的头");
System.out.println("e(exit):退出");
//取第0位的字符
c=ss.next().charAt(0);
switch(c){
case 's':
aq.showQueue();
break;
case 'a':
System.out.println("请输入要进入队列的数据:");
int data=ss.nextInt();
aq.addQueue(data);
break;
case 'g':
try{
int data2=aq.getQueue();
System.out.printf("%d出队列\n",data2);
}catch(Exception e){
System.out.println(e.getMessage());
}
break;
case 'h':
try{
int data3=aq.headQueue();
System.out.printf("%d是现在队列的队头\n",data3);
}catch(Exception e){
System.out.println(e.getMessage());
}
break;
case 'e':
loop=false;
//关闭输入
ss.close();
System.out.println("退出……");
break;
default:
break;
}
}
}
}
class ArrayQueue{
private int MaxSize;
private int[] arr;
private int front;
private int real;
//构造方法
ArrayQueue(int maxsize){
//创建队列
MaxSize=maxsize;
arr=new int[MaxSize];
front=0;
real=0;
}
//判断队列是否为空
public boolean isEmpty(){
return front==real;
}
//判断队列是否满了
public boolean isFull(){
return (real+1)%MaxSize==front;
}
//插入数据
public void addQueue(int data){
if(isFull()){
System.out.println("队列已满,插入失败");
return;
}
arr[real]=data;
real=(real+1)%MaxSize;
System.out.printf("%d入队成功\n",data);
}
//出队列
public int getQueue(){
if(isEmpty())
//throw会自动返回,所以不用return
throw new RuntimeException("队列为空,无法出队");
int get1=arr[front];
front=(front+1)%MaxSize;
return get1;
}
//显示队列中所有数据,arr中数据一直都在,即使全都出队列了,
//因为arr存储的依然是数组的地址。
//值没有被覆盖掉
public int valCount(){
return (real+MaxSize-front)%MaxSize;
}
public void showQueue(){
if(isEmpty()){
System.out.println("队列为空,没有数据");
return;
}
for(int i=front;i<front+valCount();i++){
System.out.printf("arr[%d]=%d\n",i%MaxSize,arr[i%MaxSize]);
}
}
//显示头数据,不出队
public int headQueue(){
if(isEmpty()){
//System.out.println("队列为空,没有头数据");
//return;
throw new RuntimeException("队列为空,没有头数据");
}
return arr[front];
}
}
e(exit):退出
s
arr[0]=11
arr[1]=22
arr[2]=33
s(showQueue):显示队列
a(addQueue):插入队列
g(getQueue):出队列
h(headQueue):显示队列的头
e(exit):退出
a
请输入要进入队列的数据:
44
队列已满,插入失败
s(showQueue):显示队列
a(addQueue):插入队列
g(getQueue):出队列
h(headQueue):显示队列的头
e(exit):退出
g
11出队列s(showQueue):显示队列
a(addQueue):插入队列
g(getQueue):出队列
h(headQueue):显示队列的头
e(exit):退出
s
arr[1]=22
arr[2]=33
s(showQueue):显示队列
a(addQueue):插入队列
g(getQueue):出队列
h(headQueue):显示队列的头
e(exit):退出
a
请输入要进入队列的数据:
44
44入队成功
s(showQueue):显示队列
a(addQueue):插入队列
g(getQueue):出队列
h(headQueue):显示队列的头
e(exit):退出
s
arr[1]=22
arr[2]=33
arr[3]=44
s(showQueue):显示队列
a(addQueue):插入队列
g(getQueue):出队列
h(headQueue):显示队列的头
e(exit):退出
总结:
- 结束后要关闭输入
- 数组下标是i%MaxSize,数组值为:arr[i%MaxSize]
- 留出来的空间是动态的,因此队满,出队后再添加,依然是从队尾加不是从队头或者数组下标为0加
arr[0]=11
arr[1]=22
arr[2]=33
//满状态,空间为4,从0-2
//出队后剩1-2
arr[1]=22
arr[2]=33
arr[3]=44
//再进就是3,1-3满状态,当再出后再进,又从0开始了
g
22出队列
s(showQueue):显示队列
a(addQueue):插入队列
g(getQueue):出队列
h(headQueue):显示队列的头
e(exit):退出
s
arr[2]=33
arr[3]=44
a
请输入要进入队列的数据:
55
55入队成功
s(showQueue):显示队列
a(addQueue):插入队列
g(getQueue):出队列
h(headQueue):显示队列的头
e(exit):退出
s
arr[2]=33
arr[3]=44
arr[0]=55
//又回到了0