我写了一个递归获取树深度的算法。作为函数定义,它可以工作:
def tree_depth_f(tree):
"""Counts the maximum depth of a tree."""
def recursive_count(node):
"""Recursive count function."""
childs = tree[node]
if childs == None:
return 0
else:
maxh = 0
for i in xrange(len(childs)):
h = recursive_count(childs[i])
if maxh < h:
maxh = h
return int(1 + maxh)
root = tree['root']
depth = recursive_count(root)
return depth
但是与方法定义相同的算法不起作用:
class MyClass:
def __init__():
pass
def tree_depth(self, tree):
"""Counts the maximum depth of a tree."""
def recursive_count(node):
"""Recursive count function."""
self.childs = tree[node]
if self.childs == None:
return 0
else:
self.maxh = 0
for i in xrange(len(self.childs)):
self.h = recursive_count(self.childs[i])
if self.maxh < self.h:
self.maxh = self.h
return int(1 + self.maxh)
self.root = tree['root']
self.depth = recursive_count(self.root)
return self.depth
tree
是列表字典。这就是我测试这些代码的方式:
tree = {0: [1], 1: [2], 2: [3, 4], 3: None, 4: None, 'root': 0}
m = MyClass()
print "As a function:", tree_depth_f(tree)
print "As a method:", m.tree_depth(tree)
以下是此示例中tree
的图形表示:
函数定义工作正常,但是当我使用方法定义时,我收到以下错误:
TypeError: 'NoneType' object has no attribute '__getitem__'
at Answer.py. in recursive_count on line 102
at Answer.py. in recursive_count on line 102
at Answer.py. in recursive_count on line 102
at Answer.py. in tree_depth on line 108
at Answer.py. in <module> on line 157
原始代码中的第102,108和157行指向:
102: self.h = recursive_count(self.childs[i])
108: self.depth = recursive_count(self.root)
157: print "As a method:", m.tree_depth(tree)
经过大量调试后,我发现当方法定义找到一个叶子(self.childs
为None
的一个节点)并开始从递归返回时,self.childs
父节点也是None
。我不知道为什么。功能定义工作正常。你能帮助我吗?
答案 0 :(得分:1)
您正在修改self.childs
,它在这里有效地充当全局变量(因为它记录在对象上,它通过对递归函数的不同调用持续存在)。每个节点没有一个对象,你有一个对象,句点。因此,在self.childs
上没有“{1}}父母节点”,您只有一个self.childs
。当递归从self
分支退出时,变量return 0
为self.childs
。
在您的功能代码中,您的None
是一个局部变量,因此每个函数调用都会获得一个单独的副本;无论是在方法还是在函数上,你真的需要它。
只需删除childs
,self.
就不需要成为实例变量。实际上,由于您没有使用任何面向对象的功能,因此不需要任何变量作为实例变量。