數據結構學習筆記18(北大公開課)目錄
樹的應用之表達式解析
一、知識概覽
本章主要講樹的應用——表達式解析。
1.1 樹的應用
本節主要講如何建立表達式解析樹以及如何利用表達式解析樹求值
二、代碼實現
2.1 表達式解析樹的建立
#表達式解析樹
def buildParseTree(fpexp):#字符串表達的全括號表達式
fplist=fpexp.split()#創建單詞列表
pStack=Stack()#創建節點的棧
eTree=BinaryTree('')#創建空二叉樹
pStack.push(eTree)#當前節點入棧
currentTree=eTree#當前節點設爲剛建立的節點
for i in fplist:#對每個單詞從左到右挨個掃描
if i=='(':#表達式開始
currentTree.insertLeft('')#創建左子節點
pStack.push(currentTree)#老的當前節點入棧
currentTree=currentTree.getLeftChild()
elif i not in ['+','-','*','/',')']:
currentTree.setRootval(int(i))
parent=pStack.pop()
currentTree=parent#出棧上升
elif i in ['+','-','*','/']:
currentTree.setRootval(i)#當前節點設成操作符
currentTree.insertRight('')#創建一個右子樹
pStack.push(currentTree)#老的當前節點push到棧
currentTree=currentTree.getRightChild#下降到右子節點
elif i==')':#表達式結束
currentTree=pStack.pop()#出棧上升返回到父節點
else:
raise ValueError#例外處理
2.2 表達式解析樹求值
#利用表達式解析樹求值
import operator
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()]#fn翻譯保存的操作符
return fn(evaluate(leftC),evaluate(rightC))
else:
return parseTree.getRootVal