我一直在尝试在我的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
}
}
}
}
答案 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;
}