Python递归树问题(添加元素或任意节点)

时间:2013-10-04 22:04:06

标签: python recursion tree

我必须使用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.

在给定树(a)和所需的新节点的情况下,我尝试在给定任意节点(k)的情况下添加新节点。我只能用递归来解决这个问题。

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

但我不太了解递归,不足以做到正确;这最终添加了具有适当父节点的新节点,但添加了无节点。所以这是另一个例子:

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()

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

1 个答案:

答案 0 :(得分:0)

您看到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": {}}}}}