java 算数表达式 转成 二叉树_[Java]算术表达式组建二叉树,再由二叉树得到算式的后序和中序表达式...

packagecom.hy;importjava.util.List;//以算术表达式为基础构建一棵二叉树,它是算术表达式的语法树

public classTree {//根节点

privateNode root;//infixList为分词完毕的中序表达式列表

public Tree(ListinfixList){

root=build(infixList,0,infixList.size());

}//构建一棵树,从根节点构建起

private Node build(List list,int start,intend){int depth=0;//记录深度,进一层括号加一,退出来减一

int plusDivideRightmostPos=-1;//记录最右边的加减号位置

int multiDivideRightmostPos=-1;//记录最右边的乘除号位置//操作数

if(start==end-1){//下标相差一,说明找到的是没有子节点的叶子节点,也即操作数节点

Node leafNode=newNode(NodeType.Digit,list.get(start));returnleafNode;

}//这个循环是为了找括号外最右边的运算符位置

for(int i=start;i

String operatorText=list.get(i);//获得操作符的文字,如果是操作数直接ignore

if(operatorText.equals("(")){

depth++;

}else if(operatorText.equals(")")){

depth--;

}else if(operatorText.equals("+") || operatorText.equals("-") ){if(depth==0){

plusDivideRightmostPos=i;

}

}else if(operatorText.equals("*") || operatorText.equals("/") ){if(depth==0){

multiDivideRightmostPos=i;

}

}

}int rightMost=-1;if(plusDivideRightmostPos==-1 && multiDivideRightmostPos==-1){//整个算式被多余的括号括起来了,去掉这层多余的括号再做

return build(list,start+1,end-1);

}//优先取加减号的位置,因为它的计算优先级最低,应当最后算

rightMost=plusDivideRightmostPos;if(plusDivideRightmostPos==-1 && multiDivideRightmostPos>0){//括号外只有乘除号,如(1+2)*(3+4),这时只有取乘除号位置,

rightMost=multiDivideRightmostPos;

}//如果能走到这里,则最右边括号外的运算符位置已经找到了,可以开始构建节点

String operator=list.get(rightMost);

Node nodeOper=new Node(operator);//这里创建的节点都是操作符节点,不是最终的叶子节点//以最右边的操作符为界,分两侧构建左右子节点

nodeOper.setLeftNode(build(list,start,rightMost));

nodeOper.setRightNode(build(list,rightMost+1,end));//返回构建完的节点

returnnodeOper;

}//取二叉树的值

public float evaluate() throwsException{return this.root.getValue();

}//后序遍历

privateString postOrder(Node node){if(node!=null){

String s="";

s+=postOrder(node.getLeftNode());

s+=postOrder(node.getRightNode());

s+=node.toString();returns;

}return "";

}//从构建好的二叉树获得后序表达式

publicString getPostfix(){returnpostOrder(root);

}//中序遍历

privateString inOrder(Node node){if(node!=null){

String s="";if(node.getType().equals(NodeType.OP_Plus) ||node.getType().equals(NodeType.OP_Minus)){

s+="(";

}

s+=inOrder(node.getLeftNode());

s+=node.toString();

s+=inOrder(node.getRightNode());if(node.getType().equals(NodeType.OP_Plus) ||node.getType().equals(NodeType.OP_Minus)){

s+=")";

}returns;

}return "";

}//从构建好的二叉树获得中序表达式

publicString getInfix(){

String s="";

s=inOrder(root);if(s.startsWith("(") && s.endsWith(")") && (root.getType()==NodeType.OP_Minus || root.getType()==NodeType.OP_Plus) ){return s.substring(1, s.length()-1);

}else{returns;

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是通过二叉链表遍历将算术表达式换为二叉树并求值的 C 语言代码,包含注释说明: ```c #include <stdio.h> #include <stdlib.h> // 定义二叉树节点结构体 typedef struct TreeNode { char data; // 节点数据 struct TreeNode *left; // 左子节点 struct TreeNode *right; // 右子节点 } TreeNode; // 定义栈结构体 typedef struct Stack { TreeNode **items; // 存储节点指针的数组 int top; // 栈顶指针 int size; // 栈的最大容量 } Stack; // 创建一个新的栈 Stack *createStack(int size) { Stack *stack = (Stack *) malloc(sizeof(Stack)); stack->items = (TreeNode **) malloc(size * sizeof(TreeNode *)); stack->size = size; stack->top = -1; return stack; } // 判断栈是否为空 int isEmpty(Stack *stack) { return stack->top == -1; } // 判断栈是否已满 int isFull(Stack *stack) { return stack->top == stack->size - 1; } // 入栈操作 void push(Stack *stack, TreeNode *item) { if (isFull(stack)) { printf("Error: Stack is full\n"); return; } stack->items[++stack->top] = item; } // 出栈操作 TreeNode *pop(Stack *stack) { if (isEmpty(stack)) { printf("Error: Stack is empty\n"); return NULL; } return stack->items[stack->top--]; } // 获取栈顶元素 TreeNode *peek(Stack *stack) { if (isEmpty(stack)) { printf("Error: Stack is empty\n"); return NULL; } return stack->items[stack->top]; } // 判断一个字符是否是操作符 int isOperator(char c) { return c == '+' || c == '-' || c == '*' || c == '/'; } // 通过二叉链表遍历将算术表达式换为二叉树 TreeNode *constructTree(char postfix[]) { int i = 0; Stack *stack = createStack(strlen(postfix)); while (postfix[i] != '\0') { char c = postfix[i]; if (isOperator(c)) { TreeNode *node = (TreeNode *) malloc(sizeof(TreeNode)); node->data = c; node->right = pop(stack); node->left = pop(stack); push(stack, node); } else { TreeNode *node = (TreeNode *) malloc(sizeof(TreeNode)); node->data = c; node->left = NULL; node->right = NULL; push(stack, node); } i++; } TreeNode *root = pop(stack); return root; } // 求二叉树的值 int evaluateTree(TreeNode *root) { if (root == NULL) { return 0; } if (root->left == NULL && root->right == NULL) { return root->data - '0'; // 将字符换为数字 } int leftValue = evaluateTree(root->left); int rightValue = evaluateTree(root->right); switch (root->data) { case '+': return leftValue + rightValue; case '-': return leftValue - rightValue; case '*': return leftValue * rightValue; case '/': return leftValue / rightValue; default: printf("Error: Invalid operator %c\n", root->data); return 0; } } // 测试代码 int main() { char postfix[] = "23+45+*"; // 后缀表达式 "2+3*4+5" TreeNode *root = constructTree(postfix); int result = evaluateTree(root); printf("Result: %d\n", result); // 输出结果 25 return 0; } ``` 以上代码实现了通过二叉链表遍历将算术表达式换为二叉树并求值的功能,具体实现过程包括: 1. 定义二叉树节点结构体 `TreeNode`,包含节点数据和左右子节点指针; 2. 定义栈结构体 `Stack`,使用数组存储节点指针,并实现入栈、出栈、获取栈顶元素等操作; 3. 实现判断一个字符是否是操作符的函数 `isOperator`; 4. 实现通过二叉链表遍历将算术表达式换为二叉树的函数 `constructTree`,遍历表达式字符串,遇到操作数创建节点并入栈,遇到操作符弹出两个节点作为左右子节点创建新节点并入栈; 5. 实现求二叉树的值的函数 `evaluateTree`,递归遍历二叉树,遇到操作数返回该节点的值,遇到操作符递归计算左右子节点的值并根据操作符进行运算; 6. 在 `main` 函数测试代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值