提示:所有的函数都有思路讲解,具体请大家看具体函数中的注释,如有问题请留言
一、环形队列?
队列是一个有序列表,可以用数组或是链表来实现。
遵循先入先出的原则。
即:先存入队列的数据,要先取出。后存入的要后取出
实现思路
1)既然是环形队列,那就一定有头有尾,有容量
2)既然是数组实现,那一定有个算法保证可以让数组循环起来
二、代码实现
1.代码实现
package com.data.queue;
/**
* 环形数组实现队列
*/
public class Queue1 {
int[] array;
int raer;//队列尾巴,动态的记录着为空的下标
int front;//记录这队伍首的下标
int maxSize;//记录数组长度
public Queue1(int maxSize){
//通过有参构造创建数组 并且给maxSize赋值
this.maxSize=maxSize;
array=new int[maxSize];
}
//判断是否为满
public boolean isFull(){
return (raer+1)%maxSize==front;
/**
* 此处的思路应该是raer的下一个位置就是front的位置,想象环形数组连接上了,只有rear本身
* 没有值,作为动态的空空间
* 此处取模 是为了防止raer+1后的值等于maxSize,正常等于maxSize后应该为0,
* 否则超出数组下标的最大值就不可能等于front
*/
}
//判断是否为空
public boolean isEmpety(){
/**
* 判断数组时候为空的思路应该是,如果队列首位front等于rear,
* 就说明队列头本身就没有值,就是空的,所以队列整体为空
*/
return raer==front;
}
//获取有效数值个数
public int getNumber(){
return (raer+maxSize-front)%maxSize;
/**
* 思路
* 相信大家的思路都是rear-front 直接取到有效数值的个数,但是
* 获取数组的有效数值,我们想一种情况,就是rear-front为负数,如果不知道这种情况是怎么发生的
* 请看图,自己想象不断取值和存值 的过程中有没有可能会发生以上情况
* 如果以上情况发生,我们取到的负数就不是实际有效数值的个数
* 这个时候就应该给rear加上maxSize 让他多跑一圈再减去front即(rear+maxSize-front)
* 此时的在和maxSize取模 就能得到我们要的实际有效参数的数值
*
* !!至于为什么要这样做,我们可以通过自己不断的尝试,就能总结出我们这么做正确的
*
*/
}
//添加数值 不必多说
public void add(int a){
if (isFull()){
throw new RuntimeException("满了");
}
array[raer]=a;
raer=(raer+1)%maxSize;
}
//取出数值 不必多说
public int getInt(){
if (isEmpety()){
throw new RuntimeException("空了");
}
int tump=array[front];
front=( front+1 )%maxSize;
return tump;
}
//遍历数组
public void show(){
System.out.println("a");
if (isEmpety()){
throw new RuntimeException("kongde");
}
/**
* 遍历数字的思路
* 我们知道front,肯定就是要从array[front] 开始遍历
* 但是遍历多少呢? length? 肯定是不行的
* 我们要遍历到rear? 也不行 因为有可能rear比front还小
*
* 所以我们这里先取到有效数值的个数sum,让front+sum 不就是末尾的位置吗,
* 但是由于我们的maxSize是有限的,一旦(front+sum)超出下标位置,会发生下标越界异常
* 这里我们保持循环的次数不变,让数组的下标写成array[i%maxSize]
* 这样就能找到我们的真实下标 达到遍历的效果
*/
int sum=getNumber();
for (int i = front; i <front+sum; i++) {
System.out.print(array[i%maxSize]+" ");
}
}
}
总结
提示:这里对文章进行总结:
取模这个东西真的很神奇 ,由于本人没详细学过,多以不能为大家提供详细的讲解,如果有厉害的同学,请给我留言,谢谢.