Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 通用树实现?_Python_Python 3.x - Fatal编程技术网

Python 通用树实现?

Python 通用树实现?,python,python-3.x,Python,Python 3.x,我想构建一个通用树,其根节点包含“n”个子节点,这些子节点可能包含其他子节点。…Python中的树非常简单。创建一个包含数据和子级列表的类。每个子类都是同一类的实例。这是一棵普通的n元树 class Node(object): def __init__(self, data): self.data = data self.children = [] def add_child(self, obj): self.children.a

我想构建一个通用树,其根节点包含“n”个子节点,这些子节点可能包含其他子节点。…

Python中的树非常简单。创建一个包含数据和子级列表的类。每个子类都是同一类的实例。这是一棵普通的n元树

class Node(object):
    def __init__(self, data):
        self.data = data
        self.children = []

    def add_child(self, obj):
        self.children.append(obj)
然后互动:

>>> n = Node(5)
>>> p = Node(6)
>>> q = Node(7)
>>> n.add_child(p)
>>> n.add_child(q)
>>> n.children
[<__main__.Node object at 0x02877FF0>, <__main__.Node object at 0x02877F90>]
>>> for c in n.children:
...   print c.data
... 
6
7
>>> 
>n=节点(5)
>>>p=节点(6)
>>>q=节点(7)
>>>n.add_child(p)
>>>n.add_child(q)
>>>儿童
[, ]
>>>对于n.儿童中的c:
...   打印c.data
... 
6.
7.
>>> 

这是一个非常基本的框架,不是抽象的或任何东西。实际的代码将取决于您的具体需求-我只是想说明这在Python中非常简单。

我在我的网站上发布了一个Python[3]树实现:

希望有用,

好的,下面是代码:

import uuid

def sanitize_id(id):
    return id.strip().replace(" ", "")

(_ADD, _DELETE, _INSERT) = range(3)
(_ROOT, _DEPTH, _WIDTH) = range(3)

class Node:

    def __init__(self, name, identifier=None, expanded=True):
        self.__identifier = (str(uuid.uuid1()) if identifier is None else
                sanitize_id(str(identifier)))
        self.name = name
        self.expanded = expanded
        self.__bpointer = None
        self.__fpointer = []

    @property
    def identifier(self):
        return self.__identifier

    @property
    def bpointer(self):
        return self.__bpointer

    @bpointer.setter
    def bpointer(self, value):
        if value is not None:
            self.__bpointer = sanitize_id(value)

    @property
    def fpointer(self):
        return self.__fpointer

    def update_fpointer(self, identifier, mode=_ADD):
        if mode is _ADD:
            self.__fpointer.append(sanitize_id(identifier))
        elif mode is _DELETE:
            self.__fpointer.remove(sanitize_id(identifier))
        elif mode is _INSERT:
            self.__fpointer = [sanitize_id(identifier)]

class Tree:

    def __init__(self):
        self.nodes = []

    def get_index(self, position):
        for index, node in enumerate(self.nodes):
            if node.identifier == position:
                break
        return index

    def create_node(self, name, identifier=None, parent=None):

        node = Node(name, identifier)
        self.nodes.append(node)
        self.__update_fpointer(parent, node.identifier, _ADD)
        node.bpointer = parent
        return node

    def show(self, position, level=_ROOT):
        queue = self[position].fpointer
        if level == _ROOT:
            print("{0} [{1}]".format(self[position].name, self[position].identifier))
        else:
            print("\t"*level, "{0} [{1}]".format(self[position].name, self[position].identifier))
        if self[position].expanded:
            level += 1
            for element in queue:
                self.show(element, level)  # recursive call

    def expand_tree(self, position, mode=_DEPTH):
        # Python generator. Loosly based on an algorithm from 'Essential LISP' by
        # John R. Anderson, Albert T. Corbett, and Brian J. Reiser, page 239-241
        yield position
        queue = self[position].fpointer
        while queue:
            yield queue[0]
            expansion = self[queue[0]].fpointer
            if mode is _DEPTH:
                queue = expansion + queue[1:]  # depth-first
            elif mode is _WIDTH:
                queue = queue[1:] + expansion  # width-first

    def is_branch(self, position):
        return self[position].fpointer

    def __update_fpointer(self, position, identifier, mode):
        if position is None:
            return
        else:
            self[position].update_fpointer(identifier, mode)

    def __update_bpointer(self, position, identifier):
        self[position].bpointer = identifier

    def __getitem__(self, key):
        return self.nodes[self.get_index(key)]

    def __setitem__(self, key, item):
        self.nodes[self.get_index(key)] = item

    def __len__(self):
        return len(self.nodes)

    def __contains__(self, identifier):
        return [node.identifier for node in self.nodes if node.identifier is identifier]

