节点尽可能多的孩子python

时间:2016-09-01 12:25:53

标签: python tree

我想在Python中创建一个数据结构,但因为我非常注重C语言。我需要一些帮助。

一般来说,我想创建一个Node类,它将包含数据,指向兄弟的指针,指向子节点的指针以及指向父节点的指针。

这是一种思考Node类的方法:

                                 NODE
            /            /         ...  \                   \
       child_node1 - child_node2 - ... - child_node(N-1) - child_nodeN

到目前为止,我所挣扎的是: 我想超载' +' Node类的运算符,所以我可以这样做:

node1 = Node("data1")
node2 = Node("data2", 3)
node1 = node1 + node2

所以基本上做2个节点,兄弟姐妹。

这是我的代码:

class Node:
def __init__(self, data = None, numberOfChildren = 0):
    '''
    Creates a new Node with *numberOfChildren* children. 
    By default it will be set to 0, meaning it will only create the root of the tree.
    No children whatsoever.
    '''
    self.__sibling_count = 0
    self.__parent = Node()
    self.__sibling = Node()
    self.__data = data

    self.__children = []
    if numberOfChildren != 0:
        '''
        The Node has children and we need to initialize them
        '''
        for i in range(numberOfChildren):
            self.__children[i] = Node()

def getParent(self):
    return self.__parent


def getData(self):
    return self.__data

def getChild(self, i):
    '''
    Returns the ith child of the current *Node*.
    '''
    return self.__children[i]


def __add__(self, other):
    '''
    Overloads the *+* function so that *Node* objects can be added.
    The 2 merged *Node* elements will now be siblings.
    ex. node1  = Node()
        node2 = Node()
        node1 = node1 + node2
    '''
    if self.__sibling_count == 0:
        self.__sibling = other
        self.__sibling_count += 1
    return self

但是当我尝试添加这样的2个节点时:

node1 = Node()
node2 = Node()
node1 = node1 + node2

我得到RuntimeError: maximum recursion depth exceeded。为什么会这样?

2 个答案:

答案 0 :(得分:2)

允许使用Python中的运算符覆盖,但使用+运算符来处理非连接或求和的东西是不受欢迎的。一个更加pythonic的实现就像这个未经测试的片段:

class Node(object):
    def __init__(self, parent=None):
        self.set_parent(parent)
        self.children = set()

    def set_parent(self, parent):
        if self.parent and self.parent is not parent:
            self.parent.children.remove(self)
        self.parent = parent

    def siblings(self):
        if self.parent is None:
            return []
        return [_ for _ in self.parent.children if _ is not self]

    def add_child(self, node):
        self.children.add(node)
        node.set_parent(self)

    def add_sibling(self, node):
        assert self.parent, "root node can't have siblings"
        self.parent.add_child(node)

......等等。当然,您可以覆盖+运算符来执行add_sibling,但其要点是严重依赖本机集合。

如果你想创建一个包含3个孩子的笔记,那就是:

root = Node()
nodes = [Node(parent=root) for _ in range(3)]

答案 1 :(得分:0)

Python递归仅限于防止堆栈溢出和无限递归。没有中断条件的递归或者在经过多次迭代后会停止计数器。

在多个级别之后停止创建更多节点,否则python将阻止你。 您正在激活第一个__init_中的Node,然后激活其中的每一个孩子,依此类推。这永远不会停止,并触发此运行时错误。

将此视为您可以走多远的估计:

>>> def f(): f()
>>> f()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in f
  File "<stdin>", line 1, in f
  File "<stdin>", line 1, in f
  ... another 995 times the same
  File "<stdin>", line 1, in f
RecursionError: maximum recursion depth exceeded

您可以将__init__更改为:

def __init__(self, levels = 5, numberOfChildren = 0, data = None):
    '''
    Creates a new Node with *numberOfChildren* children. 
    By default it will be set to 0, meaning it will only create the root of the tree.
    No children whatsoever.
    '''
    self.__sibling_count = 0
    # these will only produce **new** nodes. I commented them.
    # self.__parent = Node()
    # self.__sibling = Node()
    self.__data = data

    self.__children = []
    if numberOfChildren != 0 and levels > 0:
        '''
        The Node has children and we need to initialize them
        '''
        for i in range(numberOfChildren):
            self.__children[i] = Node(levels - 1, numberOfChildren)