我不是程序员,但我目前正在使用Python中的二叉树进行实验,而我想要创建一个很好的方法来逐级打印二叉树;目前我已经实现了一个广度优先方法,从根开始打印每个级别 - 工作正常,但对广泛接受的递归解决方案感兴趣。
如果我要使用递归方法,那不能简单地模拟迭代广度优先方法 - 我是否可以使用深度优先迭代深化解决方案?
我知道深度优先迭代加深被用作一种有效的搜索方法,它可以用来给我一张水平打印我的树吗?或者,这里接受的解决方案只是保留我的广度优先方法?
这是我的树类的代码,实例化创建了Fibonacci函数递归调用的树结构;我修改了这个,以便将级别保存到每个Node
:
from collections import deque
class FibTree(object):
"""Class which builds binary tree from Fibonacci function call graph"""
def __init__(self, n, parent, level=None):
if level is None:
level = 0
self.n = n
self.parent = parent
self.level = level
if n < 2:
self.left = None
self.right = None
self.value = n
else:
self.left = FibTree(n - 1, self, level + 1)
self.right = FibTree(n - 2, self, level + 1)
self.value = self.left.value + self.right.value
实现了迭代广度优先遍历方法:
def level_order_breadth_first_traversal(self):
"""Level order Breadth First Traversal, returning nodes by level"""
this_level = deque([self])
while this_level:
next_level = deque()
yield this_level
while this_level:
u = this_level.popleft()
if u.left is not None:
next_level.extend([u.left])
if u.right is not None:
next_level.extend([u.right])
this_level = next_level
我现在可以以任何方式利用我的广度优先遍历中每个Level
中存储的Node
订单来打印我的二叉树,或者我是否必须进行某种遍历不管我是否已将级别顺序存储到节点中。
编辑:要显示我的Iteratve Deepening Depth级别遍历,尝试按级别顺序打印出我的二叉树:
def _getChildren(self,node):
"""Method to expand node"""
hasLeft = node.left is not None
hasRight = node.right is not None
if hasLeft:
yield node.left
if hasRight:
yield node.right
def dls(self, node, depth):
"""Depth Limited Search"""
if (depth == 0):
return node
elif (depth > 0):
print "(" + repr(node.i) + ")" + repr(node.value),
children = self._getChildren(node)
for child in children:
self.dls(child, depth-1)
else:
return False
def iterative_deepening(self):
"""Iterative Deepening to print out binary tree level order"""
depth = 0
while True:
result = self.dls(self, depth)
if result is not False:
return result
depth += 1
调用iterative_deepening
方法时,只返回root
节点,而不是按级别顺序返回节点列表。
由于 亚历
答案 0 :(得分:1)
是的,迭代加深深度优先搜索为您提供逐层的树,即与广度优先搜索完全相同的顺序(如果以相同的顺序展开节点,例如先左,然后右)
请注意,递归不被认为是非常Pythonic,因此使用显式堆栈的解决方案可能更可取。 Python也limits recursion depth,默认为1000
,因此请注意非常深的树结构。
答案 1 :(得分:1)
您可以使用遍历来完成任务。
如果您已经有非递归解决方案,请坚持下去!记忆力更好。虽然BFS将所有节点都保存在内存中,但内存很重(O(分支^深度))。
使用内存较轻的DFS(O(分支*深度)),您可以在遍历节点时标记Node类本身中节点的级别。您还可以保留map<level, List<Node>>
,其中level是int。
如果你的树太大而你不想一直走,那么使用迭代DFS是个好主意。
答案 2 :(得分:0)
我在图表上使用过BFS / DFS。请考虑以下图表
v1-------------> v2- | | - | | - | | - |> |> - > v4------------> v3----------> v6 - | - | - | - |> -------- > v5
在BFS 中,您首先访问起始顶点v1。在访问起始顶点之后,您将访问与起始顶点相邻的顶点。
Let us start with vertex v1.
Traverse v1.
Vertices(unvisited) adjacent to v1 are v2, v4.
Traverse v2, v4.
Vertices(unvisited) adjacent to v2 are v3, v6.
Traverse v3, v6.
Vertices(unvisited) adjacent to v4 are v5.
Traverse v5.
Vertices(unvisited) adjacent to v3 is nill.
Vertices(unvisited) adjacent to v6 is nill.
Vertices(unvisited) adjacent to v5 is nill. End.
使用队列实施。
Algorithm: BFS(v)
1. Visit the starting vertex, v and insert it into the queue.
2. Repeat step 3 until the queue becomes empty.
3. Delete the front element from the queue. Visit all it's unvisited adjacent vertices and insert them into the queue.
If the graph is not connected then it's not possible to traverse the whole graph from a single vertex.
So we need to execute the preceding algorithm repeatedly for all unvisited vertices in the graph.
1. Repeat step 2 for each vertex, v in the graph
2. If v is not visited:
a. Call BFS(v)
Queue representation Vertices visited
--------------------------------------------------------
v1 v1
--------------------------------------------------------
v2 v4 v1, v2, v4
--------------------------------------------------------
v4 v3 v6 v1, v2, v4, v3, v6
--------------------------------------------------------
v3 v6 v5 v1, v2, v4, v3, v6, v5
--------------------------------------------------------
v6 v5 v1, v2, v4, v3, v6, v5
--------------------------------------------------------
v5 v1, v2, v4, v3, v6, v5
--------------------------------------------------------
empty v1, v2, v4, v3, v6, v5
--------------------------------------------------------
在DFS 中,您可以从任何verterx v作为起始顶点开始遍历。 遍历起始顶点后,您将遍历与起始顶点相邻的任何一个顶点。接下来,您沿着与最后访问的顶点相邻的任何一个顶点进行遍历。此过程将继续,直到您到达没有未访问的相邻顶点的顶点。此时,您需要回溯到具有未访问的相邻顶点的最后访问的顶点,并从那里启动DFS。
Let us first traverse v1.
Vertices adjacent to v1 which are unvisited are v2 and v4. Let us choose v2.
Traverse v2.
Vertices adjacent to v2 which are unvisited are v3 and v6. Let us choose v3.
Traverse v3.
Vertices adjacent to v3 which are unvisited are v6 and v5. Let us choose v5.
Traverse v5.
Vertices adjacent to v5 which are unvisited are nill. So backtrack.
Vertices adjacent to v3 which are unvisited is v6. Choose v6.
Traverse v6.
Vertices adjacent to v6 which are unvisited are nill. So backtrack.
Vertices adjacent to v3 which are unvisited are nill. So backtrack.
Vertices adjacent to v2 which are unvisited are nill. So backtrack.
Vertices adjacent to v1 which are unvisited v4. Choose v4.
Traverse v4.
Vertices adjacent to v4 which are unvisited are nill. So backtrack.
Vertices adjacent to v1 which are unvisited are nill. End.
使用堆栈
实施Algorithm: DFS(v)
1. Push the starting vertex, v into the stack
2. Repeat until the stack becomes empty.
a. Pop a vertex from stack.
b. Visit the popped vertex.
c. Push all the unvisited vertices adjacent to the popped vertex into the stack.
If the graph is not connected then its not possible to traverse the whole graph from a single vertex.
So we need to execute the preceding algorithm repeatedly for all unvisited vertices in the graph.
1. Repeat step 2 for each vertex, v in the graph
2. If v is not visited:
a. Call DFS(v)
Stack representation Vertices visited
--------------------------------------------------------
v1
--------------------------------------------------------
v2 v1
v4
--------------------------------------------------------
v3 v1, v2
v6
v4
--------------------------------------------------------
v5 v1, v2, v3
v6
v4
--------------------------------------------------------
v6 v1, v2, v3, v5
v4
--------------------------------------------------------
v4 v1, v2, v3, v5, v6
--------------------------------------------------------
empty v1, v2, v3, v5, v6, v4
--------------------------------------------------------