【问题标题】:DFS tree traversal function modificationDFS树遍历函数修改
【发布时间】:2012-03-07 23:33:57
【问题描述】:

请在下面找到我的 DFS 实现。

protected void DFS(String search) {
    for(Tree<T> child : leafs) {
        if(child.value.equals(search))
            return;
        else 
            child.DFS(search);            
        System.out.println(child.value);     
    }
}

目标是在找到其值在变量搜索中的节点时停止遍历。然而,上面的函数继续遍历树,甚至超出了声明的搜索节点。有人可以帮我修改上述功能吗?

谢谢。


编辑 1

protected boolean DFS(String anaphorKey) {
    boolean found = false;
    for(Tree<T> child : leafs) {
        if(child.head.equals(anaphorKey))
            return true;
        found = child.DFS(anaphorKey);
        if(found == true)
            break;            
        System.out.println(child.head);     
        //System.out.println("anaphorKey: "+anaphorKey);
    }
    return found;
}

尝试实施给定的答案建议 (@SJuan76)。上面的实现没有按预期工作。您能否指出代码与建议的逻辑不符的地方?

【问题讨论】:

    标签: java tree traversal depth-first-search


    【解决方案1】:

    菜鸟,我是否可以建议使用经典的 for 循环(而不是现在使用的增强型 for 循环)的实现,它可以更好地集成您的停止条件,例如:

    protected boolean DFS(String key) {
        boolean found = false;
    
        for(int i = 0; i < leafs.size() && !found; i++) {
            Tree<T> child = leafs.get(i);
    
            if(child.head.equals(key))
                found = true;
            else
                found = child.DFS(key);
        }
    
        return found;
    }
    

    因此,一旦您的 found 条件被满足,“found”就变为 true,并且您的循环停止。

    您可能忘记的是递归的“found = child.DFS(key)”部分,您需要记住递归调用的结果,这样链上的所有 for 循环都会立即中断当你回来时。

    希望对您有所帮助。

    【讨论】:

    • 感谢您的回复。我将您的功能插入到我的程序中,但它仍然无法正常工作。根据逻辑,它显然应该。控件没有进入 if(child.head.equals(key)) 条件。关键肯定在树上。会不会是投射错误?
    • 已解决!是的,Generic 和 String 之间需要一个强制转换语句。
    • 注意:Riyad 指出的技巧是,如果找到正确的节点,循环必须检查每次迭代!
    【解决方案2】:

    选项A(Nice):该函数返回一个值,当找到节点时,它返回与未找到节点时不同的值。当你调用方法时,如果你得到 found 值,你会停止循环并返回 found 值。

    选项B(丑陋):找到后,抛出异常(如果是您自己的实现更好)。别忘了抓住它。

    选项 C(丑陋):与全局(静态)变量相同。

    更新1:

    看起来您的方法现在应该可以正常运行了,您能否检查 (System.out.println) 是否找到了您的值?

    我个人认为,

    protected boolean DFS(String anaphorKey) { 
      for(Tree<T> child : leafs) { 
        if(child.head.equals(anaphorKey)) 
          return true; 
        if(child.DFS(anaphorKey))  // No need to store value. No need to check == true (it is implicit)
          return true;             // If we are in this line the value was found, always return true
        System.out.println(child.head);      
        //System.out.println("anaphorKey: "+anaphorKey); 
      } 
      return false;  // If the method did not exit previously it was because the value was not found, so in this line always return false
    } 
    

    更具可读性(但它应该与您的实现完全一样)

    【讨论】:

    • 请参见上面的Edit1;需要指导。
    • 是的,当找到节点时它会停止搜索。 [Riyad] 提供的建议也确实从找到的节点通过父节点进行追溯;我根据对您的建议的理解实施的那个不会追溯到搜索节点的父节点。
    猜你喜欢
    • 2020-04-01
    • 2015-03-02
    • 1970-01-01
    • 2011-10-17
    • 1970-01-01
    • 2013-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多