我有一个遍历树的函数,并将元素作为列表返回。有没有办法简化treeToList::traverse
中的所有if语句,因为它看起来有点多余?
#!/usr/bin/python
def enum(**enums):
return type('Enum', (), enums)
Order = enum(PREORDER=0, INORDER=1, POSTORDER=2)
def treeToList(root, order=Order.INORDER):
ret = list()
def traverse(node, order):
if order == Order.PREORDER: ret.append(node.data)
if node.right != None: traverse(node.right, order)
if order == Order.INORDER: ret.append(node.data)
if node.down != None: traverse(node.down, order)
if order == Order.POSTORDER: ret.append(node.data)
traverse(root, order)
return ret
class node:
def __init__(self, data=None):
self.data = data
self.down = None
self.right = None
if __name__ == '__main__':
root = node('F')
root.right = node('B')
root.down = node('G')
root.right.right = node('A')
root.right.down = node('D')
root.down.down = node('I')
root.right.down.right = node('C')
root.right.down.down = node('E')
root.down.down.right = node('H')
print treeToList(root, Order.PREORDER)
print treeToList(root, Order.INORDER)
print treeToList(root, Order.POSTORDER)
输出
['F', 'B', 'A', 'D', 'C', 'E', 'G', 'I', 'H']
['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I']
['A', 'C', 'E', 'D', 'B', 'H', 'I', 'G', 'F']
答案 0 :(得分:5)
好吧,如果你摆脱了封闭......纯粹的功能可能更清晰:
def treeToList(node, order=Order.INORDER):
if node is None:
return []
right = treeToList(node.right, order)
down = treeToList(node.down, order)
current = [node.data]
if order == Order.PREORDER:
return current + right + down
if order == Order.INORDER:
return right + current + down
if order == Order.POSTORDER:
return right + down + current
但当然会建立很多中间列表。
答案 1 :(得分:2)
我唯一想到的是:
def treeToList(root, order=Order.INORDER):
ret = list()
def inorder_traversal(node):
if node is not None:
inorder_traversal(node.right)
ret.append(node.data)
inorder_traversal(node.down)
def preorder_traversal(node):
if node is not None:
ret.append(node.data)
preorder_traversal(node.right)
preorder_traversal(node.down)
def postorder_traversal(node):
if node is not None:
postorder_traversal(node.right)
postorder_traversal(node.down)
ret.append(node.data)
if order == Order.PREORDER:
preorder_traversal(node)
elif order == Order.INORDER:
inorder_traversal(node)
else:
postorder_traversal(node)
return ret
答案 2 :(得分:2)
我不认为在不重新组织算法的情况下消除三个if order
语句是一种好方法。 ret.append
发生的位置取决于值,因此您几乎必须以这种或那种方式对其进行三次检查。
但是有一种显而易见的方法可以重组事物以删除一对if
:
def traverse(node, order):
if node is None: return
if order == Order.PREORDER: ret.append(node.data)
traverse(node.right, order)
if order == Order.INORDER: ret.append(node.data)
traverse(node.down, order)
if order == Order.POSTORDER: ret.append(node.data)
当然它只有一行,但它只有4 if
而不是6。
另一种可能性是改变事物以跟踪所有三个位置,并在事后插入适当的位置:
def traverse(node, order):
if node is None: return
prepos = len(ret)
traverse(node.right, order)
inpos = len(ret)
traverse(node.down, order)
postpos = len(ret)
pos = (prepos, inpos, postpos)[order]
ret[pos:pos+1] = node.data
这会删除所有if
,但我不认为结果更容易阅读或理解......
真的,让这个更易于阅读和理解的方法可能是转换为功能算法(递归可变算法很难通过考虑)......但这只会使三个if
体更大,不要摆脱他们。
答案 3 :(得分:0)
尝试类似
if order in (Order.PREORDER, Order.INORDER, ...):
ret.append(node.data)
击> <击> 撞击> 挑剔
你应该有多条线的条件
if cond:
pass
而不是
if cond: pass
在与is
而不是is not
和None
进行比较时,还要考虑使用==
和!=
。