BST算法中的StackOverFlowException

时间:2011-08-10 03:42:14

标签: c# algorithm exception tree binary-search-tree

我一直在尝试在我的BSTree类中实现一个Contains方法,该方法将接受一个值,然后检查所有节点以查看它是否包含在树中。我认为算法是正确的,但我不知道为什么我在第一个if语句中继续得到StackOverFlowException。有什么想法吗?

public Boolean Contains(T item)
    {
      Node<T> node = root;
      return contains(root, item);
    }



    private Boolean contains(Node<T> node, T item)
    {
      if (item.CompareTo(root.Data) == 0)
      {
        return true;//return 0 if found
      }
      else
      {
        if (item.CompareTo(root.Data) > 0)
        {
          //root = node.Left;
          Node<T> left = root.Left;
          return(contains(root, item));
        }
        else
        {
          if (item.CompareTo(root.Data) < 0)
          {
            //root = node.Right;
            Node<T> right = root.Right;
            return(contains(root, item));
          }
          else
          {
            return false;//return 1 if not found
          }
        }        
      }
    }

3 个答案:

答案 0 :(得分:3)

您的代码存在的问题是您将错误的节点传递给递归调用。例如,假设您的元素小于树中的所有元素。然后在第一次递归调用中,您将点击此声明:

Node<T> left = root.Left;
return(contains(root, item));

这意味着你递归 root ,而不是左子。因此,在下一次迭代中,您将发现该元素小于根的右子元素,因此您将再次执行完全相同的语句,重复地递归调用相同的函数,直到用完堆栈空间。 / p>

要解决此问题,您应该将上述代码更改为

Node<T> left = node.Left;
return(contains(left, item));

这表示查看当前节点的左子树,而不是根节点本身。同样,您需要更新正确分支的相应案例。

最后,要完成此操作,您需要在递归函数中添加一个基本案例,以处理树为null的情况,因为您已离开树或树是空开始。我会留下这个练习。 : - )

答案 1 :(得分:0)

你的逻辑不正确。它不会返回虚假陈述。

private Boolean contains(Node<T> node, T item)
    {
      if (item.CompareTo(root.Data) == 0)
      {
        return true;//return 0 if found
      }
      else///if 0 <> 
      {
        if (item.CompareTo(root.Data) > 0)  //if 0<
        {
          //root = node.Left;
          Node<T> left = root.Left;
          return(contains(root, item));
        }
        else  //if 0>
        {
          if (item.CompareTo(root.Data) < 0) if // 0>
          {
            //root = node.Right;
            Node<T> right = root.Right;
            return(contains(root, item));
          }
          else  // this will be not executed ever
          {
            return false;//return 1 if not found
          }
        }        
      }
    }

答案 2 :(得分:0)

你不需要递归。您可以进行迭代,这样即使您拥有一棵大树,也不会产生StackOverflow。

public Boolean Contains(T item) {
    Node<T> currentNode = root;

    while(currentNode != null) { // Or whatever you use to signal that there is no node.
        switch(item.CompareTo(currentNode.Data)) {
            case -1:
                currentNode = currentNode.Right;
                break;
            case 1:
                currentNode = currentNode.Left;
                break;
            default: // case 0
                return true;
        }
    }
    return false;
 }