樹的定義與屬性及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求解該樹的值

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章