(本人对于环形队列的代码解析,仅供个人观点)
public class ArrayTest {
public static void main(String[] args) {
Scanner myScan = new Scanner(System.in);
boolean loop = true;
System.out.println("请输入最大队列数:");
LoopArray loopArray = new LoopArray(myScan.nextInt());
while (loop){
System.out.println();
System.out.println("1. 添加数据");
System.out.println("2. 取出数据");
System.out.println("3. 显示数据");
System.out.println("4. 退出程序");
System.out.println("请输入你的选择....");
char key = myScan.next().charAt(0);
switch (key){
case '1':
System.out.println("请输入要添加的数字:");
loopArray.add(myScan.nextInt());
break;
case '2':
loopArray.get();
break;
case '3':
loopArray.list();
break;
case '4':
loop = false;
myScan.close();
break;
case '5':
default:
System.out.println("您的输入有误。");
}
}
System.out.println("您退出了程序...");
}
}
//循环数组的类
class LoopArray{
int maxSize;//规模
int HeadIndex;//头索引
int FootIndex;//尾索引
int[] arr;//数据存放
public LoopArray(int maxSize){
maxSize++; //+1是为了尾索引判断留出一个空位置
this.maxSize = maxSize;//规模
this.HeadIndex = 0;//头索引初始化
this.FootIndex = 0;//尾索引初始化
this.arr = new int[maxSize]; //初始化
}
//是否空
public boolean isNull(){
return HeadIndex == FootIndex; //当头尾索引重叠在一起时即判断为空
}
//是否满
public boolean isFull(){
return (FootIndex + 1) % maxSize == HeadIndex;//当循环时尾下一个是头索引时判断为满
}
//增加
public void add(int data){
if(isFull()){
System.out.println("已满...");
}else{
arr[FootIndex] = data;//存放
FootIndex = (FootIndex + 1) % maxSize;//指下一个坐标
}
}
//取出
public void get(){
if(isNull()){
System.out.println("已空....");
}else{
// HeadIndex %= maxSize;(错误示范)
arr[HeadIndex] = 0;//模拟取出(变0)
HeadIndex = (HeadIndex + 1) % maxSize; //最后再改变不是前面改变是因为判断时需要用到headIndex不能放进前面
System.out.println("已经取出");
}
}
//列表
public void list(){
if(isNull()){
System.out.println("已空....");
}else{ //从头索引开始遍历 , 遍历到 头索引+有效个数为止
for(int i = HeadIndex; i < HeadIndex + getSize(); i++){
//为了方便理解,这里多加了一个temp变量, i %maxSize 的目的是为了不超过数组大小,循环得以顺利进行
int temp = i % maxSize;
System.out.print(arr[temp] + "\t");
}
}
}
//有效个数
public int getSize(){
if(isNull()){
System.out.println("为空。");
return 0;
}
return (FootIndex + maxSize - HeadIndex) % maxSize;
//当FootIndex 比 HeadIndex 大时, 有效个数 就是 FootIndex - HeadIndex;
//当FootIndex小于HeadIndex时,就让FootIndex先转一个周期,即 FootIndex + maxSize,这时候FootIndex绝对大于
//HeadIndex, 这时候减去HeadIndex,就是非负数 ,也就是 (FootIndex + maxSize - HeadIndex)
// 但是不知道是大是小,所以可以统一取模 maxSize...
// 因为 FootIndex 和 HeadIndex 永远小于等于maxSize,所以取模 maxSize 都等于它本身;
//所以当F(FootIndex) 比 H(HeadIndex) 大时,式子可以变成这样:
// FootIndex - HeadIndex ====> (FootIndex - HeadIndex + maxSize) % maxSize 取模不会影响结果;
//化成这样的式子是为了适应 F 比 H 小的时候,即为了通用;
//当然,搞不明白的话也可以把 return (FootIndex + maxSize - HeadIndex) % maxSize 改成以下:
// if(FootIndex > HeadIndex){
// return FootIndex - HeadIndex;
// }else{
// return (FootIndex + maxSize - HeadIndex);
// }
}
}
(本人对于环形队列的代码解析,仅供个人观点)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ? ? ? ? ? ---2022-02-06
|