给定二进制搜索树,例如:
9
8
7
5
3
2
我想获取一个具有a和b之间值的节点列表(包含在内)。
我已经实现了递归辅助功能:
def _range(root, a, b):
node_list = []
if root.left:
node_list.append(_range(root.left, a, b))
if root.value >= a and root.value <= b:
node_list.append(root)
if root.right:
node_list.append(_range(root.right, a, b))
return node_list
给我:
[[[BTNode: 2], BTNode: 3], BTNode: 5, [BTNode: 7, [[BTNode: 8], BTNode: 9]]]
我需要:
[BTNode: 2, BTNode: 3, BTNode: 5, BTNode: 7, BTNode: 8, BTNode: 9]
无论如何是否有弄平列表?我意识到我正在做的是将列表附加到另一个列表中,但是不确定如何在不破坏代码的情况下解决此问题。
append
将作为参数传递的对象添加到列表中,因此您显然会添加嵌套列表。您想加入结果,因此要使用list.extend
(或+=
操作员):
>>> from collections import namedtuple
>>> class Node(namedtuple('Node', 'value left right')):
... # I reimplement __str__ just to avoid too much output later
... def __repr__(self):
... return 'Node(%r)' % self.value
... __str__ = __repr__
...
>>> def make_node(value, left=None, right=None):
... return Node(value, left, right)
...
>>> def _range(root, a, b):
... node_list = []
... if root.left:
... node_list.extend(_range(root.left, a, b))
... if a <= root.value <= b:
... node_list.append(root)
... if root.right:
... node_list.extend(_range(root.right, a, b))
... return node_list
...
>>> tree = make_node(5, make_node(3, make_node(2)), make_node(7, None, make_node(8, None, make_node(9))))
>>> _range(tree, 1, 3)
[Node(2), Node(3)]
>>> _range(tree, 1, 10)
[Node(2), Node(3), Node(5), Node(7), Node(8), Node(9)]
另一种做法是将列表作为参数传递:
>>> def _range(root, a, b, node_list=None):
... if node_list is None:
... # Note: do *not* use "[]" as a default!
... node_list = []
... if root.left:
... _range(root.left, a, b, node_list)
... if a <= root.value <= b:
... node_list.append(root)
... if root.right:
... _range(root.right, a, b, node_list)
... return node_list
...
>>> _range(tree, 1, 3)
[Node(2), Node(3)]
>>> _range(tree, 1, 10)
[Node(2), Node(3), Node(5), Node(7), Node(8), Node(9)]