数学表达式与二叉树

表达式:a*(b+c/d)+c*h-g*f表示如下的树。

 

View Code
package com.jstrd.base.commons.util;

import java.util.ArrayList;
import java.util.Stack;

import com.jstrd.util.StringUtil;

public  class Test {

     public  static  void main(String[] args) {
        String s = "3+abs(5+1*2)";
         // 为了生成波兰表达式,对单目运算符先做转换处理,例将abs(a+b)替换成(abs:a+b),其中冒号“:”做为一种特殊的双目运算符
         for ( int i = 0; i < unaryOperator.length; i++) {
            s = s.replaceAll(unaryOperator[i] + "\\(", "\\(" + unaryOperator[i] + "\\:");
        }
        TNode tree = ( new Test()).parseAF2Tree(s);
        ( new BinaryTree()).printTree(tree, 0);
        System.out.println("");
    }
     private  final  static String[] unaryOperator = {"abs", "sqrt"};
     private  final  static String[] binaryOperator = {":", "+", "-", "*", "/", "(", ")"};

     /**
     * 将一个数学算式转化为一个树
     * 
     * 
@param  s
     *            此算式的字符串
     
*/
     public TNode parseAF2Tree(String s) {
        Stack<String> sta =  new Stack<String>();
        sta.push("#");
//         char[] ch = new char[s.length() + 1];
        ArrayList<String> ch =  new ArrayList<String>();
//         int j = 0;
        
//  将中序表达式转化为逆波兰表达式
        String character = "";
         for ( int i = 0; i < s.length(); i++) {
             char cha = s.charAt(i);
             if (!StringUtil.exists(String.valueOf(cha), binaryOperator)) {
                character += String.valueOf(cha);
                 if ((i + 1) < s.length() && !StringUtil.exists(String.valueOf(s.charAt(i+1)), binaryOperator)) {
                     continue;
                }  else {
                    ch.add(character);
                    character = "";
                }
//                 ch[j++] = cha;
            }  else  if (cha == '(') {
                sta.push(String.valueOf(cha));
            }  else  if (cha == ')') {
                String c = sta.pop();
                 while (!c.equals("(")) {
//                     ch[j++] = c;
                    ch.add(c);
                    c = sta.pop();
                }
            }  else {
                String c = sta.peek();
                 while (c.equals("*") || c.equals("/")) {
                     // ch[j++] = sta.pop();
                    ch.add(sta.pop());
                    c = sta.peek();
                }
                sta.push(String.valueOf(cha));
            }
        }
        String c = sta.pop();
         while (!c.equals("#")) {
//             ch[j++] = c;
            ch.add(c);
            c = sta.pop();
        }
         //  将逆波兰转化为波兰表达式
        Object[] chArr = ch.toArray();
         int j = chArr.length;
        String[] temp =  new String[j + 1];
         for ( int i = 0; i < j; i++) {
            temp[j - i - 1] = chArr[i].toString();
        }
        temp[j] = "#";
         //  由波兰表达式建树
        TNode root = creatAFTree(temp);
         return root;
    }

     /**
     * 将波兰表达式建成一棵树
     * 
     * 
@param  ch
     * 
@param  key
     * 
@return
     
*/
     public TNode creatAFTree(String[] ch) {
        TNode current =  null;
         if (!ch[key].equals("#")) {
             if (StringUtil.exists(ch[key], binaryOperator)) {
                current =  new TNode(ch[key++]);
                TNode temp = creatAFTree(ch);
                 if (temp ==  null) {
                }  else {
                    current.setRight(temp);
                    temp.setParent(current);
                }
                TNode temp2 = creatAFTree(ch);
                 if (temp2 ==  null) {
                }  else {
                    current.setLeft(temp2);
                    temp2.setParent(current);
                }
                 return current;
            }  else {
                current =  new TNode(ch[key++]);
                 return current;
            }
        }  else {
             return  null;
        }
    }

     private  int key = 0;
}

class TNode {

     // 1常量,2变量,3运算函数,4双目运算符,5单目运算符
     private  int nodeType; 
     private Object obj;
     private TNode parent;
     private TNode left;
     private TNode right;
    
     public  int getNodeType() {
         return nodeType;
    }

