栈
栈 (stack)又称堆栈,只允许在表的一端进行加入数据(push)和移除数据(pop)。因而按照 后进先出(LIFO, Last In First Out) 的原理运作。通常称能够进行插入、删除运算的一端为栈顶(Top),另一端称为栈底(Bottom)。当表中没有元素的时候称为空栈。
空栈时最先插入的元素总被放在栈的底部,只有所有元素被移除(弹出)后,它才能被删除
栈的存储结构有顺序存储结构和链式存储结构两种。在顺序栈中,可以考虑栈的上溢;在链式栈中,不必考虑栈的上溢,只需要考虑栈的下溢
栈的上溢是一种出错状态,应该设法避免;而下溢则是正常现象,可作为程序控制转移的条件
顺序栈
顺序栈 常用一维数组来实现
Java代码实现:
public class MyStack {
private int[] storage;//存放栈中元素的数组
private int capacity;//栈的容量
private int count;//栈中元素数量
private static final int GROW_FACTOR = 2;
//不带初始容量的构造方法。默认容量为8
public MyStack() {
this.capacity = 8;
this.storage=new int[8];
this.count = 0;
}
//带初始容量的构造方法
public MyStack(int initialCapacity) {
if (initialCapacity < 1)
throw new IllegalArgumentException("Capacity too small.");
this.capacity = initialCapacity;
this.storage = new int[initialCapacity];
this.count = 0;
}
}
链式栈
链式栈 常用链表来实现
Java代码实现:
public class LinkedList<E> {
private class Node{
public E e;
public Node next;
public Node(E e, Node next){
this.e = e;
this.next = next;
}
public Node(E e){
this(e, null);
}
public Node(){
this(null, null);
}
}
常见应用场景
浏览器的回退和前进
我们只需要使用两个栈(Stack1 和 Stack2)和就能实现这个功能。比如你按顺序查看了 1,2,3,4 这四个页面,我们依次把 1,2,3,4 这四个页面压入 Stack1 中。当你想回头看 2 这个页面的时候,你点击回退按钮,我们依次把 4,3 这两个页面从 Stack1 弹出,然后压入 Stack2 中。假如你又想回到页面 3,你点击前进按钮,我们将 3 页面从 Stack2 弹出,然后压入到 Stack1 中。
反转字符
利用栈后进先出的特征,将栈中的每个字符先入栈,再出栈即可。
分隔符匹配
栈通常用于解析某种类型的文本串。通常,文本串是用计算机语言写的代码行,而解析它们的程序就是编译器。
分隔符匹配程序从字符串不断地读取字符,若它是左分隔符,则压入栈中。当从输入中读取到一个右分隔符时,弹出栈顶的左分隔符,并查看它和右分隔符是否匹配。如果栈中没有匹配的左右分隔符,或栈中一直存在着没有被匹配的分隔符(所有字符读入后,栈中仍有分隔符),则程序报错。
Java中的代码实现:
public class BracketChecker {
public static void main(String[] args) {
String s ;
s = getString();
BracketChecker bracketChecker = new BracketChecker(s);
bracketChecker.check();
}
private String input;
public BracketChecker(String input) {
this.input = input;
}
public void check() {
Stack<Character> stack = new Stack<>();
for (int i = 0; i < input.toCharArray().length; i++) {
char ch = input.charAt(i);
switch (ch) {
case '{':
case '[':
case '(':
stack.push(ch);
break;
case '}':
case ']':
case ')':
if (!stack.isEmpty()) {
char chx = stack.pop();
if ((ch == '}' && chx != '{') ||
(ch == ']' && chx != '[') ||
(ch == ')' && chx != '(')) {
System.out.println("解析异常:" + ch + "在位置" +i);
}
}else{
System.out.println("解析异常:" + ch + "在位置" +i);
}
break;
default:
break;
}
}
if (!stack.isEmpty()){
System.out.println("字符串异常,遗失右分隔符");
}
System.out.println("解析正确");
}
}
栈是一种遵循后进先出(LIFO)原则的数据结构,常用于浏览器的回退和前进、字符反转及分隔符匹配等场景。顺序栈通常使用一维数组实现,链式栈则依赖链表。本文将探讨Java中这两种栈的实现方式。


被折叠的 条评论
为什么被折叠?



