如何以递归方式遍历树并在python中创建受访节点列表

时间:2016-11-22 19:40:12

标签: python algorithm recursion tree

我已经定义了一个类Tree,它包含一个TreeNodes列表,如下所示:

class Tree(object):
    def __init__(self, name, nodes):
        self.name = name
        self.nodes = nodes

class TreeNode(object):
    def __init__(self, name, parent):
        self.name = name
        self.parent = parent

如您所见,对于每个TreeNode,我只定义一个父节点。但是,我想编写一个Tree方法,它给出了一个名为targetNodeName的目标节点的所有父节点的列表(输出列表也应该包含targetNodeName本身)。为此,我编写了一个递归函数,迭代直到找到没有父节点的节点(即根节点),同时构建一个名为results的列表。

def allParents(self, targetNodeName, results):
    currentNode = next((node for node in self.nodes if node.name == targetNodeName))
    results.append(currentNode.name)
    if (currentNode.parent == None):
        print results
        return results
    else:
        return results.append(self.allParents(currentNode.parent, results))

但是我的递归函数没有按预期执行。我举一个例子,我首先定义一个三级,7节点的树,然后调用allParents方法获取节点的所有父节点' N7'即[' N7',' N3',' N1']。

# create nodes
myTreeNodes = []
myTreeNodes.append(TreeNode(name = 'N1', parent = None))
myTreeNodes.append(TreeNode(name = 'N2', parent = 'N1'))
myTreeNodes.append(TreeNode(name = 'N3', parent = 'N1'))
myTreeNodes.append(TreeNode(name = 'N4', parent = 'N2'))
myTreeNodes.append(TreeNode(name = 'N5', parent = 'N2'))
myTreeNodes.append(TreeNode(name = 'N6', parent = 'N3'))
myTreeNodes.append(TreeNode(name = 'N7', parent = 'N3'))

myTree = Tree(name = 'ST1', nodes = myTreeNodes)

a = myTree.allParents(targetNodeName = 'N7', results = [])
print a

> ['N7', 'N3', 'N1']
> None

虽然它打印出正确的父节点列表 - 注意' debug'在函数中打印命令 - (即[' N7',' N3',' N1']),该函数返回None,这意味着我被删除了没有任何回报的功能。我该如何解决这个问题?

2 个答案:

答案 0 :(得分:1)

使用debugger逐步执行该方法对于计算代码所采用的路径非常有用。

使用这个我可以看到该方法最初遵循else分支,它只是对self.allParents的子调用导致print语句。问题在于results.append,它始终返回None而不是列表。

a = []
b = a.append(3)
assert a == [3]
assert b is None

最简单的解决方案是将该行拆分为原始results.append,然后是return results

答案 1 :(得分:1)

使用 来检查值是否等于None。 allParents 方法可简化如下:

def allParents(self, targetNodeName):
    currentNode = next(node for node in self.nodes
                       if node.name == targetNodeName)
    if currentNode.parent is None:
        return [currentNode.name]
    else:
        return [currentNode.name] + self.allParents(currentNode.parent)