栈
栈(stack) 是一种先入后出的线性结构
应用:子程序的调用/递归调用/表达式求值(中缀表达式转后缀表达式)/二叉树遍历/图的DFS
使用数组来模拟栈
初始化:top = -1
入栈:top++,stack[top] = data
出栈: int value = stack[top], top–,return value
package com.like.java.data_structure.stack;
// 表示栈结构
public class ArrayStack {
// 栈的大小
private int maxSize;
private int[] stack;
private int top = -1;
public ArrayStack(int maxSize)
{
this.maxSize = maxSize;
stack = new int[this.maxSize];
}
public boolean isFull()
{
return top == (maxSize-1);
}
public boolean isEmpty()
{
return top == -1;
}
public void push(int val)
{
if(isFull())
{
System.err.println("Full");
return;
}
stack[++top] = val;
}
public int pop()
{
if(isEmpty())
{
throw new RuntimeException("Empty Stack,No data");
}
return stack[top--];
}
public void show()
{
if(isEmpty())
{
throw new RuntimeException("Empty Stack,No data");
}
for(int i=top;i>=0;i--)
{
System.out.println("stack["+i+"]="+stack[i]);
}
}
}
使用链表来模拟栈
package com.like.java.data_structure.stack;
import com.like.java.data_structure.linkedList.Boy;
public class LinkedStack {
private Boy bottom = new Boy(-1);
private Boy top = bottom;
public boolean isEmpty()
{
return bottom == top;
}
public void push(Boy boy)
{
boy.next = top;
top = boy;
}
public Boy pop()
{
if(isEmpty())
{
System.err.println("Empty Stack");
return null;
}
Boy curBoy = top;
top = top.next;
return curBoy;
}
public void show()
{
Boy temp = top;
while(temp != bottom)
{
System.out.println(temp);
temp = temp.next;
}
}
}
使用栈实现综合计算器
对于一个中缀表达式形如722-5+1+5+3-4,使用栈来计算综合的结果
思想:1. 通过一个index值来遍历表达式
2. 如果是一个数字,直接加入到数栈中
3. 如果是运算符,分为两种情况
- 3.1 若符号栈为空,直接入栈
- 3.2 若符号栈不为空,比较当前操作符和栈中操作符进行比较
当前运算符小或等于栈中,就从数栈中pop出两个数,从符号栈中pop出一个,运算出结果入数栈,然后将当前操作符如符号栈(Note 后面弹出的数 操作符 前面弹出的数)
当前运算符优先级大于栈中的操作符,直接入符号栈
4. 当表达式扫描完毕后,就顺序地从数栈和符号栈中pop出相应的数和符号栈就行运算,最后数栈中只有一个数值即运算结果
package com.like.java.data_structure.stack;
// 用于综合计算器
public class ArrayStack2 {
// 栈的大小
private int maxSize;
private int[] stack;
private int top = -1;
public ArrayStack2(int maxSize)
{
this.maxSize = maxSize;
stack = new int[this.maxSize];
}
public boolean isFull()
{
return top == (maxSize-1);
}
public boolean isEmpty()
{
return top == -1;
}
public void push(int val)
{
if(isFull())
{
System.err.println("Full");
return;
}
stack[++top] = val;
}
public int pop()
{
if(isEmpty())
{
throw new RuntimeException("Empty Stack,No data");
}
return stack[top--];
}
public void show()
{
if(isEmpty())
{
throw new RuntimeException("Empty Stack,No data");
}
for(int i=top;i>=0;i--)
{
System.out.println("stack["+i+"]="+stack[i]);
}
}
// 增加优先级判断功能
// 优先级使用数字表示,数字越大,优先级越大
public int priority(int oper)
{
if(oper == '*' || oper == '/')
{
return 1;
}
else if(oper == '+' || oper == '-')
{
return 0;
}else {
return -1;
}
}
// 判断是不是运算符
public boolean isOper(int oper)
{
return oper == '+' || oper == '-' || oper == '*' || oper == '/';
}
// 计算方法
public int calc(int num1, int num2, int oper)
{
int res = 0;
switch(oper)
{
case '+':
res = num1 + num2;
break;
case '-':
res = num2 - num1;
break;
case '*':
res = num1*num2;
break;
case '/':
res = num2/num1;
break;
}
return res;
}
// peek
public int peek()
{
return stack[top];
}
}
package com.like.java.data_structure.stack;
public class Calculator {
public static void main(String[] args) {
String expression = "3+2*6-2*9";
ArrayStack2 numStack2 = new ArrayStack2(10);
ArrayStack2 operStack2 = new ArrayStack2(10);
int index = 0; // 扫描
int num1 = 0,num2 = 0;
int res = 0;
int oper = 0;
char ch = ' ';
// 扫描入栈
while(index < expression.length())
{
ch = expression.charAt(index++);
if(operStack2.isOper(ch))
{
if(!operStack2.isEmpty())
{
if(operStack2.priority(ch) <= operStack2.priority(operStack2.peek()))
{
num1 = numStack2.pop();
num2 = numStack2.pop();
oper = operStack2.pop();
res = operStack2.calc(num1, num2, oper);
numStack2.push(res);
// 当前操作符入符号栈
operStack2.push(ch);
}else {
operStack2.push(ch);
}
}
else {
operStack2.push(ch);
}
}else {
numStack2.push(ch-48);
}
}
// 扫描完毕运算到符号栈为空
while(!operStack2.isEmpty())
{
num1 = numStack2.pop();
num2 = numStack2.pop();
oper = operStack2.pop();
res = operStack2.calc(num1, num2, oper);
numStack2.push(res);
}
System.out.printf("%s=%d",expression,numStack2.pop());
}
}
Java.util.Stack示例
package com.like.java.data_structure.stack;
import java.util.Stack;
public class StackTester {
public static void main(String[] args) {
Stack<String> stack = new Stack<String>();
// 入栈
stack.setSize(3);
stack.add("Jack");
stack.add("Tom");
stack.add("Alice");
String isPush = stack.push("Like");
boolean isAdd = stack.add("Smith");
System.out.println(isPush);
System.out.println(isAdd);
// 出栈
System.out.println(stack.pop());
// 查看栈顶元素
System.out.println(stack.peek());
//查看栈大小
System.out.println(stack.size());
}
}