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