提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
目录
为什么要是用环形队列
提示:这里可以添加本文要记录的大概内容:
1.普通队列的数组尾部用完了,头部又取出一些元素,因为尾部已经用完了导致无法进行继续添加元素 导致 溢出(假溢出,前面取出的位置是空着的)由此推出解决方案 环形队列
提示:以下是本篇文章正文内容,下面案例可供参考
一、思路
本文 read代表头下标 front代表尾巴下标
- 环形队列 头下标(read) 尾下标(front) 初始下标都为0
- 尾下标指向的值 始终都是空
- 接第二条 为什么始终都为空呢?因为环形队列 会 拿一个元素位置 来当作 约束,也就是说给定 数组队列 容量(size)为 4个元素, 实际他只可以存放3个元素。还有一个元素要保持为空,而指向的那个空值就是 环形队列的约束。
- 我们要把环形队列想象成一个圆环 首尾相接
二、操作步骤详解
1.判断什么样的情况下环形队列是满的
当环形队列的尾部下标(被约束的空值)在 头下标前一个时 如下图
代码如下(示例):
//判断数列是否已经满
public boolean isFull(){
//当队列的尾巴下标+1 等于 头部下标时
return (read+1)%MaxSize==front;
}
2.判断环形队列是否为空
尾下标==头下标时
public boolean isNull(){
return read==front;
}
3.为环形队列添加元素
- 判断队列是否已满 如果没满添加数据
- 添加元素
- 将read 尾下标指向下一个空元素
如不理解read=(read+1)%MaxSize 先看第五步
public void addQueue(int value){
//当队列没有满的时候可以添加数据
if (isFull()){
System.out.println("队列已满 无法添加数据");
return;
}
//在队列read下标出添加数据
Queue[read]=value;
//将尾部指向下一个空元素下标, read=(read+1)%MaxSize 为什么使用这个算法呢
//因为 下标不能超过 给定的队列最大容量(size)-1 如果超过就会下标越界
read=(read+1)%MaxSize;
}
4.取出队列中的元素
- 判断队列是否为null
- 将变量保存到临时变量 如果直接return 就无法让头下标指向下一个值
- 将头下标指向下一个值
如不理解 front=(front+1)%MaxSize 先看第五步
public int getQueue(){
if (isNull()){
throw new RuntimeException("队列为空 无数据可取");
}
//将数据保存到一个临时变量 如果直接return 就无法让头下标指向下一个值
int value=Queue[front];
//因为 下标不能超过 给定的队列最大容量(size)-1 如果超过就会下标越界
front=(front+1)%MaxSize;
return value;
}
5.为什么使用(下标+1)%maxsize
- 开头思路说过 我们要把环形队列想象成一个首尾相连的一个圆环
- 倘若 尾下标read 此刻 指向下标3的空元素而头下标指向下标1的元素。这个时候, 队列是没有满的 (下标3 下标0 都是空的), 所以还可以添加新的数据进去 。
- 第三步的时候 说过添加完元素后 尾下标会指向下一个空值 。 所以在尾下标为3处添加了元素 那么我们的尾下标就要指向下一个空值,已知我们的maxsize=4 所以如果 用尾下标read+1 就等于 4 就造成下标越界,那么当我们拿(read+1)%maxize(4)的余 那么 尾下标read 指向了 下标为0的空值 如下图:
6.显示队列有些数据
- 因为循环队列就像一个圆环 可能read尾下标为1,而头下标front为2 这个时候如果(1-2)%余就是一个负数
- 如果直接拿尾下标-头下标就会取出负数 加上maxsize就可以解决这个负数的问题
public void QueuetoString(){
if (isNull()){
throw new RuntimeException("队列为空 无数据");
}
//起始位置为头下标, 循环次数就是 头下标 到 头下标+数据个数
for (int i = front; i <front+size() ; i++) {
//使用1%数组最大容量是防止下标越界
System.out.printf("arr[%d]的值为:%d", i%MaxSize,Queue[i%MaxSize]);
}
}
//有效数据个数
public int size(){
return (read+MaxSize-front)%MaxSize;
}
7.显示头数据
和取数据差不多就是不用去把头下标向后加
public void showfrontData(){
if (isNull()){
System.out.println("队列为空 无数据可取");
return;
}
System.out.println(Queue[front]);
}
该处使用的url网络请求的数据。
总结
环形队列 主要在于 对 %的使用