樹的定義:
樹由若干節點、以及兩兩連接節點的邊組成,並有如下性質:
(1)其中一個節點被設定爲根;
(2)每個節點n(除根節點)都恰連接一條來自節點p的邊;
(3)每個節點從根開始的路徑是惟一的;
另外一種定義(遞歸定義):樹是空集,或者由根節點及多個字數構成,每個子樹的根到根節點具有邊相連。
樹的python實現
方法一:嵌套列表實現
#創建僅有根節點的二叉樹
def BinaryTree(r):
return [r,[],[]]
#將新節點插入樹中作爲其直接子節點
def InsertLeft(root,newBranch):
t=root.pop(1)
if len(t)>1: #左子節點的列表不爲空
root.insert(1,[newBranch,t,[]])
else:
root.insert(1,[newBranch,[],[]])
return root
def InsertRight(root,newBranch):
t=root.pop(2)
if len(t)>1:
root.insert(2,[newBranch,[],t])
else:
root.insert(2,[newBranch,[],[]])
return root
# 取得或返回根節點
def getRootVal(root):
return root[0]
def setRootVal(root,newVal):
root[0]=newVal
#返回左右子樹
def getLeftChild(root):
return root[1]
def getRightChild(root):
return root[2]
tree=BinaryTree('a')
InsertLeft(tree,'b')
InsertRight(tree,'c')
InsertLeft(getLeftChild(tree),'d')
InsertRight(getLeftChild(tree),'e')
InsertLeft(getRightChild(tree),'f')
print(tree) #['a', ['b', ['d', [], []], ['e', [], []]], ['c', ['f', [], []], []]]
方法二:鏈表實現
# 使用遞歸實現二叉樹基本功能
class BinaryTree:
def __init__(self, root_obj):
self.key = root_obj
self.left_child = None
self.right_child = None
def insert_left(self, new_node):
node = BinaryTree(new_node)
if self.left_child is None:
self.left_child = node
else:
node.left_child = self.left_child
self.left_child = node
def insert_right(self, new_node):
node = BinaryTree(new_node)
if self.right_child is None:
self.right_child = node
else:
node.right_child = self.right_child
self.right_child = node
def get_right_child(self):
return self.right_child
def get_left_child(self):
return self.left_child
def set_root_val(self, obj):
self.key = obj
def get_root_val(self):
return self.key
樹的應用:表達式解析
實例:
求解思路:
python實現:建立表達式解析數
# 建立一個算術分析樹
def build_parse_tree(fp_exp):
fp_list = fp_exp.split()
p_stack = Stack()
e_tree = BinaryTree('')
p_stack.push(e_tree)
current_tree = e_tree
for item in fp_list:
if item == '(':
current_tree.insert_left('')
p_stack.push(current_tree)
current_tree = current_tree.get_left_child()
elif item not in ['+', '-', '*', '/', ')']:
current_tree.set_root_val(int(item))
parent = p_stack.pop()
current_tree = parent
elif item in ['+', '-', '*', '/']:
current_tree.set_root_val(item)
current_tree.insert_right('')
p_stack.push(current_tree)
current_tree = current_tree.get_right_child()
elif item == ')':
current_tree = p_stack.pop()
else:
raise ValueError
return e_tree
利用解析數求值
思路:從樹的底層子樹開始,逐步向上層求值,最終得到整個表達式的值。
採用遞歸算法來處理,
#增加一個匹配規則,提高可讀性
class DoMatch:
@staticmethod
def add(op1, op2):
return op1 + op2
@staticmethod
def sub(op1, op2):
return op1 - op2
@staticmethod
def mul(op1, op2):
return op1 * op2
@staticmethod
def true_div(op1, op2):
return op1 / op2
解析數求值的python實現:
# 算術分析式的求值
def evaluate(parse_tree):
operator = DoMatch()
opers = {'+': operator.add,
'-': operator.sub,
'*': operator.mul,
'/': operator.true_div
}
left_c = parse_tree.get_left_child()
right_c = parse_tree.get_right_child()
if left_c and right_c:
fn = opers[parse_tree.get_root_val()]
return fn(evaluate(left_c), evaluate(right_c))
else:
return parse_tree.get_root_val()
##測試實例
建立具體表達式的解析樹
利用evalate求解該樹的值