树的定义与属性及python实现

树的定义:

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笨猪起飞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值