数据结构中的栈
PS:出栈(POP) 入栈(PUSH)
实现栈的思路:
1.使用数组来模拟栈
2.定义一个top来表示栈顶,初始化为-1
3.入栈的操作: 当有数据加入时 top++ stack[top]=data
4.出栈的操作: int value=stack[top];top–;retrurn value;
代码实现
package demo1;
import java.util.Scanner;
import javax.management.RuntimeErrorException;
public class StackDemo {
public static void main(String[] args) {
//测试
//创建一个对象
Stack stack=new Stack(4);
boolean loop=true;
String key ="";
Scanner scanner=new Scanner(System.in);
while(loop) {
System.out.println("1:显示数据");
System.out.println("2:添加数据");
System.out.println("3:删除栈顶数据");
System.out.println("4:退出菜单");
System.out.println("请输入你的操作编号:");
key=scanner.next();
switch (key) {
case "1":
stack.list();
break;
case "2":
System.out.println("请输入你要添加的数据:");
int value=scanner.nextInt();
stack.push(value);
break;
case "3":
try {
int res=stack.pop();
System.out.println("栈顶数据已成功被删除,值为"+res);
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case "4":
scanner.close();
loop=false;
break;
}
}
System.out.println("退出程序成功!");
}
}
class Stack{
private int maxsize;//数组最大长度
private int top=-1;//栈顶top
private int[] data;
//构造器
public Stack(int maxsize) {
this.maxsize=maxsize;
data=new int[this.maxsize];
}
//判断是否已满
public boolean isFull() {
return top==maxsize-1;
}
//判断栈是否为空
public boolean isEmpty() {
return top==-1;
}
//入栈
public void push(int value) {
//判断是否栈满
if(isFull()){
System.out.println("栈满,无法在添加数据");
}
top++;
data[top]=value;
}
//出栈
public int pop() {
if(isEmpty()) {
//抛出异常
throw new RuntimeException("栈空,无数据");
}
int value=data[top];
top--;
return value;
}
//遍历
public void list() {
if(isEmpty()) {
System.out.println("栈空,没有数据");
}
//离栈要从栈顶离开
for(int i=top;i>=0;i--) {
System.out.println("当前栈顶数据是:"+data[top]);
}
}
}
题目:栈实现综合计算器
package demo1;
public class Calculator {
public static void main(String[] args) {
String expression = "7*2*2-5+1-5+3-4";
//创建了两个栈,一个数栈 一个符号栈
Stack2 numStack=new Stack2(10);
Stack2 operStack=new Stack2(10);
//定义相关变量
int num1=0;
int num2=0;
int oper=0;
int res=0;
int index=0;//用于扫描
char ch=' ';//将每次扫到的char保存在ch中
String keepNum="";//用来拼接多位数
//开始用while循环的扫描语句 扫描expression
while(true) {
//一次得到expression的每一个字符
ch=expression.substring(index,index+1).charAt(0);
//判断是否是数字和符号 做相应的处理
if(operStack.isOper(ch)) {
//如果是运算符
//判断当前符号栈是否为空
if(!operStack.isEmpty()) {
// 如果符号栈有操作符 就进行比较 如果当前的操作符的优先级小于等于栈中的操作符,就需要从数栈中pop出两个数
// 再从符号栈中pop出一个符号 ,进行运算,将得到的结果,入数栈 然后将 当前的操作符入符号栈
if(operStack.priority(oper)<=operStack.priority(operStack.peek())) {
num1=numStack.pop();
num2=numStack.pop();
oper=operStack.pop();
res=numStack.cal(num1, num2, oper);
//把计算的结果入数栈
numStack.push(res);
//把当前的操作符入符号栈
operStack.push(ch);
}else {
//如果当前的符号符优先级大于栈中的操作符,就直接入符号栈
operStack.push(ch);
}
}
else {
operStack.push(ch);
}
}
else {
// 如果是数字 则直接入数栈 注意这是字符 不是真正的数字
// numStack.push(ch - 48);在ASCII字符表中,字符号与真正的数字相差为48 如数字1在ASCII表中是49
//这样其实有问题,因为13+1=》'1''3'+'1'
// 在处理多位数时, 不能发现是一个数就立即入栈 因为他可能是多位数
// 在处理数,需要向expression的表达式的index 后再看一位 , 如果是数 就进行扫描, 如果是符号才入栈
// 因此我们需要定义一个变量 keepNum字符串 ,用于拼接多位数
//处理多位数时
keepNum+=ch;
//如果ch是expression最后一位,直接入栈
if(index==expression.length()-1) {
numStack.push(ch-48);
}else {
//判断下一个字符 是不是字符 继续扫描 如果是运算符 则入栈
//只看后一位 不是index++
if(operStack.isOper(expression.substring(index+1,index+2).charAt(0))) {
//如果后一位是运算符 则数字入栈
numStack.push(Integer.parseInt(keepNum));
//清空keepNum
keepNum="";
}
}
}
index++;
if(index>=expression.length()) {
break;
}
}
while(true) {
//当表达式扫描完毕 就顺序的从数栈和符号栈中pop出相应的数和符号 并运行
if(operStack.isEmpty()) {
break;
}
num1=numStack.pop();
num2=numStack.pop();
oper=operStack.pop();
res=numStack.cal(num1, num2, oper);
numStack.push(res);
}
System.out.println(expression+"="+res);
}
}
//先创建一个栈
class Stack2{
private int maxsize;//数组最大长度
private int top=-1;//栈顶top
private int[] data;
//构造器
public Stack2(int maxsize) {
this.maxsize=maxsize;
data=new int[this.maxsize];
}
//查看当前的栈顶,不是pop
public int peek() {
if(top==-1) {
System.out.println("为空栈");
return -1;
}
return data[top];
}
//判断是否已满
public boolean isFull() {
return top==maxsize-1;
}
//判断栈是否为空
public boolean isEmpty() {
return top==-1;
}
//入栈
public void push(int value) {
//判断是否栈满
if(isFull()){
System.out.println("栈满,无法在添加数据");
}
top++;
data[top]=value;
}
//出栈
public int pop() {
if(isEmpty()) {
//抛出异常
throw new RuntimeException("栈空,无数据");
}
int value=data[top];
top--;
return value;
}
//遍历
public void list() {
if(isEmpty()) {
System.out.println("栈空,没有数据");
}
//离栈要从栈顶离开
for(int i=top;i>=0;i--) {
System.out.println("当前栈顶数据是:"+data[top]);
}
}
//返回运算符的优先级,由程序员来确定,优先级用数字来表示
//数字越大,优先级越高
public int priority(int oper) {
if(oper=='*' || oper=='/') {
return 1;
}else if(oper=='+' || oper=='-') {
return 0;
}else{
return -1;//假定目前表达式只有:*、-、/、+
}
}
//判断是不是一个运算符
public boolean isOper(char val) {
return val=='+' || val=='-' || val=='*' || val=='/';
}
//计算方法
public int cal(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;
}
}