我有这个代码迭代一棵树,进行深度优先搜索。每个元素都只处理一次。很好。
-(void)iterateOverTree:(TreeNode *)node
{
NSMutableArray * elements = [NSMutableArray array];
[elements addObject:node];
while([elements count])
{
TreeNode * current = [elements objectAtIndex:0];
[self doStuffWithNode:current];
for(TreeNode * child in current.children)
{
[elements addObject:child];
}
[elements removeLastObject];
}
}
但是:如何跟踪图表中的当前深度?我需要知道深度。例如,我有这些节点:
A有孩子B,J。 B有孩子C. C有孩子D. D有孩子E,F,I。
当A处于深度级别1时,则B为2且C为3。
通过递归,可以很容易地跟踪当前的深度级别。只是在调用自身之前修改变量并在调用自身之后减少它。
但是这里有这种花哨的while循环是不可能的。框中的框中没有框,就像递归一样。
我真的不想将属性(或实例变量)添加到TreeNode对象,因为对于任何类型的对象图,它都应该以通用方式重用。
有谁知道如何做到这一点?我必须引入另一个数组来跟踪访问过的节点吗?
答案 0 :(得分:1)
我不理解你的符号,但如果我读得正确,你就会处理一个节点并将所有孩子添加到你要做的工作列表中。
如果您可以将该部分更改为使用递归,则可以跟踪树深度,因为它将是递归深度。
因此,不是添加子节点,而是递归每个子节点。
HTH
马里奥
答案 1 :(得分:1)
我认为你确实需要叠加深度。如果你有一个递归版本,这就是你实际上要做的事情。这只是存储将是“不可见的”,因为您将使用调用堆栈而不是像现在这样使用显式堆栈。
如果它对您有帮助,您可以通过将数组用作队列而不是堆栈,轻松地将深度优先搜索转换为广度优先搜索。 (只需执行removeFirstObject而不是removeLastObject。)然后你会知道你总是按照不减少深度的顺序查看节点。但是,如果您需要精确的深度,我认为您仍然需要添加一些存储空间来跟踪何时必须增加当前深度。
更新
你应该能够在没有堆栈的情况下完成DFS,相反,你可以按照节点的父指针来备份树。这将使维持深度变得简单。但是你必须要小心,不要通过重新扫描孩子来找出你所处的位置来打破线性时间最坏情况的复杂性。
如果您没有父指针,则应该可以堆叠足够的信息来跟踪父项。但是这意味着你在堆栈上放置的信息比你现在做的要多,所以与直接堆叠深度相比,这并没有太大的改进。
顺便说一句,仔细查看你的算法,当你得到下一个当前节点时,你不是在看数组的错误一面吗?它应该像这样工作:
push root
while stack not empty:
current = pop
push all children of current
答案 2 :(得分:1)
我相信你所做的实际上是BFS。您正在使用列表。要做DFS,你应该使用堆栈;
This可能对深度轨道很有用,你可以查看矢量p(父母)
答案 3 :(得分:-1)
假设您正在进行BFS,最简单的方法是引入另一个深度镜像节点队列队列。将深度初始化为零。每次推送到节点队列时,将当前深度+ 1推送到深度队列。