栈Stack
1. 什么是栈
- 栈是一个先入后出的有序列表;
- 栈限制了元素的插入与删除只能在线性表的同一端进行(即栈顶Top),而另一端则为固定的一端(即栈底Bottom)。
2. 栈的常见应用场景
- 子程序调用
- 处理递归调用,ps:除了存地址还可以存参数和局部变量
- 表达式转换(中缀转后缀)与求值
- 二叉树遍历
- 图的深度优先搜索算法(DFS)
3. 数组模拟栈的思路与代码实现
3.1 思路分析
- 定义一个变量top表示栈顶,初始化为-1
- 当数据入栈时,top++,stack[top]=data
- 当数据出栈时,top--
3.2 代码实现
package com.datastructure;
import java.util.Scanner;
public class ArrayStackDemo {
public static void main(String[] args) {
ArrayStack arrayStack = new ArrayStack(5);
String key = " ";
boolean flag = true;
Scanner scanner = new Scanner(System.in);
while (flag) {
System.out.println("------------------------------------------");
System.out.println("测试数组模拟栈的使用说明:");
System.out.println("quit:退出程序");
System.out.println("push:向栈中插入数据");
System.out.println("pop:从栈顶取出数据");
System.out.println("ergodic:从栈顶遍历打印栈");
System.out.println("请输入你的选择:");
key = scanner.next();
switch (key) {
case "quit":
System.out.println("退出程序!");
flag = false;
scanner.close();
break;
case "ergodic":
arrayStack.ergodic();
break;
case "push":
System.out.println("请输入一个数:");
int data = scanner.nextInt();
arrayStack.push(data);
break;
case "pop":
try {
int result = arrayStack.pop();
System.out.println("当前出栈的栈顶数据是:"+result);
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
default:
break;
}
}
}
}
class ArrayStack {
private int MaxSize;
private int[] stack;
private int top = -1;
public ArrayStack(int maxSize) {
this.MaxSize = maxSize;
this.stack = new int[maxSize];
}
public boolean isEmpty() {
return top == -1;
}
public boolean isFull() {
return top == MaxSize -1;
}
public void push(int data) {
if (isFull()) {
System.out.println("栈满,无法入栈!");
return;
}
top++;
stack[top] = data;
}
public int pop() {
if (isEmpty()) {
throw new RuntimeException("栈空,无法出栈!");
}
int value = stack[top];
top--;
return value;
}
public void ergodic() {
if (isEmpty()) {
System.out.println("栈空!");
return;
}
for (int i = top; i >= 0 ; i--) {
System.out.println("stack["+i+"]="+stack[i]);
}
}
}
4. 栈实现综合计算器(中缀表达式)
4.1 思路:
- 创建一个index索引值,用于遍历表达式;
- 如果遍历到数字,就直接入数栈;
- 如果遍历到操作符,分如下情况讨论:
- 若符号栈为空,则直接入符号栈;
- 若符号栈不为空,则将当前符号与栈顶符号进行比较:
- 若当前operator的优先级大于栈顶的operator,则入栈;
- 若当前operator的优先级小于等于栈顶的operator,则从数栈中pop出两个数,并从符号栈中pop出一个运算符进行运算,将运算结果push进数栈,(
*注:此时需循环判断当前operator的优先级是否仍小于等于新的栈顶的优先级,若仍小于等于新的栈顶operator的优先级,重复执行上述步骤*
eg.3-2*6-2)最后将当前operator入符号栈;
- 表达式遍历完毕,顺序地从数栈和符号栈取出数和运算符进行运算;
- 最终数栈中只剩一个数,即为表达式的计算结果。
4.2 代码实现
package com.datastructure;
public class Calculator {
public static void main(String[] args) {
String expression = "12-2*2-2*3+1*3*2";
ArrayStack2 numStack = new ArrayStack2(10);
ArrayStack2 operStack = new ArrayStack2(10);
int index = 0;
int num1, num2, operator, res= 0;
char ch = ' ';
String keepNum = "";
while (index < expression.length()) {
ch = expression.substring(index, index+1).charAt(0);
if (operStack.isOperator(ch)) {
if (!operStack.isEmpty()) {
while (!operStack.isEmpty() && operStack.priority(ch) <= operStack.priority(operStack.peek())) {
num1 = numStack.pop();
num2 = numStack.pop();
operator = operStack.pop();
res = operStack.calculate(num1, num2, operator);
numStack.push(res);
}
operStack.push(ch);
}else {
operStack.push(ch);
}
}else {
keepNum += ch;
if (index == expression.length()-1) {
numStack.push(Integer.parseInt(keepNum));
}else {
if (operStack.isOperator(expression.substring(index+1, index+2).charAt(0))) {
numStack.push(Integer.parseInt(keepNum));
keepNum = "";
}
}
}
index++;
}
while (!operStack.isEmpty()) {
num1 = numStack.pop();
num2 = numStack.pop();
operator = operStack.pop();
res = operStack.calculate(num1, num2, operator);
numStack.push(res);
}
int result = numStack.pop();
System.out.println("表达式"+expression+"="+result);
}
}
class ArrayStack2 {
private int MaxSize;
private int[] stack;
private int top = -1;
public ArrayStack2(int maxSize) {
this.MaxSize = maxSize;
this.stack = new int[maxSize];
}
public boolean isEmpty() {
return top == -1;
}
public boolean isFull() {
return top == MaxSize - 1;
}
public void push(int data) {
if (isFull()) {
System.out.println("栈满,无法入栈!");
return;
}
top++;
stack[top] = data;
}
public int pop() {
if (isEmpty()) {
throw new RuntimeException("栈空,无法出栈!");
}
int value = stack[top];
top--;
return value;
}
public int peek() {
if (isEmpty()) {
throw new RuntimeException("栈空,无法显示栈顶元素!");
}
return stack[top];
}
public void ergodic() {
if (isEmpty()) {
System.out.println("栈空!");
return;
}
for (int i = top; i >= 0; i--) {
System.out.println("stack["+i+"]="+stack[i]);
}
}
public boolean isOperator(char c) {
return c == '+' || c == '-' || c == '*' || c == '/';
}
public int priority(int operator) {
if (operator == '*' || operator == '/') return 1;
else if (operator == '+' || operator == '-') return 0;
else return -1;
}
public int calculate(int num1, int num2, int operator) {
int res = 0;
switch (operator) {
case '+':
res = num1 + num2;
break;
case '-':
res = num2 - num1;
break;
case '*':
res = num1 * num2;
break;
case '/':
res = num2 / num1;
break;
default:
break;
}
return res;
}
}
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决