利用数组模拟环形队列
队列是一种先进先出的线性数据结构。在传统的模拟队列中,因为队首的front指针和队尾的rear指针增长到maxSize无法回到0的原因,无法无限存取数据。所以引出了环形队列的思想。
所谓环形队列,是指定义一个大小为maxSize的空间,而其最多只能存储(maxSize-1)的元素。front指针指向当前队列的第一个元素,rear指针指向当前队列的最后一个元素的后一个位置。之所以设计留出一个空间,主要是因为如果不流出这个元素。在这种情况下,队列空间满和队列为空的判断条件均为front =rear,这样就无法判断到底是队列为空还是队列为满了。
而留出一个空间,队空的条件仍为:
front == rear;
而队满的条件,就变为了
(rear+1)%maxSize = front;
此时,队列中的元素个数为:
(rear-front+maxSize)%maxSize;
package com.yck.queue;
import java.util.Scanner;
public class CircleQueueDemo2 {
public static void main(String[] args) {
CircleQueue2 circleQueue2 = new CircleQueue2(5);
/*
array的大小为5,但队列的大小为 (5-1) = 4;
*/
char key = ' '; //接收用户输入
Scanner scanner = new Scanner(System.in);
boolean loop = true;
while(loop){
System.out.println("s(show):显示队列");
System.out.println("e(show):退出队列");
System.out.println("a(show):添加数据到队列");
System.out.println("g(show):从队列中取出数据");
System.out.println("h(show):查看队头的数据");
System.out.println("c(show):查看队列中的数据个数");
key = scanner.next().charAt(0);
switch(key){
case 's':
circleQueue2.showQueue();
break;
case 'a':
System.out.println("请输入一个数字");
int value = scanner.nextInt();
circleQueue2.EnQueue(value);
break;
case 'g':
try{
int res = circleQueue2.DeQueue();
System.out.printf("输出的数据是:%d\n",res);
}catch (Exception e){
System.out.println(e.getMessage());
}
break;
case 'h'://查看队列头的数据
try{
int res = circleQueue2.headQueue();
System.out.printf("队头的数据是:%d\n",res);
}catch(Exception e){
System.out.println(e.getMessage());
}
break;
case 'e':
scanner.close();
loop = false;
break;
case 'c':
System.out.println("队列中元素的个数为:"+circleQueue2.getNum());
default:
break;
}
}
System.out.println("程序退出");
}
}
class CircleQueue2{
private int maxSize; //数组的大小 = 队列的最大容量-1
private int[] array; //模拟队列的数组
private int front; //队首指针
private int rear; //队尾指针
public CircleQueue2(int maxSize){
this.maxSize = maxSize;
this.array = new int[maxSize];
this.front = 0;
this.rear = 0;
}
public boolean isFull(){
return (this.rear+1)%this.maxSize == this.front;
}
public boolean isEmpty(){
return this.front == this.rear;
}
public int getNum(){
return (this.rear-this.front+this.maxSize)%this.maxSize;
}
public void EnQueue(int addNum){
if(isFull()){
System.out.println("队列已满,无法加入");
return;
}else{
this.array[this.rear] = addNum;
this.rear = (this.rear+1)%this.maxSize;
}
}
public int DeQueue(){
if(isEmpty()){
throw new RuntimeException("队列为空,无法取出队首元素");
}else{
int getNum = this.array[this.front];
this.front = (this.front+1)%this.maxSize;
return getNum;
}
}
public void showQueue(){
if(isEmpty()){
System.out.println("队列为空");
}else{
int NumInQueue = (this.rear-this.front+this.maxSize)%this.maxSize;
for(int i=this.front;i<this.front+NumInQueue;i++) {
System.out.printf("%d\t",this.array[i%maxSize]);
}
System.out.println();
}
}
public int headQueue(){
if(isEmpty()){
throw new RuntimeException("队列为空,无队首元素");
}else{
return this.array[this.front];
}
}
}