1. 二叉樹
二叉樹(binary tree)中的每個節點都不能有多於兩個的兒子。

1.1 二叉樹列表實現
如上圖的二叉樹可用列表表示:
tree=['A', #root
['B', #左子樹
['D',[],[]],
['E',[],[]]],
['C', #右子樹
['F',[],[]],
[]]
]
實現:
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]
要實現下圖的樹:

tree=BinaryTree('a')
insertLeft(tree,'b')
insertRight(tree,'c')
insertRight((getLeftChild(tree)),'d')
insertLeft((getRightChild(tree)),'e')
insertRight((getRightChild(tree)),'f')
1.2 二叉樹的類實現
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
2. 表達式樹
表達式樹(expression tree)的樹葉是操作數,其他節點為操作符。

圖 ((7+3)*(5-2))的表達式樹表示
2.1 根據中綴表達式構造表達式樹:
遍歷表達式:
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.樹的遍歷
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
