二叉樹(binary tree)中的每一個節點都不能有多於兩個的兒子。node
1.1 二叉樹列表實現python
如上圖的二叉樹可用列表表示:算法
tree=['A', #root ['B', #左子樹 ['D',[],[]], ['E',[],[]]], ['C', #右子樹 ['F',[],[]], []] ]
實現:express
def BinaryTree(item): return [item,[],[]] def insertLeft(tree,item): leftSubtree=tree.pop(1) if leftSubtree: tree.insert(1,[item,leftSubtree,[]]) else: tree.insert(1,[item,[],[]]) return tree def insertRight(tree,item): rightSubtree=tree.pop(2) if rightSubtree: tree.insert(2,[item,[],rightSubtree]) else: tree.insert(2,[item,[],[]]) return tree def getLeftChild(tree): return tree[1] def getRightChild(tree): return tree[2]
要實現下圖的樹:app
tree=BinaryTree('a') insertLeft(tree,'b') insertRight(tree,'c') insertRight((getLeftChild(tree)),'d') insertLeft((getRightChild(tree)),'e') insertRight((getRightChild(tree)),'f')
1.2 二叉樹的類實現post
class BinaryTree(object): def __init__(self,item): self.key=item self.leftChild=None self.rightChild=None def insertLeft(self,item): if self.leftChild==None: self.leftChild=BinaryTree(item) else: t=BinaryTree(item) t.leftChild=self.leftChild self.leftChild=t def insertRight(self,item): if self.rightChild==None: self.rightChild=BinaryTree(item) else: t=BinaryTree(item) t.rightChild=self.rightChild self.rightChild=t
表達式樹(expression tree)的樹葉是操做數,其餘節點爲操做符。ui
圖 ((7+3)*(5-2))的表達式樹表示3d
2.1 根據中綴表達式構造表達式樹:指針
遍歷表達式:blog
1.創建一個空樹
2.遇到'(',爲當前的Node添加一個left child,並將left child當作當前Node。
3.遇到數字,賦值給當前的Node,並返回parent做爲當前Node。
4.遇到('+-*/'),賦值給當前Node,並添加一個Node做爲right child,將right child當作當前的Node。
5.遇到')',返回當前Node的parent。
def buildexpressionTree(exp): tree=BinaryTree('') stack=[] stack.append(tree) currentTree=tree for i in exp: if i=='(': currentTree.insertLeft('') stack.append(currentTree) currentTree=currentTree.leftChild elif i not in '+-*/()': currentTree.key=int(i) parent=stack.pop() currentTree=parent elif i in '+-*/': currentTree.key=i currentTree.insertRight('') stack.append(currentTree) currentTree=currentTree.rightChild elif i==')': currentTree=stack.pop() else: raise ValueError return tree
上述算法對中綴表達式的寫法要求比較繁瑣,小括號應用太多,例如要寫成(a+(b*c))的形式。
用後綴表達式構建表達式樹會方便一點:若是符號是操做數,創建一個單節點並將一個指向它的指針推入棧中。若是符號是一個操做符,從棧中彈出指向兩棵樹T1和T2的指針並造成一棵新的樹,樹的根爲此操做符,左右兒子分別指向T2和T1.
def build_tree_with_post(exp): stack=[] oper='+-*/' for i in exp: if i not in oper: tree=BinaryTree(int(i)) stack.append(tree) else: righttree=stack.pop() lefttree=stack.pop() tree=BinaryTree(i) tree.leftChild=lefttree tree.rightChild=righttree stack.append(tree) return stack.pop()
3.1 先序遍歷(preorder travelsal)
先打印出根,而後遞歸的打印出左子樹、右子樹,對應先綴表達式
def preorder(tree,nodelist=None): if nodelist is None: nodelist=[] if tree: nodelist.append(tree.key) preorder(tree.leftChild,nodelist) preorder(tree.rightChild,nodelist) return nodelist
3.2 中序遍歷(inorder travelsal)
先遞歸的打印左子樹,而後打印根,最後遞歸的打印右子樹,對應中綴表達式
def inorder(tree): if tree: inorder(tree.leftChild) print tree.key inorder(tree.rightChild)
3.3 後序遍歷(postorder travelsal)
遞歸的打印出左子樹、右子樹,而後打印根,對應後綴表達式
def postorder(tree): if tree: for key in postorder(tree.leftChild): yield key for key in postorder(tree.rightChild): yield key yield tree.key
3.4 表達式樹的求值
def postordereval(tree): operators={'+':operator.add,'-':operator.sub,'*':operator.mul,'/':operator.truediv} leftvalue=None rightvalue=None if tree: leftvalue=postordereval(tree.leftChild) rightvalue=postordereval(tree.rightChild) if leftvalue and rightvalue: return operators[tree.key](leftvalue,rightvalue) else: return tree.key