package com.hblg.queue;
import java.util.Scanner;
import java.util.concurrent.ForkJoinPool;
/**
* @author i
* @create 2019/9/9 19:19
* @Description 用数组实现环形队列的思路整理
* 环形队列结构分析:
* 我们可以得知数组队列在一定程度上,是只有一次使用权限,当队列中数据处于满状态,就没有办法使用
* 因此,环形队列从某种角度上可以解决这个问题。
* 1.做一个约定那就是当尾索引的下一个为头索引时,表示队列满,预留出一个位置用于存放
* 所以队列满=:(rear+1)%maxSize = front;
* 2.队列为空时
* rear = front
* 3.队列中有效数据的计算
* (rear+maxSize-front)%maxSize
* 1+3-0%3 1
* 2+4-2%4 0
* 4.在取数据和添加数据的时候 我们要考虑到front和rear的变化,有一种极端的情况
* 就是当队列数据为满的情况下,循环队列从头开始存储数据,因此 这块和数组队列上是一个很大的不同点
* 也就是实现循环队列的前提条件。
*/
public class CircleArrayDemo {
public static void main(String[] args) {
CircleArray circleArray = new CircleArray(5);
boolean flag = true;
Scanner scanner = new Scanner(System.in);//获取键盘输入的数据
while(flag){
System.out.println("A(Add) 添加数据");
System.out.println("G(Get) 获取数据");
System.out.println("S(Show) 展示数据");
System.out.println("T(Exit) 退出程序");
System.out.println("H(Head) 查询队头数据");
char chars = scanner.next().charAt(0);//获取键盘上的数据
switch (chars){
case 'A':
try {
//添加数据
circleArray.addDataQuene(scanner.nextInt());
}catch (Exception e){
e.printStackTrace();
};break;
case 'G':
System.out.println(circleArray.getHeadData());
break;
case 'S':
circleArray.printAllData();
break;
case 't':
flag = true;
scanner.close();//关闭对io流的操作
break;
case 'H':
System.out.println(circleArray.getHeadValue());
break;
}
}
}
}
/***
* 用数组实现环形队列,
*/
class CircleArray{
private int maxSize;//队列最大空间
private int front;//队列头部
private int rear;//队列尾部
private int [] array;
//构造方法进行初始化
public CircleArray(int maxSize){
this.maxSize = maxSize;
rear = 0;
front = 0;
array = new int [maxSize];
}
//是否为空
public boolean isEmpty(){
return rear == front;
}
//是否为满
public boolean isFull(){
return (rear+1)%maxSize == front;
}
//向队列中添加数据
public void addDataQuene(int data){
//先判断是否为满
if(isFull()){
throw new RuntimeException("队列为满,不能添加数据");
}
array[rear] = data;
rear = (rear+1)%maxSize;
//这里必须要进行对maxSize进行取模,如果当前超出了队列范围,就需要从头开始 覆盖掉之前的数据,从而形成一个新的队列
}
//取出队头数据
public int getHeadData(){
if(isEmpty()){
throw new RuntimeException("队列为空,不能查!");
}
int value = array[front];
front = (front+1)%maxSize;//这里和rear是一样的
return value;
}
//打印所有数据
public void printAllData(){
for (int i = front; i < front+getArrayQueneLength(); i++) {
System.out.print(array[i%maxSize]+" ");
//i%maxSize 含义 当前数据位于front位置,因此 我们要考虑到
}
}
//查询队头数据 不取出
public int getHeadValue(){
if(isEmpty()){
throw new RuntimeException("队列为空 不能查看!");
}
return array[front];
}
//获取当前队列中的数据个数
private int getArrayQueneLength(){
return (rear+maxSize-front)%maxSize;
}
}