package sparseArray;
import java.util.Scanner;
/**
*
* 循环数组队列
* arr[front]指向队列第一个元素,初始值为0
* arr[rear]指向队列最后一个元素的后一个位置,空出一个空间作为约定,初始值为0
* 队列满的条件(rear+1)%maxSize==front
* 队列的有效元素数:(rear+maxSize-front)%maxSize ((rear+maxSize)-front)%maxSize 算法
*
* @param <E>
*/
public class CircleQueue<E>{
private int maxSize; //表示队列(数组)最大容量
private int front; //队列头
private int rear; //队列尾
private Object[] arr; //存放数据的数组,用来模仿队列
public CircleQueue(int arrMaxSize) {
maxSize = arrMaxSize;
arr = new Object[maxSize];
front = 0;
rear = 0;
}
//判断队列是否满
public boolean isFull(){
//♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦
return (rear+1)%maxSize==front; //队列最多存储数组(max-1)
//♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦
}
//判断队列是否为空
public boolean isEmpty(){
return rear == front;
}
//添加数据到队列
public void addQueue(E e){
if(isFull()){
System.out.println("队列已满,无法添加数据!");
return;
}
//♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦
//rear++; //让rear后移
arr[rear]=e;
rear = (rear +1)% maxSize;//取模后移,可以让数组循环利用(循环数组)
//♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦
}
public E getQueue(){
if(isEmpty()){
throw new RuntimeException("队列为空,不能取数据");
}
/*
* front++;
*return (E) arr[front]; //数据出队列,并没有把队列数据删除,只是移动了指针。
*/
//♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦
//front指向队列第一个元素,先把这个元素用临时变量保存返回,再把front向后移一位(考虑队顶取模后移)
E value = (E) arr[front];
front = (front+1)%maxSize;
return value;
//♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦
}
//显示队列的所有数据
public void showQueue(){
if(isEmpty()){
System.out.println("队列为空,没有数据!");
return;
}
//♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦
for(int i = front;i<front+size();i++){ // (rear+maxSize-front)%maxSize获得队列有效元素个数。
//♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦♦
System.out.printf("arr[%s]=%s\n",i%maxSize,arr[i%maxSize]); //环形数组它的下个值可能循环到前面,i会index越界
}
}
//显示队列头数据,注意不是取数据
public E headQueue(){
if(isEmpty()){
throw new RuntimeException("队列为空,不能取数据");
}
return (E) arr[front];
}
public int size(){
return (rear+maxSize-front)%maxSize;
}
public static void main(String[] args) {
System.out.println("测试数组模拟环形队列");
CircleQueue queue = new CircleQueue(3);
char key =' '; //接受用户输入
Scanner scanner = new Scanner(System.in);
boolean loop = true;
//输出一个菜单
while(loop){
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':
queue.showQueue();
break;
case'a':
System.out.println("输出一个数");
Object value = scanner.next();
queue.addQueue(value);;
break;
case'g': //取出数据
try{
Object res = queue.getQueue();
System.out.printf("取出的数据是%s\n",res);
}catch(Exception e){
System.out.println(e.getMessage());
}
break;
case'h':
try{
Object res = queue.headQueue();
System.out.printf("队列头部元素是%s\n",res);
}catch(Exception e){
System.out.println(e.getMessage());
}
break;
case'e':
scanner.close();
loop = false;
break;
default:
break;
}
}
System.out.println("程序退出");
}
}
输出:
测试数组模拟环形队列
s(show):显示队列
e(exit):退出程序
a(add):添加数据到队列
g(get):从队列取出数据
h(head):查看队列头的数据
a
输出一个数
1
s(show):显示队列
e(exit):退出程序
a(add):添加数据到队列
g(get):从队列取出数据
h(head):查看队列头的数据
a
输出一个数
2
s(show):显示队列
e(exit):退出程序
a(add):添加数据到队列
g(get):从队列取出数据
h(head):查看队列头的数据
a
输出一个数
3
队列已满,无法添加数据!
s(show):显示队列
e(exit):退出程序
a(add):添加数据到队列
g(get):从队列取出数据
h(head):查看队列头的数据
s
arr[0]=1
arr[1]=2
s(show):显示队列
e(exit):退出程序
a(add):添加数据到队列
g(get):从队列取出数据
h(head):查看队列头的数据
h
队列头部元素是1
s(show):显示队列
e(exit):退出程序
a(add):添加数据到队列
g(get):从队列取出数据
h(head):查看队列头的数据
g
取出的数据是1
s(show):显示队列
e(exit):退出程序
a(add):添加数据到队列
g(get):从队列取出数据
h(head):查看队列头的数据
a
输出一个数
3
s(show):显示队列
e(exit):退出程序
a(add):添加数据到队列
g(get):从队列取出数据
h(head):查看队列头的数据
s
arr[1]=2
arr[2]=3
s(show):显示队列
e(exit):退出程序
a(add):添加数据到队列
g(get):从队列取出数据
h(head):查看队列头的数据
h
队列头部元素是2
s(show):显示队列
e(exit):退出程序
a(add):添加数据到队列
g(get):从队列取出数据
h(head):查看队列头的数据