将数学表达式转化成树结构

def from_infix_to_prefix(expression):
    st = list()
    res = list()
    priority = {"+": 0, "-": 0, "*": 1, "/": 1, "^": 2}
    expression = deepcopy(expression)
    expression.reverse()
    for e in expression:
        if e in [")", "]"]:
            st.append(e)
        elif e == "(":
            c = st.pop()
            while c != ")":
                res.append(c)
                c = st.pop()
        elif e == "[":
            c = st.pop()
            while c != "]":
                res.append(c)
                c = st.pop()
        elif e in priority:
            while len(st) > 0 and st[-1] not in [")", "]"] and priority[e] < priority[st[-1]]:
                res.append(st.pop())
            st.append(e)
        else:
            res.append(e)
    while len(st) > 0:
        res.append(st.pop())
    res.reverse()
    return res

['(', 'N1', '-', '1', ')', '*', 'N0'] -> ['*', '-', 'N1', '1', 'N0']
先反转是为了得到先序遍历 根左右,不然就会成为根右左

将表达式转换为树结构,常见的方法是利用表达式的不同表示形式(如中缀表达式、后缀表达式等)来构建表达式树。以下以中缀表达式和后缀表达式为例说明构建方法: ### 从中缀表达式构建表达式树 可以先将中缀表达式转换为后缀表达式,再基于后缀表达式构建表达式树。 - **中缀转后缀**:按照引用[1]中的算法,初始化一个空的运算符栈,在未到达中缀表达式结尾且无错误时,依次获取表达式标记。若标记是左括号则压入栈;若是右括号,连续弹出栈中元素直到遇到左括号;若是运算符,若栈为空或标记优先级高于栈顶元素则压入栈,否则弹出并显示栈顶元素再比较;若是操作数则直接显示。到达中缀表达式结尾时,弹出并显示栈中剩余元素直至栈空[^1]。 ```python def infix_to_postfix(expression): precedence = {'+': 1, '-': 1, '*': 2, '/': 2} output = [] operator_stack = [] for token in expression: if token.isalnum(): output.append(token) elif token == '(': operator_stack.append(token) elif token == ')': while operator_stack and operator_stack[-1] != '(': output.append(operator_stack.pop()) operator_stack.pop() # 弹出左括号 else: while operator_stack and operator_stack[-1] != '(' and precedence[token] <= precedence.get(operator_stack[-1], 0): output.append(operator_stack.pop()) operator_stack.append(token) while operator_stack: output.append(operator_stack.pop()) return output ``` - **基于后缀表达式构建表达式树**:遍历后缀表达式,遇到操作数创建叶子节点压入栈,遇到运算符创建内部节点,从栈中弹出两个节点作为左右子节点,再将该内部节点压入栈。 ```python class TreeNode: def __init__(self, value): self.value = value self.left = None self.right = None def postfix_to_expression_tree(postfix): stack = [] for token in postfix: if token.isalnum(): node = TreeNode(token) stack.append(node) else: right = stack.pop() left = stack.pop() node = TreeNode(token) node.left = left node.right = right stack.append(node) return stack.pop() ``` ### 直接从中缀表达式构建表达式树 可以使用两个栈,一个存储操作数节点,一个存储运算符节点。扫描中缀表达式,遇到操作数创建节点压入操作数栈;遇到运算符,根据运算符优先级和括号情况处理运算符栈,构建表达式树。 ```python def infix_to_expression_tree(expression): precedence = {'+': 1, '-': 1, '*': 2, '/': 2} operand_stack = [] operator_stack = [] for token in expression: if token.isalnum(): node = TreeNode(token) operand_stack.append(node) elif token == '(': operator_stack.append(token) elif token == ')': while operator_stack and operator_stack[-1] != '(': op = operator_stack.pop() right = operand_stack.pop() left = operand_stack.pop() node = TreeNode(op) node.left = left node.right = right operand_stack.append(node) operator_stack.pop() # 弹出左括号 else: while operator_stack and operator_stack[-1] != '(' and precedence[token] <= precedence.get(operator_stack[-1], 0): op = operator_stack.pop() right = operand_stack.pop() left = operand_stack.pop() node = TreeNode(op) node.left = left node.right = right operand_stack.append(node) operator_stack.append(token) while operator_stack: op = operator_stack.pop() right = operand_stack.pop() left = operand_stack.pop() node = TreeNode(op) node.left = left node.right = right operand_stack.append(node) return operand_stack.pop() ``` ### 从后缀表达式直接构建表达式树 直接遍历后缀表达式,遇到操作数创建叶子节点压入栈,遇到运算符创建内部节点并连接左右子节点。 ```python def postfix_to_expression_tree_direct(postfix): stack = [] for token in postfix: if token.isalnum(): node = TreeNode(token) stack.append(node) else: right = stack.pop() left = stack.pop() node = TreeNode(token) node.left = left node.right = right stack.append(node) return stack.pop() ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值