数据结构(java)——栈及其应用
2016-04-13 16:28
495 查看
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); }else if(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)); } }由于两种栈的数据类型不一样,这里分别使用了顺序栈和链式栈实现。欢迎指正!
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树