简体   繁体   English

Python中最简单的树数据结构,可以在两个方向上轻松遍历

[英]Most simple tree data structure in Python, that can be easily traversed in both directions

I would need the simplest possible implementation for a data structure, that can be traversed in both parent->children and children->parent direction; 我需要一个最简单的数据结构实现,它既可以在parent-> children和children-> parent方向上遍历; so ideally the child should hold a reference to the parent as well. 因此理想情况下,孩子也应该参考父母。

Was thinking about a dictionary, where the children would simply hold a reference to their parent, similar to this: 正在考虑一本字典,其中的孩子会简单地引用其父母,类似于以下内容:

# define the root node
a = {'name': 'trunk', 'value': 0, 'parent': None, 'children': []}
# add child
a['children'].append({'name': 'branch-1', 'value': 1,
                      'parent': a, 'children': []})
# and so on...

Is this safe to do? 这样安全吗? (Circular reference might impact garbage collection?) Does it make sense to do this? (循环引用可能会影响垃圾回收?)这样做有意义吗? What would be simpler? 有什么会更简单?

A simple Tree (Node) class, that can be traversed both ways: 一个简单的Tree(节点)类,可以通过两种方式遍历:

class Tree(object):
    def __init__(self, data, children=None, parent=None):
        self.data = data
        self.children = children or []
        self.parent = parent

    def add_child(self, data):
        new_child = Tree(data, parent=self)
        self.children.append(new_child)
        return new_child

    def is_root(self):
        return self.parent is None

    def is_leaf(self):
        return not self.children

    def __str__(self):
        if self.is_leaf():
            return str(self.data)
        return '{data} [{children}]'.format(data=self.data, children=', '.join(map(str, self.children)))

> t = Tree('foo')
> bar = t.add_child('bar')
> baz = t.add_child('baz')
> print(t)
'foo [bar, baz]'

> print(bar.parent)
'foo [bar, baz]'

You would make a Node class. 您将创建一个Node类。

The basic structure would look something like this, though honestly you could probably do it with dicts too. 基本结构看起来像这样,尽管说实话您也可以用字典来完成。 Just personally feel classes are cleaner looking. 只是个人感觉课程看起来更干净。

class Node(object):
    def __init__(self):
        self.parent = None # Single object
        self.child = []  # Array of objects
        self.name = None
        self.data = None 

The rest depends on your needs. 其余的取决于您的需求。 Some functions you may want built into your class (or if you use hashes, build out as methods in your script) 您可能想将某些函数内置到类中(或者,如果您使用哈希,请在脚本中作为方法构建出来)

  • Update: which takes a specific node and updates its values/name/what have you 更新:获取特定节点并更新其值/名称/您拥有什么
  • Delete: which takes a specific node and removes it from the tree. Delete:删除特定节点并将其从树中删除。 If you do this make sure to connect the deleted nodes children to the 如果这样做,请确保将已删除的节点子节点连接到
    deleted nodes parent. 父节点已删除。
  • Insert: which takes a specific point in the tree and adds a new node into it. 插入:在树中指定一个点,并在其中添加一个新节点。 This should update the parent and children around the node. 这将更新节点周围的父级和子级。
  • Update children: appends children to node.child array. 更新子代:将子代追加到node.child数组。 Should be called from update parent as the two processes are self referential. 应该从更新父级调用,因为这两个过程是自引用的。
  • Update parent: Deletes self from parent.child array. 更新父级:从parent.child数组中删除self。 Adds self to new_parent.child array. 将自身添加到new_parent.child数组。

If you want to easily reference specific parts of a node, you can make a hash_map as a sort of table of contents 如果要轻松引用节点的特定部分,则可以将hash_map用作一种目录

node_tree_map = {}
node_tree_map[node.name] = node 
# node_tree_map['name'] would allow you quick access to bob's
# parent/children/value 
# just by knowing the name but without having to traverse 
# the whole tree to find it 

The above will allow you to easily dive into specific nodes if necessary. 如果需要,以上内容将使您轻松进入特定的节点。

Btw, removing a node from being referenced in the tree or hash map would make garbage collection a non issue. 顺便说一句,从树或哈希图中删除引用的节点将使垃圾回收成为一个问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM