数据结构-数组循环队列 作者:哇塞大嘴好帥
作者:哇塞大嘴好帥(哇塞大嘴好帅)
思路分析:
foot永远指向序列尾
head永远指向队列头部的后一位
当队列满的时候,条件是: (head + 1) % 数组容量 == foot (详细介绍在最下方的代码分析)
当队列为空的时 条件是:head == foot(详细介绍在最下方的代码分析)
获取队列中有效数据个数 条件为:(head + 数组容量 - foot) % maxSize(详细介绍在最下方的代码分析)
此文章一定要耐心看完,我会把为什么这样做以及错误的示范,正确的代码都会给你讲解,让你彻底懂数组循环队列。
1.代码
package com.dazuizui;
import java.lang.reflect.Array;
public class QueueArray1 {
public static void main(String[] args) {
CircleArray circleArray = new CircleArray(5);
System.out.println("======================");
System.out.println("添加数据");
circleArray.putArrayMember(12);
circleArray.putArrayMember(13);
circleArray.putArrayMember(13);
circleArray.putArrayMember(14);
circleArray.putArrayMember(15);
System.out.println("======================");
System.out.println("显示队列");
circleArray.showListArray();
System.out.println("======================");
System.out.println("弹出");
circleArray.numberExit();
circleArray.numberExit();
circleArray.numberExit();
circleArray.numberExit();
circleArray.numberExit();
circleArray.numberExit();
System.out.println("头部坐标"+circleArray.head+"foot:"+circleArray.foot);
circleArray.putArrayMember(13);
System.out.println("插入成功");
System.out.println("头部坐标"+circleArray.head+"foot:"+circleArray.foot);
circleArray.showListArray();
circleArray.putArrayMember(13);
circleArray.putArrayMember(13);
System.out.println("======================");
circleArray.showListArray();
}
}
class CircleArray{
private int maxSize ; //数组长度
int head = 0;
int foot = 0;
private int array[] ; //可使用的数组空间
/**
* 进行初始化
* @param maxSize 数组长度
*/
public CircleArray(int maxSize){
this.maxSize = maxSize;
array = new int[maxSize];
}
//如果为空
public boolean isNull(){
return head == foot;
}
/**
* 如果数列为满 如果 (5+1 % 6 == foot
* @return
*/
public boolean isMax(){
return (head+1) % maxSize == foot;
}
/**
* 添加数组
*/
public void putArrayMember(int num){
//0.判断数组是否为满
if (isMax()){
System.out.println("您的列表满了");
return;
}
//1.将数据添加到进入
array[head] = num;
//2.将表头的数据前进一格
head = (head + 1) % maxSize;
System.out.println("长孺成功当前坐标为"+head);
return;
}
/**
* 显示所有数组
*/
public void showListArray(){
//0.判断是否为null
if (isNull()){
throw new RuntimeException("数组为null");
}
System.out.println("\n\n当前head:"+head+"foot"+foot+"有效数据"+vDataSize()+"数组大小"+maxSize);
System.out.println(vDataSize()+foot+"/*/*");
//遍历有效数据
for (int i = foot; i < vDataSize()+foot ; i++) {
System.out.println(array[i%maxSize]);
}
}
/**
* 查询有效数据
* 假设 head 为 3
* foot 为 2
* 大小 为 4
*/
public int vDataSize(){
return (head + maxSize - foot) % maxSize;
}
/**
* 弹出数
*/
public void numberExit(){
//-0判断是否为null
if (isNull()){
System.out.println("数组为null");
return;
}
System.out.println("当前坐标"+foot);
//0.弹出数组的值
System.out.println(array[foot]);
//1.尾指针后移
foot = (foot + 1) % maxSize;
System.out.println("弹出后坐标"+foot);
}
}
2.代码分析
构造方法初始化部分
/**
* 进行初始化
* @param maxSize 数组长度
*/
public CircleArray(int maxSize){
this.maxSize = maxSize;
array = new int[maxSize];
}
当我们传递5进此方法,该构造器就会把数组长度赋值给maxSize,并且创建一个长度为5的数组。
接下来看是否为空方法
//如果为空
public boolean isNull(){
return head == foot;
}
只要**(head+1) % maxSize == foot相等就证明数组为Null**
如以下表格进行理解
数组下标 | 值 | 描述 |
---|---|---|
0 | 1 | 已经被弹出 |
1 | 2 | 已经被弹出 |
2 | 3 | 已经被弹出 |
3 | 头指针和尾指针都在此处 | 我们知道foot每次弹出后都会条件是: (foot+ 1) % 数组容量 head的算法是条件是: (head + 1) % 数组容量当他们相撞的时候就正常该队列没有元素了。 |
队列满载的方法
/**
* 如果数列为满
* @return
*/
public boolean isMax(){
return (head+1) % maxSize == foot;
}
假设现在head为4 foot为0 maxSize为5将数值代入这时候算法为:
(4+1) % 5 = 0;
这时候结果与foot相等,就证明了该队列为满载状态。
只有满载 (head+1) % maxSize == foot该条件才会满足,如果我们的队列没有满足他的可视图是这个样子的。
往列表增加元素方法
/**
* 添加数组
*/
public void putArrayMember(int num){
//0.判断数组是否为满
if (isMax()){
System.out.println("您的列表满了");
return;
}
//1.将数据添加到进入
array[head] = num;
//2.将表头的数据前进一格
head = (head + 1) % maxSize;
System.out.println("长孺成功当前坐标为"+head);
return;
}
首先它做了判断是否为满的,如果为满,那么停止添加。
如果数组不为满,它会在 array[head] = num; ,当添加完数组他head会重新赋值将自己的下标后移一位。算法为:(head + 1) % maxSize
看弹出元素
/**
* 弹出数
*/
public void numberExit(){
//-0判断是否为null
if (isNull()){
System.out.println("数组为null");
return;
}
//0.弹出数组的值
System.out.println(array[foot]);
//1.尾指针后移
foot = (foot + 1) % maxSize;
}
首先判断是否为null,如果为null,程序停止操作。
如果不为NULL,那么就弹出array[foot]的数据,弹出之后经过(foot+1) % maxSize算法将自己坐标后移一位。
查询队列有效数据个数
/**
* 查询有效数据
* 假设 head 为 3
* foot 为 2
* 大小 为 5
*/
public int vDataSize(){
return (head + maxSize - foot) % maxSize;
}
假设现在head为2 foot为4 大小为5 将数值代入:(2+5-4)%5 = 3 这时候算出来有效数据有3个
查询队列数据
/**
* 显示队列数据
*/
public void showListArray(){
//0.判断是否为null
if (isNull()){
throw new RuntimeException("数组为null");
}
//遍历有效数据
for (int i = foot; i < vDataSize()+foot ; i++) {
System.out.println(array[i%maxSize]);
}
}
首先判断是否为Null,接下来注意for循环
首先i = foot 因为foot代表列表尾巴,也就是说先进入的数据,接下来看 i < vDataSize()+foot 已知现在有效数据为3个,vDataSize()+foot = 7 foot = 4 也就是通过3次循环把队列中的3个有效数据打印出来。
第一次循环: i% maxSize = 4 这时候i=4,maxSize=5 把array数组第4个数据读取出来.
第二次循环: i% maxSize = 0 这时候i=5,maxSize=5 把array数组第0个数据读取出来.
第三次循环: i% maxSize = 1 这时候i=6,maxSize=5 把array数组第1个数据读取出来.
3.为什么数组中要空一个空间
因为方便计算空出一个空间