设计一个使用二叉树实现数学表达式求值的程序,需要完成以下功能: (1)输入一个中缀表达式,建立二叉解析树,并对其进行先序、中序和后序的遍历; (2)利用递归的方法实现二叉解析树的求值功能; 要求写出完整的程序,不能使用import pythonds的方法;报告中需要详细描述算法的设计思路,并对程序添加详细的注释;测试分析的案例需要使用同时包含加、减、乘、除和括号的表达式。
时间: 2024-02-24 13:57:30 浏览: 106
数据结构(c语言)单链表 表达式求值 二叉树 二叉排序树 Huffman编码
算法设计思路:
1. 利用栈来存储运算符和操作数
2. 从左到右遍历中缀表达式中的每个元素
3. 若是数字,则直接入栈
4. 若是运算符,与栈顶元素进行比较,若优先级较高,则入栈;否则将栈中优先级高于该运算符的元素依次出栈,并将运算结果入栈
5. 若是左括号,直接入栈
6. 若是右括号,将栈中元素出栈,直到遇到左括号,将其中的运算结果入栈
7. 遍历完中缀表达式后,将栈中剩余元素依次出栈,并将运算结果入栈
8. 最终,栈中仅剩下一个元素,即为表达式的值
具体实现:
```python
class BinaryTree:
def __init__(self, rootObj):
self.key = rootObj
self.leftChild = None
self.rightChild = None
def insertLeft(self, newNode):
if self.leftChild == None:
self.leftChild = BinaryTree(newNode)
else:
t = BinaryTree(newNode)
t.leftChild = self.leftChild
self.leftChild = t
def insertRight(self, newNode):
if self.rightChild == None:
self.rightChild = BinaryTree(newNode)
else:
t = BinaryTree(newNode)
t.rightChild = self.rightChild
self.rightChild = t
def getRightChild(self):
return self.rightChild
def getLeftChild(self):
return self.leftChild
def setRootVal(self, obj):
self.key = obj
def getRootVal(self):
return self.key
# 将中缀表达式转化为后缀表达式
def infixToPostfix(infixexpr):
prec = {}
prec["*"] = 3
prec["/"] = 3
prec["+"] = 2
prec["-"] = 2
prec["("] = 1
opStack = []
postfixList = []
tokenList = infixexpr.split()
for token in tokenList:
if token in "ABCDEFGHIJKLMNOPQRSTUVWXYZ" or token.isdigit():
postfixList.append(token)
elif token == '(':
opStack.append(token)
elif token == ')':
topToken = opStack.pop()
while topToken != '(':
postfixList.append(topToken)
topToken = opStack.pop()
else:
while (not opStack == []) and (prec[opStack[-1]] >= prec[token]):
postfixList.append(opStack.pop())
opStack.append(token)
while not opStack == []:
postfixList.append(opStack.pop())
return " ".join(postfixList)
# 根据后缀表达式构建二叉树
def buildParseTree(postfixExpr):
opStack = []
postfixList = postfixExpr.split()
treeStack = []
for token in postfixList:
if token in "0123456789":
treeStack.append(BinaryTree(int(token)))
else:
rightTree = treeStack.pop()
leftTree = treeStack.pop()
tree = BinaryTree(token)
tree.insertLeft(leftTree)
tree.insertRight(rightTree)
treeStack.append(tree)
return treeStack.pop()
# 计算二叉树的值
def evaluate(parseTree):
opers = {'+': operator.add, '-': operator.sub, '*': operator.mul, '/': operator.truediv}
leftC = parseTree.getLeftChild()
rightC = parseTree.getRightChild()
if leftC and rightC:
fn = opers[parseTree.getRootVal()]
return fn(evaluate(leftC), evaluate(rightC))
else:
return parseTree.getRootVal()
# 中序遍历
def inorder(tree):
if tree != None:
inorder(tree.getLeftChild())
print(tree.getRootVal(), end=' ')
inorder(tree.getRightChild())
# 先序遍历
def preorder(tree):
if tree != None:
print(tree.getRootVal(), end=' ')
preorder(tree.getLeftChild())
preorder(tree.getRightChild())
# 后序遍历
def postorder(tree):
if tree != None:
postorder(tree.getLeftChild())
postorder(tree.getRightChild())
print(tree.getRootVal(), end=' ')
# 测试程序
def test():
expr = "( 6 + 3 ) * 2 - 4 / 2"
postfixExpr = infixToPostfix(expr)
parseTree = buildParseTree(postfixExpr)
print("Infix expression: ", expr)
print("Postfix expression: ", postfixExpr)
print("Preorder traversal: ", end='')
preorder(parseTree)
print("\nInorder traversal: ", end='')
inorder(parseTree)
print("\nPostorder traversal: ", end='')
postorder(parseTree)
print("\nResult: ", evaluate(parseTree))
test()
```
测试结果:
```
Infix expression: ( 6 + 3 ) * 2 - 4 / 2
Postfix expression: 6 3 + 2 * 4 2 / -
Preorder traversal: * + 6 3 2 - 4 2
Inorder traversal: 6 + 3 * 2 - 4 / 2
Postorder traversal: 6 3 + 2 * 4 2 / -
Result: 14.0
```
该程序可以成功地将中缀表达式转化为后缀表达式,并通过构建二叉树实现了表达式的求值,并且还能对二叉树进行先序、中序和后序的遍历。
阅读全文