【问题标题】:How to search a tree with three children nodes?如何搜索具有三个子节点的树?
【发布时间】:2015-04-09 15:39:11
【问题描述】:

我的树节点有 3 个字符串字段和 3 个节点字段,分别是左、中和右。

其中一个问题是该方法只能以字符串为参数

这就是我所拥有的

public TreeNode findNode(String name) {
    TreeNode pointer = this.getRoot();

    if (pointer.getName().equals(name))
        return pointer;
    if (pointer.getLeft() != null)
        pointer = pointer.getLeft();
    findNode(name);
    if (pointer.getMiddle() != null)
        pointer = pointer.getMiddle();
    findNode(name);
    if (pointer.getRight() != null)
        pointer = pointer.getRight();
    findNode(name);
    return null;

}

这会导致堆栈溢出错误,因为我只是将指针设置为根。但我必须从某个地方开始,该方法的唯一参数可以是名称。我似乎无法看到如何做到这一点。

【问题讨论】:

  • 难道你的方法体应该有更多的返回语句?你看,你递归地调用你的 find 方法;然后忽略它的结果;并且总是返回null?顺便说一句:你想把 { } 放在任何块周围(所以,总是对 if/then/else、for 循环、while 循环等执行此操作)。
  • 好吧,如果我找到同名的节点,我会返回指针。这还不够吗?
  • 再次:如果您的递归调用之一“找到”正确的节点并返回它;该递归调用的结果是未使用。含义:在一个地方返回值无济于事;当你忽略上一层返回的结果时!

标签: java search tree children


【解决方案1】:

您可以使用列表作为参数堆栈。

public TreeNode findNode(String name) {
    List<TreeNode> stack = new ArrayList<TreeNode>();
    stack.add(this.getRoot());
    while (!stack.isEmpty())
    {
        TreeNode node = stack.remove(0);
        if (node.getName().equals(name))
            return node;
        if (pointer.getLeft() != null)
            stack.add(node.getLeft());
        if (node.getMiddle() != null)
            stack.add(node.getMiddle());
        if (node.getRight() != null)
            stack.add(node.getRight());
    }
    return null;
}

如果你想深度优先搜索,你可以从列表的末尾而不是列表的前面删除。

【讨论】:

  • 我不能使用任何 Java API 数据结构类。只有数组
  • 如果存在最大树深度,那么您可以使用数组和数组索引以类似的方式遍历树。使用“列表”只是让这更容易。不过,这将要求您深度优先,否则您将超出界限。
【解决方案2】:

我猜你不能改变这个函数的签名。有一个辅助函数,它接受两个参数(节点和名称),您使用根和名称调用它们。

【讨论】:

    【解决方案3】:

    在所有三种情况下(左、中、右),您都在调用findNode(name),但不是针对这些对象,而是针对this。这就是您得到堆栈溢出的原因。

    【讨论】:

      【解决方案4】:

      使用一种辅助方法,除了字符串之外还接受TreeNode 参数:

      public TreeNode findNode(String name) {
          return auxFindNode(this.getRoot(), name);
      }
      
      private TreeNode auxFindNode(TreeNode node, String name) {
          //perform your recursive traversal here
      }
      

      您的代码将永远无法工作,因为您在方法的开头一直将pointer 设置为树的根。所以你所有的递归调用都是从树的根开始的。

      如果您不想使用其他方法,可以使用堆栈迭代遍历树:

      public TreeNode findNode(String name) {
          Stack<TreeNode> stack = new Stack<TreeNode>();
          TreeNode foundNode = null;
      
      
          while(!stack.empty() && foundNode == null) {
              TreeNode node = stack.pop();
      
              if(node.getName().equals(name)) {
                  foundNode = node;
              } else {
                  if(node.getLeft() != null) {
                      stack.push(node.getLeft();
                  }
      
                  if(node.getMiddle() != null) {
                      stack.push(node.getMiddle());
                  }
      
                  if(node.getRight() != null) {
                      stack.push(node.getRight());
                  }
              }            
          }
      
          return foundNode;
      } 
      

      【讨论】:

        猜你喜欢
        • 2012-01-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多