我们知道队列是一个非常常用的底层数据结构
他具有先进先出(FIFO)的特性
而和他很亲近的栈具有先进后出的特性当然我们知道栈和队列都可以利用数组和链表实现特性
我们今天来考虑两个事情:
1、使用数组实现循环队列结构
2、使用双栈实现队列结构
使用数组实现循环队列结构
一个队列的状态
- 插入节点的时候向end指针指向的位置插入节点,然后end向后移动
- 出队的时候将head 指针指向的位置的数据出队,head指针后移
- 当head等于end的时候队列为空
- 当添加元素end后移之后,与head相等,说明队列已满这时候需要扩容
- 上述的向后移动都不是单纯的,而是加一然后对数组长度进行除余
public class RoundQue<T> {
private T[] dataBase = (T[])new Object[10];
private int head = 0;
private int end = 0;
public void add(T t){
System.out.println("head:"+head+" 数据:"+t);
dataBase[head] = t;
head = (head+1)%dataBase.length;
if(head == end){
System.out.println("队列满为空,当前的长度是"+dataBase.length);
T[] dataBase1 = (T[])new Object[dataBase.length*2];
int e = end;
for(int i = 0; i < dataBase.length ; i++){
dataBase1[e+i] = dataBase[end];
end = (end+1)%dataBase.length;
}
head += (dataBase.length);
dataBase = dataBase1;
}
}
public T get(){
System.out.println("当前head为"+head+"当前end为"+end);
if(head == end){
System.out.println("队列为空");
return null;
}
T t = dataBase[end];
dataBase[end] = null;
end = (end+1)%dataBase.length;
return t;
}
}
使用双栈实现队列结构
是不是很奇葩
用栈实现队列可能会更加的麻烦,用两个栈无形中增加了空间负责度
不过两个栈中一个出队栈、一个入队栈,分开操作,不会相互影响更加安全
- 初始的两个空的栈
- 添加数据(入队)直接进入 入队栈
- 如果现在要进行出队 ,从 出队栈 中出栈,入过当前栈为空,则将入队栈中的数据全部出队依次放入入队栈(这样在入队栈中是倒序的,到了出队栈就成了顺序)
public class TwoStackForQue<T> {
private Stack<T> stackout = new Stack<T>();
private Stack<T> stackin = new Stack<T>();
private int count;
public void add(T t){
if(t!=null) {
stackin.add(t);
}else{
System.out.println("插入值为空,对不起不能插入");
}
}
public T pop() {
if(stackout.isEmpty()&&!stackin.isEmpty()){
while(!stackin.isEmpty()){
stackout.add(stackin.pop());
}
}
return stackout.pop();
}