     public  void setNodeType( int nodeType) {
         this.nodeType = nodeType;
    }

     public TNode(Object obj) {
         this.obj = obj;
    }

     public TNode() {
    }

     public Object getObj() {
         return obj;
    }

     public  void setObj(Object obj) {
         this.obj = obj;
    }

     public TNode getParent() {
         return parent;
    }

     public  void setParent(TNode parent) {
         this.parent = parent;
    }

     public TNode getLeft() {
         return left;
    }

     public  void setLeft(TNode left) {
         this.left = left;
    }

     public TNode getRight() {
         return right;
    }

     public  void setRight(TNode right) {
         this.right = right;
    }
}

class BinaryTree {

     private  static TNode root;

     public BinaryTree() {

    }

     /**
     * 重写二叉树的构造方法
     * 
     * 
@param  obj
     
*/
     public BinaryTree(Object obj) {
        root =  new TNode(obj);
    }

     /**
     * 将整型数组转化为一棵二叉查找树
     * 
     * 
@param  Array
     *            待转化的数组
     
*/
     public  void ArraytoTree( int[] Array) {
         if (Array.length == 0) {
             throw  new RuntimeException("数组长度为0,没有元素用来建树!");
        }
         int first = Array[0];
        root =  new TNode(first);
         for ( int i = 1; i < Array.length; i++) {
            addofBST(root, Array[i]);
        }
    }

     /**
     * 将一个数以二叉查找树的顺序插入树中
     * 
     * 
@param  node
     * 
@param  value
     
*/
     public  void addofBST(TNode node,  int value) {
        TNode current;
         if ((Integer) node.getObj() >= value) {
             if (node.getLeft() !=  null) {
                current = node.getLeft();
                addofBST(current, value);
            }  else {
                current =  new TNode(value);
                current.setParent(node);
                node.setLeft(current);
            }
        }  else {
             if (node.getRight() !=  null) {
                current = node.getRight();
                addofBST(current, value);
            }  else {
                current =  new TNode(value);
                current.setParent(node);
                node.setRight(current);
            }
        }
    }

     /**
     * 以选定模式遍历打印二叉树
     * 
     * 
@param  node
     *            二叉树起始结点
     * 
@param  style
     *            模式,1为中左右,0为左中右,-1为左右中
     
*/
     public  void printTree(TNode node,  int style) {
         if (node !=  null) {
             if (style == 1) {
                 //  打印此结点
                Object obj = node.getObj();
                System.out.println(obj);
                 //  得到它的左子结点,并递归
                TNode left = node.getLeft();
                printTree(left, style);
                 //  得到它的右子结点,并递归
                TNode right = node.getRight();
                printTree(right, style);
            }  else  if (style == 0) {
                Object obj = node.getObj();
                 //  得到它的左子结点,并递归
                TNode left = node.getLeft();
                 if ( null != left
                        &&  null != node.getParent()
                        &&  this.getOperatorLevel(obj.toString()) <  this
                                .getOperatorLevel(node.getParent().getObj()
                                        .toString()))
                    System.out.print("(");
                printTree(left, style);
                 //  打印此结点
                System.out.print(obj);
                 //  得到它的右子结点,并递归
                TNode right = node.getRight();
                printTree(right, style);
                 if ( null != right
                        &&  null != node.getParent()
                        &&  this.getOperatorLevel(obj.toString()) <  this
                                .getOperatorLevel(node.getParent().getObj()
                                        .toString()))
                    System.out.print(")");
            }  else  if (style == -1) {
                 //  得到它的左子结点,并递归
                TNode left = node.getLeft();
                printTree(left, style);
                 //  得到它的右子结点,并递归
                TNode right = node.getRight();
                printTree(right, style);
                 //  打印此结点
                Object obj = node.getObj();
                System.out.println(obj);
            }
        }
    }

     private  int getOperatorLevel(String operator) {
         if (StringUtil.exists(operator,  new String[] { "+", "-" })) {
             return 1;
        }
         if (StringUtil.exists(operator,  new String[] { "*", "/" })) {
             return 2;
        }
         return 0;
    }

}

 

 

 

 

 

 

 

你可能感兴趣的:(数学表达式与二叉树)