您的位置:首页 > 理论基础 > 数据结构算法

数据结构(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