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