树的定义:
树由若干节点、以及两两连接节点的边组成,并有如下性质:
(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求解该树的值