zoukankan      html  css  js  c++  java
  • 二叉树深度优先遍历的一个例子

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

    ~~

  • 相关阅读:
    第三次实验总结
    实验总结
    自我介绍
    BGP学习笔记
    source insight用于C语言编程的工具脚本
    LevelDB源码剖析
    LevelDB源码之五Current文件Manifest文件版本信息
    LevelDB源码之六缓存机制
    LevelDB源码之四LOG文件
    jQuery向动态生成的内容添加事件响应
  • 原文地址:https://www.cnblogs.com/paulwhw/p/13731164.html
Copyright © 2011-2022 走看看