如何将以下递归函数walk()
转换为迭代函数?
迭代地以相同的顺序遍历节点很容易使用堆栈,但是我无法弄清楚如何编写迭代函数,它将打印每个节点的开始和结束标记,就像递归版本一样。 / p>
代码:
class Node(object):
def __init__(self, name, children=[]):
self.name = name
self.children = children
def walk(node):
print('<', node.name, '>', sep='')
for n in node.children:
walk(n)
print('</', node.name, '>', sep='')
root = \
Node('html', [
Node('head'),
Node('body', [
Node('div'),
Node('p', [
Node('a'),
])
]),
])
walk(root)
输出:
<html>
<head>
</head>
<body>
<div>
</div>
<p>
<a>
</a>
</p>
</body>
</html>
迭代遍历树的代码:
该函数以正确的顺序访问节点,但显然不会打印结束标记。
def walk(node):
stack = []
stack.append(node)
while len(stack) > 0:
node = stack.pop()
for child in reversed(node.children):
stack.append(child)
print(node.name)
答案 0 :(得分:0)
问题是,为了使其工作,您还需要在节点结束的堆栈上进行记录。可能的解决方案是:
lst <- mget(ls(pattern = "\\.value$"))
names(lst) <- sub("\\.value$", "", names(lst))
我已经添加了缩进功能,因此输出效果更好:
def walk(root):
stack = []
stack.append(root)
indent = 0
while stack:
node = stack.pop()
if isinstance(node, Node):
print(' ' * indent, "<", node.name, ">", sep="")
indent += 1
stack.append(node.name)
stack.extend(reversed(node.children))
else:
indent -= 1
print(' ' * indent, "</", node, ">", sep="")
答案 1 :(得分:0)
有点post-order tree treversal ,因为你必须在访问子节点后访问父节点。
我修改了几行现有代码:
class Node(object):
def __init__(self, name, children=[]):
self.name = name
self.children = children
# def walk(node):
# print('<', node.name, '>', sep='')
# for n in node.children:
# walk(n)
# print('</', node.name, '>', sep='')
def walk(node):
stack = []
stack.append((node, 'start'))
while len(stack) > 0:
node, status = stack.pop()
if status == 'start':
stack.append((node, 'end'))
for child in reversed(node.children):
stack.append((child, 'start'))
print('<', node.name, '>', sep='')
else: # status == 'end'
print('</', node.name, '>', sep='')
root = \
Node('html', [
Node('head'),
Node('body', [
Node('div'),
Node('p', [
Node('a'),
])
]),
])
walk(root)