if __name__ == "__main__":

    tree = Tree()
    tree.create_node("Harry", "harry")  # root node
    tree.create_node("Jane", "jane", parent = "harry")
    tree.create_node("Bill", "bill", parent = "harry")
    tree.create_node("Joe", "joe", parent = "jane")
    tree.create_node("Diane", "diane", parent = "jane")
    tree.create_node("George", "george", parent = "diane")
    tree.create_node("Mary", "mary", parent = "diane")
    tree.create_node("Jill", "jill", parent = "george")
    tree.create_node("Carol", "carol", parent = "jill")
    tree.create_node("Grace", "grace", parent = "bill")
    tree.create_node("Mark", "mark", parent = "jane")

    print("="*80)
    tree.show("harry")
    print("="*80)
    for node in tree.expand_tree("harry", mode=_WIDTH):
        print(node)
    print("="*80)
如果你坚持“OOP”的话,我想展示一下关于实现的另一种想法

任何树 我推荐

例子 特征 还具有功能强大的API,包括:

  • 简单树创建
  • 简单树修改
  • 预序树迭代
  • 后序树迭代
  • 解析相对和绝对节点路径
  • 从一个节点移动到另一个节点
  • 树渲染(请参见上面的示例)
  • 节点连接/分离连接

我无法开始,请给我一张code@vishnu:这就足够了吗?这个答案应该被接受。答案是,这可能会导致对象或魔术方法的递归限制错误。链表实现转换树结构怎么样?比如这里:|问题是,这会带来很多工作要做,比如确保一个节点没有两个父节点。@ErdinEray你能修复链接吗?这是几天前才提出的。。。你阅读了哪些在线资源?你试过什么?你在哪里被卡住?双重欺骗:考虑在这里发布代码。如果你的博客消失了,这个答案将毫无用处。@Brett Kromkamp。很好的实现,但想知道您发布了哪种软件许可证类型的实现?谢谢,啊!看起来像GPLv3。无法使用此代码:-(您将如何从该树的中间删除?看起来不错,但搜索具有特定属性的所有节点将无法工作,因为它使用OrderedDict。我打开了一个github问题。
node = { 'parent':0, 'left':0, 'right':0 }
import copy
root = copy.deepcopy(node)
root['parent'] = -1
left = copy
class Node:
    def __init__(self,data):
        self.data = data
        self.child = {}
    def append(self, title, child):
        self.child[title] = child

CEO = Node( ('ceo', 1000) )
CTO = ('cto',100)
CFO = ('cfo', 10)
CEO.append('left child', CTO)
CEO.append('right child', CFO)

print CEO.data
print ' ', CEO.child['left child']
print ' ', CEO.child['right child']
from anytree import Node, RenderTree

udo = Node("Udo")
marc = Node("Marc", parent=udo)
lian = Node("Lian", parent=marc)
dan = Node("Dan", parent=udo)
jet = Node("Jet", parent=dan)
jan = Node("Jan", parent=dan)
joe = Node("Joe", parent=dan)

print(udo)
Node('/Udo')
print(joe)
Node('/Udo/Dan/Joe')

for pre, fill, node in RenderTree(udo):
    print("%s%s" % (pre, node.name))
Udo
├── Marc
│   └── Lian
└── Dan
    ├── Jet
    ├── Jan
    └── Joe

print(dan.children)
(Node('/Udo/Dan/Jet'), Node('/Udo/Dan/Jan'), Node('/Udo/Dan/Joe'))