python實現樹結構並顯示

因爲需要查表,但是關鍵字有各種組合非常煩,爲了不寫一堆的if else決定弄個搜索樹,葉子節點就是我要的結果,路徑就是表中的關鍵字組合。之前都是用指針實現的各種鏈表 圖 樹,換成python後忽然不知道怎麼辦了。在網上搜了下,用python的list來實現,不過網上幾乎都是二叉樹的實現,木法只好自己寫啦。這是按我的需求寫的,如果要直接還得按實際情況略作修改。
樹的顯示使用graphviz這個包,不過僅僅pip是不行的,還需要去下個壓縮包(請自行百度)
========================== 我是定妝照的分界線==================
在這裏插入圖片描述好像還挺好看,哈哈~
======================= 我是答應我以後直接給出能直接運行的源碼好嗎的分界線====================

# -*- coding:utf-8 -*-
# name: 樹型結構
# author: bqh
# datetime:2019/9/17 9:48
# =========================

from graphviz import Digraph
import os
import string
import random

os.environ["PATH"] += os.pathsep + r'D:\Program Files (x86)\graphviz2.38\release\bin'


class Node:
    def __init__(self, parent=None, children=None, data=None, tag=None):
        """
        結點數據結構
        :param parent:  父節點
        :param children: 子節點,列表結構
        :param data: 數據域, 類型string
        """
        if children is None:
            children = []
        self.tag = tag if tag is not None else ''.join(random.sample(string.ascii_letters + string.digits, 8))
        self.parent = parent
        self.data = data
        self.children = children


class Tree:
    def __init__(self, rootdata):
        self.root = Node(data=rootdata)

    def insert(self, parent_node, children_node):
        children_node.parent = parent_node
        parent_node.children.append(children_node)

    def search(self, node, data):
        """
        以node爲根節點查找值爲data的結點,返回
        :param node: 根節點
        :param data: 值域
        :return:
        """
        if node.data == data:
            return node
        elif len(node.children) == 0:
            return None
        else:
            for child in node.children:
                res = self.search(child, data)
                if res is not None:
                    return res
            return None

    def get_leavesByDataRoute(self, data_list):
        """
        根據數據域提供的列表查找該路徑下的所有葉子集合
        :param data_list: 路徑的數據域列表,[子節點數據, ……]
        :return: 該路徑下的葉子數據集合
        """
        leaves = set()
        node = self.root
        for data in data_list:
            node = self.search(node, data)

        for child in node.children:
            if len(child.children) > 0:
                leaves.add(child.data)

        return leaves

    def show(self, save_path=None):
        """
        顯示該樹形結構
        :return:
        """
        from random import sample

        colors = ['skyblue', 'tomato', 'orange', 'purple', 'green', 'yellow', 'pink', 'red']
        plt = Digraph(comment='Tree')

        def print_node(node):
            color = sample(colors, 1)[0]
            if len(node.children) > 0:
                for child in node.children:
                    plt.node(child.tag, child.data, style='filled', color=color, fontname="Heiti")
                    plt.edge(node.tag, child.tag)
                    print_node(child)

        plt.node(self.root.tag, self.root.data, style='filled', color=sample(colors, 1)[0])
        print_node(self.root)
        plt.view()
        if save_path is not None:
            plt.render(save_path)


def create(csvfile_name):
    tree = Tree('tongue_color')
    with open(csvfile_name, 'r', encoding='utf-8') as rf:
        lines = rf.readlines()
        for line in lines:
            elements = line.split(',')
            p = tree.root
            # 前2列或4列是屬性組合,作爲搜索路徑
            for i in range(len(elements) - 5):
                if len(elements[i]) == 0:
                    continue
                q = tree.search(p, elements[i])
                if q is None:
                    q = Node(data=elements[i])
                    tree.insert(p, q)
                p = q
            # 最後5列是證型,全部作爲當前節點的葉子節點
            for i in range(len(elements) - 5, len(elements)):
                if len(elements[i].strip()) == 0:
                    continue
                new_node = Node(data=elements[i])
                tree.insert(p, new_node)

    return tree


def tree_test():
    tree = Tree('10')
    root = tree.root
    for i in range(7, 10):
        node = Node(data=str(i))
        tree.insert(root, node)

    p = tree.search(root, '7')
    child = Node(data=u'淡紅')
    tree.insert(p, child)

    p = tree.search(root, '8')
    for i in range(4, 6):
        node = Node(data=str(i))
        tree.insert(p, node)

    tree.show()


if __name__ == '__main__':
    file = r'E:\code\Tongue\TongueProposal\material\tongue_color.csv'
    tree = create(file)
    tree.show()

tongue_color.csv文件,就幾行:

舌淡紅,舌形瘦,血虛,,,,
舌淡紅,舌形胖,溼,痰,陽虛,氣虛,寒
舌紅,,陰虛,暑,陽亢,津虧,
舌紅,舌形瘦,陰虛,,,,
舌紅,舌形胖,熱,痰,溼,血熱,
舌絳,,血熱,熱,陰虛,亡陰,
舌白,,血虛,陽虛,氣虛,氣陷,
舌白,舌形胖,陽虛,寒,溼,氣虛,
舌紫,,陽虛,血瘀,痰,,
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章