二叉树深度优先遍历的一个例子

  之前在屡业务逻辑的时候曾试图将数据构建成二叉树的格式,使用深度优先遍历的方式获取想要的结果(结果证明自己还是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']]
    """

 

~~

posted on 2020-09-25 16:50  江湖乄夜雨  阅读(497)  评论(0编辑  收藏  举报