在数据结构中,栈的应用十分广泛,比如说:括号匹配问题、二叉树的遍历、迷宫路径搜索问题、非递归遍历问题、回溯搜索问题、递归转非递归等问题,栈的特点是先进后出(或者说后进先出)。
1.栈的java实现
/*
* 用java数组实现简单的栈
* */
public class StackX {
private int maxSize;
private Object[] stackArray;
private int top;
public StackX(int s) {
maxSize = s;
stackArray = new Object[maxSize];
top = -1;
}
// 入栈
public void push(Object i) {
if (top != maxSize - 1) {
stackArray[++top] = i;
}
}
// 出栈
public Object pop() {
if (top != -1) {
return stackArray[top--];
} else {
return 0;
}
}
// 查看栈顶元素
public Object peek() {
return stackArray[top];
}
// 判断栈是否为空
public boolean isEmpty() {
return top == -1;
}
}
在刷题的过程中,会发现许多算法使用的就是栈的数据结构,下面总结一些平时刷题过程中用到栈数据结构的面试题。
2.1 二叉树的前、中、后序遍历,我在之前的博客中就已经实现过了,有兴趣的话可以去看一下,二叉树的四种遍历
2.2 用两个栈实现队列
package org.algorithm.pointtooffer;
import java.util.Stack;
/**
* 面试题7:用两个栈实现队列
*
* @author dell
*
*/
/**
* 构造一个类
*
* @author dell
*
* @param <T>泛型
*/
class CQueue<T> {
// 两个栈
private Stack<T> stack1;
private Stack<T> stack2;
public CQueue() {
this.stack1 = new Stack<T>();
this.stack2 = new Stack<T>();
}
/**
* 模拟在队列末尾插入
*
* @param node
*/
public void appendTail(T node) {
stack1.push(node);
}
/**
* 模拟删除队列的头
*
* @return
*/
public T deleteHead() {
if (stack2.size() == 0) {
if (stack1.size() == 0) {
try {
throw new Exception("队列为空");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// stack1 不为空,将stack1中的元素放入stack2中
while (stack1.size() > 0) {
stack2.push(stack1.pop());
}
}
return stack2.pop();
}
}
public class Item07 {
// 测试
public static void main(String args[]) {
// 在队列中增加元素
CQueue<Integer> cq = new CQueue<Integer>();
for (int i = 0; i < 5; i++) {
cq.appendTail(i);
}
// 依次取出
for (int i = 0; i < 5; i++) {
System.out.print(cq.deleteHead() + "、");
}
System.out.println();
// 此时为空,再取一次,看会不会报错
cq.deleteHead();
}
}
2.3包含min函数的栈(剑指offer和leetcode中都包含了)
import java.util.Stack;
/**
* 面试题21:包含min函数的栈
*
* @author dell
*
*/
class StackWithMin {
private Stack<Integer> stack;
private Stack<Integer> stackHelp;// 一个辅助的栈
public StackWithMin() {
stack = new Stack<Integer>();
stackHelp = new Stack<Integer>();
}
/**
* 直接插入stack中,在插入stackHelp时,如果为空则直接插入,或者要判断与顶部元素的大小,若小于则插入,若大于则继续插入顶部元素
*
* @param t
* 待插入元素
*/
public void push(int t) {
stack.push(t);
// 插入辅助的栈
if (stackHelp.size() == 0 || t < stackHelp.peek()) {
stackHelp.push(t);
} else {
stackHelp.push(stackHelp.peek());
}
}
/**
* 出栈,要求stack和stackHelp均不为空
*
* @return
*/
public int pop() {
assert (stack.size() > 0 && stackHelp.size() > 0);
stackHelp.pop();
return stack.pop();
}
/**
* 取得最小值,最小值一定是stackHelp的栈顶元素
*
* @return
*/
public int min() {
assert (stack.size() > 0 && stackHelp.size() > 0);
return stackHelp.peek();
}
}