数组实现固定大小的栈
public class Array2Stack<T> {
private T[] arr;
//size就是添加元素要存放的位置
private Integer size;
public Array2Stack(int initSize) {
if(initSize < 0) {
throw new IllegalArgumentException("The initSize must more than zero");
}else {
arr = (T[]) new Object[initSize];
size=0;
}
}
public T peek() {
if(size == 0) {
return null;
}else {
return arr[size-1];
}
}
public void push(T obj) {
if(size == arr.length) {
throw new ArrayIndexOutOfBoundsException("The Stack is full");
}
arr[size++] = obj;
}
public T pop() {
if (size == 0) {
throw new ArrayIndexOutOfBoundsException("The queue is empty");
}
return arr[--size];
}
}
数组实现循环队列
理解循环队列
循环队列可以解决普通队列的"假溢出"问题。
循环队列如何判断队满?
循环队列就可以用来解决 假溢出 问题, 当队列后面的满了,就从头在开始,形成头尾相接的循环.。 出现的问题: front=rear即头指针和尾指针相等,但是对应两种情况:一种是队列是空,一种是队列是满。
因此,我们定义循环队列中空出一个位置为满队列状态。front指向头元素,rear指向尾元素的下一个位置
head表示弹出时的位置
tail表示添加元素的位置
循环队列长度计算?
- 情况一:当tail大于head时,循环队列长度为 head - tail
- 情况二:当tail小于head时,循环队列的长度:分为两部分计算 0+tail 和 Quesize-head , 将两部分的长度合并到一起即为: tail-head+Quesize
public class Array2Queue {
private int[] d = null;// 队列空间
private int head = 0;// 队列头索引
private int tail = 0;// 队列尾索引
private int len = 0;// 队列最大长度
public Array2Queue(int len) {
this.len = len;
d = new int[len];
}
//入队函数
public void push(int x) {
if (isFull()) {
System.out.println("队列已满,入队失败");
} else {
d[tail] = x;
tail = (tail + 1) % len;
}
}
//出队函数
public void pop() {
if (isEmpty()) {
System.out.println("队列为空,出对失败");
} else {
head = (head + 1) % len;
}
}
//查看队首元素
public int front() {
return d[head];
}
//查看队尾元素
public int back() {
return d[(tail + len - 1) % len];
}
//查看队列元素总数
public int size() {
return (tail + len - head) % len-1;
}
//判断队列是否为空
public boolean isEmpty() {
//头尾索引相等表示队列为空
if (tail == head)
return true;
return false;
}
//判断队列是否为满
public boolean isFull() {
//尾索引的下一个为头索引时表示队列满,即将队列容量空出一个作为约定
if ((tail + 1) % len == head)
return true;
return false;
}
}
队列结构实现栈
用队列实现栈,可以用两个队列实现,一个用来插入数据,一个用来返回数据。push时直接把数据放在第一个队列中,pop时先把第一个队列里除了最后一个push进去的数全部push进第二个队列,最后的元素就是我们要pop出的元素,pop出后再把第二个队列中的数放进队列一,实际上直接交换引用也可以。
简单理解就是在需要弹栈时将队列其他元素全部Poll进另一个队列,留下最后一个元素即可
public static class TwoQueuesStack {
private Queue<Integer> queue;
private Queue<Integer> help;
public TwoQueuesStack() {
queue = new LinkedList<Integer>();
help = new LinkedList<Integer>();
}
public void push(int pushInt) {
queue.add(pushInt);
}
public int peek() {
if (queue.isEmpty()) {
throw new RuntimeException("Stack is empty!");
}
while (queue.size() != 1) {
help.add(queue.poll());
}
int res = queue.poll();
help.add(res);
//交换引用,将Data队列和Help队列互换
swap();
return res;
}
public int pop() {
if (queue.isEmpty()) {
throw new RuntimeException("Stack is empty!");
}
while (queue.size() > 1) {
help.add(queue.poll());
}
int res = queue.poll();
//交换引用,将Data队列和Help队列互换
swap();
return res;
}
private void swap() {
Queue<Integer> tmp = help;
help = queue;
queue = tmp;
}
}
栈结构实现队列
用栈实现队列结构,同样需要两个栈实现,一个栈用来Poll数据,另一个用来Push数据。Push时将数据放进栈一,Poll时将栈1的数据都放进栈2再Poll。
通过两个栈实现队列的先进先出
public static class TwoStacksQueue {
private Stack<Integer> stackPush;
private Stack<Integer> stackPop;
public TwoStacksQueue() {
stackPush = new Stack<Integer>();
stackPop = new Stack<Integer>();
}
public void push(int pushInt) {
stackPush.push(pushInt);
}
//将Push栈的元素Pop进Pop栈,这样就可以做到队列的先进先出
public int poll() {
if (stackPop.empty() && stackPush.empty()) {
throw new RuntimeException("Queue is empty!");
} else if (stackPop.empty()) {
while (!stackPush.empty()) {
stackPop.push(stackPush.pop());
}
}
return stackPop.pop();
}
public int peek() {
if (stackPop.empty() && stackPush.empty()) {
throw new RuntimeException("Queue is empty!");
} else if (stackPop.empty()) {
while (!stackPush.empty()) {
stackPop.push(stackPush.pop());
}
}
return stackPop.peek();
}
}