您的位置:首页 > 编程语言 > Java开发

java 二叉树(十一)表达式与逆波兰序列

2016-07-09 11:35 363 查看
后缀表达式(逆波兰式):将运算符写在操作数之后。

算法实现:

1.准备两个空栈:S1,用来存放运算符;S2用来存放操作数和接收S1弹出的
运算符,最后得到的栈S2就是后缀表达式的逆向序列。

2.从左至右解析表达式的操作数,运算符,和左右括号。

3.当解析出一个操作数时,把操作数压入S2栈顶。

4.当解析出运算符时,将该运算符与S1栈顶的运算符进行比较,若当前运算符 的优先级大于栈顶的优先级,则将该运算符压入S1的栈顶;若当前运算符 的优先级小于S1栈顶的优先级时,把S1栈顶的运算符弹出压入S2,直到
S1栈顶运算符的优先级不在大于当前运算符的优先级为止,然后把当前运算 符压入S1栈顶。

5.若遇到左括号‘(’,直接压入S1栈顶。

6.若遇到右括号‘)’,则把S1栈顶的运算符弹出,压入S2栈顶,直到S1弹
出过程中遇到第一个左括号‘(’为止,并把此时S1栈顶的左括号‘(’, 舍弃(弹出)。

7.重复2-6步,直到把表达式处理完

8.若此时S1站内还有运算符,则把S1全部弹出压入S2即可。

9.此时得到的S2的从栈低到栈顶的顺序为逆波兰式,若要使用把S2做一下你 需处理即可。

用到的数据结构:

栈,链表,还有一个String转double类型的方法。

链表的创建:

package 二叉树结算器;

public class LinkList{
public Node head;
public Node tail;
//头插
public void addOpre(char opre){
Node node = new Node(opre);

if(head==null){
head=node;
head.setFront(null);
tail=node;
tail.setNext(null);
}else{
head.setFront(node);
node.setNext(head);
head=node;
head.setFront(null);
}
}
public void addSum(double num){
Node node = new Node(num);
if(head==null){
head=node;
head.setFront(null);
tail=node;
tail.setNext(null);
}else{
head.setFront(node);
node.setNext(head);
head=node;
head.setFront(null);
}
}
public void addStr(String str){
Node node = new Node(str);
if(head==null){
head=node;
head.setFront(null);
tail=node;
tail.setNext(null);
}else{
head.setFront(node);
node.setNext(head);
head=node;
head.setFront(null);
}
}
//删除,每次删除头节点
public char delHeadOpre(){
Node temp;
if(head.getNext()!=null){
temp=head;
head=head.getNext();
head.setFront(null);
return temp.opre;
}else{
return head.opre;
}
}
public double delHeadNum(){
Node temp;
if(head.getNext()!=null){
temp=head;
head=head.getNext();
head.setFront(null);

return temp.num;
}else{
return head.num;
}
}
public String delStr(){
Node temp ;
if(head.getNext()!=null){
temp=head;
head=head.getNext();
head.setFront(null);
return temp.str;
}else{
return head.str;
}
}
public String del_Num(){
Node temp;
if(head.getNext()!=null){
temp=head;
head=head.getNext();
head.setFront(null);
if(temp.num==0){
return String.valueOf(temp.opre);
}
return	String.valueOf(temp.num);
}else{
if(head.num==0){
return String.valueOf(head.opre);
}
return	String.valueOf(head.num);
}
}

public void print(){
Node node=head;
while(node!=null){
if(node.num==0){
System.out.println(node.opre);
}else{
System.out.println(node.num);
}
node=node.getNext();
}
}
public void str_print(){
Node node=head;
while(node!=null){{
System.out.println(node.str);
node=node.getNext();
}

}
}

class Node{
public char opre;
public double num;
public String str;
public Node1 node;
public Node front;
public Node next;
public Node(char opre){
this.opre=opre;
}
public Node(double num){
this.num=num;
}
public Node(String str){
this.str=str;
}
public Node(){

}
public void setOpre(char opre){
this.opre=opre;
}
public char getOpre(){
return opre;
}
public void setNum(double num){
this.num=num;
}
public double getNum(){
return num;
}
public void setFront(Node front){
this.front=front;
}
public Node getFront(){
return front;
}
public void setNext(Node next){
this.next=next;
}
public Node getNext(){
return next;
}
public void setStr(String str){
this.str=str;
}
public String getStr(){
return str;
}
}
}


栈的创建:
package 二叉树结算器;

public class Stack {
public LinkList ll=new LinkList();
public int top;
public Stack(){
top=-1;
}
public boolean isEmpty(){
if(top==-1){
return true;
}
return false;
}
public void push(double value){
ll.addSum(value);
top++;
}
public void push(char c){
ll.addOpre(c);
top++;
}
public double popNum(){
top--;
return ll.delHeadNum();

}
public char popOpre(){
top--;
return ll.delHeadOpre();
}
public void print(){
ll.print();
}
public void str_print(){
ll.str_print();
}
public void push(String str){
ll.addStr(str);
top++;
}
public String pop(){
top--;
return ll.del_Num();
}
}


逆波兰算法的实现(RPN):
package 二叉树结算器;

//import java.util.Scanner;

//逆波兰算法(后缀表达式)
public class RPN {
public Stack rpn(String str){
//public static void main(String args[]){
Stack opre = new Stack();
Stack num = new Stack();
Stack nst = new Stack();
//		System.out.println("请输入表达式:");
//		Scanner scan = new Scanner(System.in);
//		String str=scan.nextLine();
String s="";
String st="";
char c;
//(1+2)*3-(1+2)/4
opre.push('#');
for(int i=0;i<str.length();i++){
if(i==10){
int aaa=0;
System.out.println(aaa);
}
c=str.charAt(i);
s=String.valueOf(c);
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'){
if(st!=""){
num.push(string_double(st));
st="";
}
if(opre.ll.head !=null){
if(c!='('&&c!=')'){
if((c=='*'||c=='/')&&(opre.ll.head.opre=='+'||opre.ll.head.opre=='-')){
opre.push(c);
continue;
}
if((c=='+'||c=='-')&&(opre.ll.head.opre=='*'||opre.ll.head.opre=='/')){
while(true){
num.push(opre.popOpre());
if(opre.ll.head.opre!='*'||opre.ll.head.opre!='/'){
//opre.push(c);
break;
}
}
}
}
if(c=='('||c==')'){
if(c=='('){
opre.push(c);
continue;
}
if(c==')'){
boolean asd = true;
while(asd==true){
num.push(opre.popOpre());
if(opre.ll.head.opre=='('){
opre.popOpre();
asd=false;
//break;
}
}
continue;
}
}
}
opre.push(c);
continue;
}
st+=s;
if(i==str.length()-1){
if(st!=""){
num.push(string_double(st));
st="";
}
//boolean aa=true;
while(true){
if(opre.ll.head.opre!='#'){
num.push(opre.popOpre());
}else{
break;
}
}
}
}
num.print();
System.out.println("----------------");
int m=-1;
while(m<num.top){
nst.push(num.ll.del_Num());
m++;
}

nst.str_print();
return nst;

//scan.close();
}
public static double string_double(String str){
double sum=0;
double aa=0;
double aaa=0;
int a=0;
boolean asd = true;
for(int i=0;i<str.length();i++){
if(str.charAt(i)=='.'){
asd=false;
continue;
}
if(asd == true){
aa=aa*10+(double)(str.charAt(i)-'0');
}else{
aaa = aaa*10+(double)(str.charAt(i)-'0');
a++;
}
}
for(int j=0;j<a;j++){
aaa=aaa/10;
}
sum=aaa+aa;
return sum;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息