循环数组队列
和栈一样,队列也是表,但是使用队列的特点是先进先出。
队列模型
队 列 的 基 本 操 作 是 入 队 , 它 是 在 表 的 末 端 插 入 一 个 元 素 , 和 出 队 , 它 是 删 除 在 表 开 头 的 一 个 元 素 \color{black}{队列的基本操作是入队,它是在表的末端插入一个元素,和出队,它是删除在表开头的一个元素} 队列的基本操作是入队,它是在表的末端插入一个元素,和出队,它是删除在表开头的一个元素
队列的循环数组实现
- 实现队列的类
import java.util.Arrays;
/**
* @author 李正阳
* @param <E> 泛型存储类型
*/
public class MyArrayQueue<E> implements queue<E> {
/**
* @param rear 队尾
* @param front 队头
* @param size 数组中现在有多少个元素
* @param MAX_CAPATIAL 数组的总大小
* @param array 存储元素的数组
*/
private int rear;
private int front;
private int size;
private final int MAX_CAPATIAL=10;
private Object[] array;
/**
* 构造方法 初始化数组和相关的值
*/
public MyArrayQueue(){
array=new Object[MAX_CAPATIAL];
rear=0;
front=0;
size=0;
}
/**
* 入队方法
* 先给size遍历加一,如果队列满了,就给size变量减一
* 若队列未满就给队尾加一赋值
* @param p 需要入队的元素
* @return true 成功入队 false 入队失败
*/
@Override
public boolean push(Object p) {
size++;
if(isFull()){
System.out.println("队列满了");
size--;
return false;
}else{
if(rear>=MAX_CAPATIAL){
rear=0;
array[rear++]=p;
}else{
array[rear++]=p;
}
}
return true;
}
/**
* 出队方法
* 先判空再出队
* @return 出队的泛型类型的元素
*/
@Override
public E pop() {
size--;
E temp=(E) array[front];
if(isEmpty()){
System.out.println("队列为空");
}else{
front++;
if(front>MAX_CAPATIAL){
front=0;
}
}
return temp;
}
/**
* 表的长度
* @return 表中有多少哥元素
*/
@Override
public int size() {
return size;
}
/**
* 从表头到表尾输出表中的元素
*/
@Override
public void travel() {
int i=front;
while (true){
System.out.print(array[i++]+" ");
if(i==MAX_CAPATIAL){
i=0;
}
if(i==rear){
break;
}
}
System.out.println();
}
/**
* 判断表是否为空
* @return true 表为空 false 表不为空
*/
@Override
public boolean isEmpty() {
if(size==0){
return true;
}else{
return false;
}
}
/**
* @return 返回队尾元素
*/
@Override
public E getRear() {
return (E) array[rear];
}
/**
* @return 返回队头元素
*/
@Override
public E getFront() {
return (E)array[front];
}
/**
* 判断表是否满了
* @return true 队列满了 false 队列未满
*/
private boolean isFull(){
if(size>MAX_CAPATIAL){
return true;
}else{
return false;
}
}
}
- 实现接口文件
/**
* 队列的接口
* @param <E> 泛型类型
*/
public interface queue<E> {
/**
* 入队方法
* @param p
* @return
*/
boolean push(E p);
/**
* 出队方法
* @return 返回泛型类型的方法
*/
E pop();
/**
* 表中元素的大小
* @return
*/
int size();
/**
* 输出表中元素
*/
void travel();
/**
* 判断表是否为空的
* @return true 表是空的 false 表是非空
*/
boolean isEmpty();
/**
* 获取表尾元素
* @return 表尾的元素
*/
E getRear();
/**
* 获取表头的元素
* @return 表头的元素
*/
E getFront();
}
为什么要使用循环数组
5 | 6 | 8 | 6 | 7 | |||
---|---|---|---|---|---|---|---|
front | rear |
例如这样一个数组,如果再入队一个,不看成循环数组的话,就队满了。
循环数组就是将一个线性数组看成一个圆形数组,即头尾相连:
1 | 2 | 5 | 6 | 8 | 6 | 7 | 9 |
---|---|---|---|---|---|---|---|
rear | front |
当入队时队尾和队头相等时就已经队满了