python实现树结构并显示

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_36810544/article/details/100976545

因为需要查表,但是关键字有各种组合非常烦,为了不写一堆的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文件,就几行:

舌淡红,舌形瘦,血虚,,,,
舌淡红,舌形胖,湿,痰,阳虚,气虚,寒
舌红,,阴虚,暑,阳亢,津亏,
舌红,舌形瘦,阴虚,,,,
舌红,舌形胖,热,痰,湿,血热,
舌绛,,血热,热,阴虚,亡阴,
舌白,,血虚,阳虚,气虚,气陷,
舌白,舌形胖,阳虚,寒,湿,气虚,
舌紫,,阳虚,血瘀,痰,,

猜你喜欢

转载自blog.csdn.net/qq_36810544/article/details/100976545