1、栈基础知识
1.1、栈的特征
形象比喻:子弹弹夹,第一颗的子弹最后打出。
1.2、栈的操作
栈的常用操作主要有:
- push(E):增加一个元素E
- pop(): 弹出元素E
- peek():显示栈顶元素,但是不出栈
- empty():判断栈是否为空
问题:入栈顺序为1234,所有可能的出栈序列是什么?
4个元素的全排列共有24中,栈要求符合后进先出,按此衡量排出后即有:
1234√,1243√,1324√,1342√,1423
1.3、Java中的栈
Java中的util中提供了栈Stack类,如下例子:
public class MainTest {
public static void main(String[] args) {
Stack stack = new Stack();
stack.push(1);
stack.push(2);
stack.push(3);
stack.push(4);
System.out.println("栈顶元素为:" + stack.peek());
while (!stack.empty()) {
//只显示没出栈
System.out.println("显示栈顶元素:" + stack.peek());
//出栈并显示
System.out.println("出栈并且显示:" +stack.pop());
}
}
}
2、基础数组实现栈
补充小知识:栈顶(top)有的地方指向栈顶元素,有的地方指向栈顶再往上的一个空单位。
入栈过程如下所示:
出栈的过程如图所示:
top先将栈顶元素取出,然后再执行top–。完整代码如下:
public class Mystack<T> {
//实现栈的数组
private Object[] stack;
//栈顶元素
private int top;
Mystack(){
//初始容量为10
stack = new Object[10];
}
//判断是否为空
public boolean isEmpty(){
return top == 0;
}
//返回栈顶元素
public T peek(){
T t = null;
if (top > 0){
t = (T) stack[top -1];
}
return t;
}
public void push(T t){
expandCapacity(top + 1);
stack[top] = t;
top++;
}
//出栈
public T pop(){
T t = peek();
if (top > 0){
stack[top -1] = null;
top--;
}
return t;
}
//扩大容量
public void expandCapacity(int size){
int len = stack.length;
if (size > len){
size = size * 3 / 2 + 1;//每次扩大50%
stack = Arrays.copyOf(stack,size);
}
}
//测试方法
public static void main(String[] args) {
Mystack<String> stack = new Mystack<>();
System.out.println(stack.peek());
System.out.println(stack.isEmpty());
stack.push("java");
stack.push("is");
stack.push("beautiful");
System.out.println(stack.pop());
System.out.println(stack.isEmpty());
System.out.println(stack.peek());
}
}
3、基于链表实现栈
链表也可以实现栈,插入和删除都在头结点进行。
代码完整实现如下:
public class ListStack<T> {
//定义链表
class Node<T> {
public T t;
public Node next;
}
public Node<T> head;
//构造函数初始化头指针
ListStack() {
head = null;
}
//入栈
public void push(T t) {
if (t == null) {
throw new NullPointerException("参数不能为空");
}
if (head == null) {
head = new Node<T>();
head.t = t;
head.next = null;
} else {
Node<T> temp = head;
head = new Node<>();
head.t = t;
head.next = temp;
}
}
//出栈
public T pop(){
if (head ==null){
return null;
}
T t = head.t;
head = head.next;
return t;
}
//取栈顶元素
public T peek(){
if (head ==null){
return null;
}
T t = head.t;
return t;
}
//栈空
public boolean isEmpty(){
if (head == null){
return true;
}else {
return false;
}
}
//测试方法
public static void main(String[] args) {
ListStack stack = new ListStack();
System.out.println(stack.isEmpty());
stack.push("KAva");
stack.push("is");
stack.push("beau");
System.out.println(stack.peek());
System.out.println(stack.pop());
System.out.println(stack.isEmpty());
}
}