我有这个代码迭代一棵树,进行深度优先搜索.每个元素都只处理一次.很好.
-(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对象,因为对于任何类型的对象图,它都应该以通用方式重用.
有谁知道如何做到这一点?我必须引入另一个数组来跟踪被访问的节点吗?
最佳答案 我认为你确实需要叠加深度.如果你有一个递归版本,这就是你实际上要做的事情.这只是存储将是“不可见的”,因为您将使用调用堆栈而不是像现在这样使用显式堆栈.
如果它对您有帮助,您可以通过将数组用作队列而不是堆栈,轻松地将深度优先搜索转换为广度优先搜索. (只需执行removeFirstObject而不是removeLastObject.)然后你会知道你总是按照不减少深度的顺序查看节点.但是,如果您需要精确的深度,我认为您仍需要添加一些存储空间来跟踪何时必须增加当前深度.
更新:
您应该能够在没有堆栈的情况下完成DFS,如果您遵循节点的父指针来备份树.这将使维持深度变得简单.但是你必须要小心,不要通过重新扫描孩子来找出你的位置来打破线性时间最坏情况的复杂性.
如果您没有父指针,则应该可以堆叠足够的信息来跟踪父项.但是这意味着你在堆栈上放置的信息比你现在做的要多,所以直接堆叠深度并没有太大的改进.
顺便说一句,仔细查看你的算法,当你得到下一个当前节点时,你不是在看数组的错误方面吗?它应该像这样工作:
push root
while stack not empty:
current = pop
push all children of current