【问题标题】:Python recursive tree issues (adding elements or arbitrary nodes)Python递归树问题(添加元素或任意节点)
【发布时间】:2013-10-12 01:24:28
【问题描述】:

我必须使用 A* 解决学校的一个小问题(这不是我遇到的问题),我想使用树来存储探索过的节点,这样当找到解决方案时很容易找到从叶子返回根的路径。

在 python 中,可以使用 defaultdictionaries 创建树:

def tree(): return defaultdict(tree)

例如:

a=tree() is an empty tree
a[1] tree with one root node
a[1][2] has a child of 2
a[1][2]['another']... and so on.

我试图做一些事情来添加一个新节点给定一个任意节点(k)给定树(a)和所需的新节点。我只能使用递归来解决。

def addNode(a,k,newNode):
    for x in list(a.keys()):
        if x!=k:
            a[addNode(a[x],k,newNode)]
        if x==k:
            a[x][newNode]
            break

但我不太了解递归,不足以正确执行;这最终会添加具有正确父节点的新节点,但会添加 None 节点。所以这是另一个例子:

a=tree()
a
defaultdict(<function tree at 0x029CE930>, {})
a[1]
defaultdict(<function tree at 0x029CE930>, {})
a[1][2]
defaultdict(<function tree at 0x029CE930>, {})
a[1][3]
defaultdict(<function tree at 0x029CE930>, {})
a[1][2]['b']
defaultdict(<function tree at 0x029CE930>, {})
addNode(a,'b','new')
a
defaultdict(<function tree at 0x029CE930>, {1: defaultdict(<function tree at 0x029CE930>, {2: defaultdict(<function tree at 0x029CE930>, {'b': defaultdict(<function    tree at 0x029CE930>, {'new': defaultdict(<function tree at 0x029CE930>, {})})}), 3:   defaultdict(<function tree at 0x029CE930>, {}), None: defaultdict(<function tree at   0x029CE930>, {})}), None: defaultdict(<function tree at 0x029CE930>, {})})

如何正确实现这一点,为什么 addNode 过程会生成这些 None 节点?我有点看到我必须正确退出递归,那是怎么做的?

我也尝试恢复路径如下:

parentList=[]
found=False
def getPath(tree,final):
    global found
    for x in list(tree.keys()):
        parentList.append(x)
        if found:
            parentList.pop()
        if x==final:
            found=True
        else:
            getPath(tree[x],final)
            if not found:
                parentList.pop()

我尝试将所有父节点添加到堆栈中,直到找到目标节点,然后弹出所有父节点,直到只有到达目标状态的路径保留在堆栈中。我怎样才能以优雅的方式做到这一点?

【问题讨论】:

    标签: python recursion tree


    【解决方案1】:

    您看到添加了None,因为您的addNode 函数没有返回任何内容。这意味着当您使用a[addNode(a[x],k,newNode)] 进行递归调用时,它相当于addNode(a[x],k,newNode); a[None]。我认为您实际上想要以下内容:

    def addNode(a,k,newNode):
        if k in a:
            a[k][newNode]
        else:
            for x in a:
                addNode(a[x],k,newNode)
    

    例如:

    >>> import json
    >>> a = tree()
    >>> a['1']
    defaultdict(<function <lambda> at 0x7fee0285f848>, {})
    >>> addNode(a, '1', 'new')
    >>> print json.dumps(a)
    {"1": {"new": {}}}
    >>> a['1']['2']['3']
    defaultdict(<function <lambda> at 0x7fee0285f848>, {})
    >>> addNode(a, '3', 'new2')
    >>> print json.dumps(a)
    {"1": {"new": {}, "2": {"3": {"new2": {}}}}}
    

    【讨论】:

    • 我看到我不小心用 a[addNode(a[x],k,newNode)] 自己创建了 None 节点,非常感谢您指出这一点。我花了一些时间试图弄清楚,我只是看不到我的错误,我认为这是递归的副作用,从某种意义上说,但这主要是我自己的错。再次感谢您
    猜你喜欢
    • 2019-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-08
    • 2021-03-17
    • 1970-01-01
    • 1970-01-01
    • 2017-09-26
    相关资源
    最近更新 更多