数据结构(java)——栈及其应用

来源:互联网 发布:加拿大 软件 研究生 编辑:程序博客网 时间:2024/05/20 21:21
   

1.  栈的简单介绍

      栈(Stack)是一种特殊的线性表,其插入和删除操作只允许在线性表的一端进行.允许操作的一端成为栈顶(Top),不允许操作的是另一端栈底(Bottom)。特点是后进先出,栈的基本操作有创建栈、判空、入栈、出栈和取栈顶元素。(下面用java实现栈的声明)

public interface Stack<T> {public abstract boolean isEmpty();public abstract void push(T x);//返回栈顶元素public abstract T peek();//出栈public abstract T pop();}

     根据栈采用的存储结构分别有顺序栈和链式栈,(在此注意栈和线性表示不同的抽象数据类型,栈的概念不依懒于线性表或链表而存在)。

 

2.  栈的应用

在实现嵌套调用和递归调用、实现非线性结构的深度遍算法、以非递归方式实现递归算法等系统设计中,栈都是必不可少的数据结构。下面有两个例子运用栈来实现。

(1)  括号匹配的语法检查,例如:((1+2*3+4))(

首先设置一个infix存放字符串,从左向右依次对infix中的每个字符ch进行语法检查。若是左括号,则 ch入栈;若ch是右括号,则出栈,若出栈字符为左括号,表示这一对括号匹配;如果栈空或出栈字符不是左括号,表示缺少与ch匹配的左括号。然后重复执行上述步骤,直到infix检查结束,若栈空则全部括号匹配;否则栈中仍有括号。

  实现代码如下:

package Stackitcast;/** * 括号匹配,((1+2)*3+4)( *  * @author Administrator *  */public class Bracket {public static String isMatched(String infix) {// 检查字符创infix表达式中圆括号是否匹配,是,返回空串;否,返回错误信息Stack<String> stack = new SeqStack<String>(infix.length());for (int i = 0; i < infix.length(); i++) {char ch = infix.charAt(i);switch (ch) {case '(':stack.push(ch + "");break;case ')':if (stack.isEmpty() || !stack.pop().equals("("))return "期望(";}}return (stack.isEmpty()) ? "" : "期望)";}public static void main(String[] args) {String infix = "((1+2)*3+4))(";System.out.println(infix + "  ,编译错误:" + Bracket.isMatched(infix));}}

(2)  使用栈计算算术表达式值

第一步:将中缀表达式转换为后缀表达式

 

第二步:后缀表达式求值,下图为栈的操作过程


具体实现代码如下:

package Stackitcast;/** * 利用顺序栈和链式栈分别存储符号字符串和数字,对中缀表达式进行计算 *  * @author Administrator *  */public class Expression {/** * 将中缀表达式转换为后缀表达式的过程 *  * @param infix * @return */public static StringBuffer toPostfix(String infix) {// 运算符栈,顺序栈Stack<String> stack = new SeqStack<String>(infix.length());// 后缀表达式字符串StringBuffer postfix = new StringBuffer(infix.length() * 2);int i = 0;while (i < infix.length()) {char ch = infix.charAt(i);switch (ch) {case '+':case '-':while (!stack.isEmpty() && !stack.peek().equals("("))postfix.append(stack.pop());// 当前运算符入栈stack.push(ch + "");i++;break;case '*':case '/':while (!stack.isEmpty()&& (stack.peek().equals("*") || stack.peek().equals("/")))postfix.append(stack.pop());stack.push(ch + "");i++;break;case '(':stack.push(ch + "");i++;break;case ')':// 遇到右括号出栈String out = stack.pop();while (out != null && !out.equals("(")) {postfix.append(out);out = stack.pop();}i++;break;default:while (i < infix.length() && ch >= '0' && ch <= '9') {postfix.append(ch);i++;if (i < infix.length())ch = infix.charAt(i);}postfix.append(" ");}}while (!stack.isEmpty()) {postfix.append(stack.pop());}return postfix;}/** * 后缀表达式求值过程 */public static int toValue(StringBuffer postfix){Stack<Integer> stack = new LinkedStack<Integer>();int value=0;for(int i=0;i<postfix.length();i++){char ch = postfix.charAt(i);//不太懂、、、、、if(ch>='0'&&ch<='9'){value =0;while(ch!=' '){//将整数字符串转换成整数值value=value*10+ch-'0';ch=postfix.charAt(++i);}stack.push(value);}elseif(ch!=' '){int y=stack.pop(), x=stack.pop();switch(ch){case '+':value=x+y; break;case '-':value=x-y; break;case '*':value=x*y; break;case '/':value=x/y; break;}//去掉(ch+"")直接就是x+y的结果了System.out.print(x+(ch+"")+y+"="+value+", ");stack.push(value);}}//这时候栈里就剩一个结果值return stack.pop();}public static void main(String[] args) {String infix="123+10*(45-50+20)/((35-25)*2+10)-11";StringBuffer postfix=toPostfix(infix);System.out.println("infix="+infix);System.out.println("postfix="+postfix);System.out.println("\nvalue="+toValue(postfix));}}
由于两种栈的数据类型不一样,这里分别使用了顺序栈和链式栈实现。欢迎指正!


1 0
原创粉丝点击