paulwhw

  之前在屡业务逻辑的时候曾试图将数据构建成二叉树的格式,使用深度优先遍历的方式获取想要的结果(结果证明自己还是too young...)。

  但是思考问题的过程还是很有意思的。。。

  现在将二叉树的深度优先遍历的实例分享一下,当作是自己的一个笔记吧:

  入参:

node_list = [
    {\'data\': \'A\', \'parent\': None, \'children\': [\'B\', \'C\'], \'is_root\': True},
    {\'data\': \'B\', \'parent\': \'A\', \'children\': [\'D\', \'E\'], \'is_root\': False},
    {\'data\': \'C\', \'parent\': \'A\', \'children\': [\'F\'], \'is_root\': False},
    {\'data\': \'D\', \'parent\': \'B\', \'children\': None, \'is_root\': False},
    {\'data\': \'E\', \'parent\': \'B\', \'children\': None, \'is_root\': False},
    {\'data\': \'F\', \'parent\': \'C\', \'children\': None, \'is_root\': False}
]

  出参:

[[\'A\', \'B\', \'D\'], [\'A\', \'B\', \'E\'], [\'A\', \'C\', \'F\']]

  代码:

 

# -*- coding:utf-8 -*-
class BaseNode():
    """基础节点类"""
    def __init__(self, data, parent=None, children=None):
        self.data = data
        self.parent = parent
        self.children = children


class BaseTree():
    """基础多叉树类"""
    def __init__(self, root=None):
        self.root = root

    @classmethod
    def build_tree(cls, node_list):
        """
        根据节点属性列表构建树
        :param node_list: [{\'data\': \'A\', \'parent\': None, \'children\': [\'B\', \'C\'], \'is_root\': True},
        {\'data\': \'B\', \'parent\': \'A\', \'children\': [\'D\'], \'is_root\': False}]
        return: 树对象
        """
        node_dict = {}
        # 循环遍历节点数据列表创建节点对象映射字典,此时节点对象没有明确父子关系
        for node_data in node_list:
            data = node_data["data"]
            node_dict[data] = BaseNode(data)
        # 明确节点对象的父子关系
        for node_data in node_list:
            data = node_data["data"]
            node = node_dict[data]
            # 明确根据节点对象
            if node_data["is_root"]:
                root = node
            # 为每一个非root节点明确其父子节点对象
            node.parent = node_dict.get(node_data["parent"])
            if node_data["children"]:
                node.children = [node_dict.get(child) for child in node_data["children"]]
            else:
                node.children = None
        return cls(root)

    def dfs_preorder_travel(self, start_node):
        """
        深度优先先序遍历数,获取遍历路径中所有节点的值
        :param start_node: 出发节点对象
        :return node_path_list: 所有路径列表
        """
        node_path_list = []
        stack_list = []
        visited = []
        stack_list.append(start_node)
        visited.append(start_node)
        while len(stack_list) > 0:
            p_node = stack_list[-1]
            if p_node.children is not None:
                for child_node in p_node.children:
                    if child_node not in visited:
                        print("child_node.data>>>>>>>>>", child_node.data)
                        if child_node.children is None:
                            # node_path = self.back_travel(child_node)
                            node_path = stack_list + [child_node]
                            node_path_data = [i.data for i in node_path]
                            node_path_list.append(node_path_data)
                        visited.append(child_node)
                        stack_list.append(child_node)
                        break
            if stack_list[-1] == p_node:
                stack_list.pop()
        return node_path_list

    def back_travel(self, leaf_node):
        """
        从叶子节点回溯到根节点经过的路径
        :param leaf_node: 叶子节点对象
        :return node_path
        """
        node_path = [leaf_node.data]
        p_node = leaf_node.parent
        while p_node:
            node_path.insert(0, p_node.data)
            p_node = p_node.parent
        return node_path


if __name__ == \'__main__\':
    node_list = [
        {\'data\': \'A\', \'parent\': None, \'children\': [\'B\', \'C\'], \'is_root\': True},
        {\'data\': \'B\', \'parent\': \'A\', \'children\': [\'D\', \'E\'], \'is_root\': False},
        {\'data\': \'C\', \'parent\': \'A\', \'children\': [\'F\'], \'is_root\': False},
        {\'data\': \'D\', \'parent\': \'B\', \'children\': None, \'is_root\': False},
        {\'data\': \'E\', \'parent\': \'B\', \'children\': None, \'is_root\': False},
        {\'data\': \'F\', \'parent\': \'C\', \'children\': None, \'is_root\': False}
    ]

    tree = BaseTree.build_tree(node_list=node_list)
    ret = tree.dfs_preorder_travel(start_node=tree.root)
    print("ret>>>>",ret)
    """
    child_node.data>>>>>>>>> B
    child_node.data>>>>>>>>> D
    child_node.data>>>>>>>>> E
    child_node.data>>>>>>>>> C
    child_node.data>>>>>>>>> F
    ret>>>> [[\'A\', \'B\', \'D\'], [\'A\', \'B\', \'E\'], [\'A\', \'C\', \'F\']]
    """

 

~~

分类:

技术点:

相关文章: