由于堆栈(使用push和pop),我在树中使用了回溯算法。 它有效,但我有一个问题。堆栈给出的路径是“错误的”。
bool Prefix(Node*root, stack *tas, char *search)
{
if (!isEmpty(root))
{
if (strcmp(search,root->data) != 0)
push(tas, root->data, search, root);
if (strcmp(search,root->data) == 0)
{
return True ;
}
Prefix(root->left, tas, search);
Prefix(root->right, tas, search);
}
return False;
}
例如,我有一棵树:
Root
/ \
A B
/ \ / \
C D E F
当我想要C的路径时,此函数返回R A B(对于R和A,而不是B,则为ok)。
我不知道它是来自这个函数还是push()函数。 如果你没有在函数中看到任何错误,我会粘贴push(),但它很长。
编辑:我现在好好理解, 我已添加到功能中:edit2:
这是代码:(返回R A B F而不是R B F)
bool Prefix(Node*root, stack *tas, char *search)
{
if (!isEmpty(root))
{
if (strcmp(search,root->data) == 0)
return True ;
if (LeafOrNot(root) == True ){ //it's a leaf, pop()
pop(tas);
if (Prefix(root->left, tas, search))
return True;
if (Prefix(root->right, tas, search))
return True;
}
return False;
}
我不明白如何弹出遍历子节点以获得良好的结果,可能是添加 否则为if(前缀(root-> left,tas,search))?有人有想法吗?
谢谢!
答案 0 :(得分:3)
至少有一个问题是你没有检查调用Prefix
的返回值,所以你不知道递归调用是否“完成”(并且你应该停止探索)。 / p>
看到这个的简单方法就是遍历函数调用(给定样本树):
Prefix("Root") found "C"? no: Prefix("A") found "C"? no: Prefix("C") found "C"? yes: return true (without check of Prefix("C")): Prefix("D") found "C"? no: return false Prefix("B") found "C"? no: Prefix("E") found "C"? no: return false Prefix("F") found "C"? no: return false return false return false
这表示调用和缩进的顺序粗略地与调用堆栈上的帧相对应。
您可以查看检查Prefix
的回复true
是否允许您在适当的时间退出。
答案 1 :(得分:2)
我必须同意@Mark Elliot,但乍一看,他的回答似乎令人困惑。您确实需要一个停止条件,因此您不会继续探索其他节点并将它们添加到堆栈中。您正在返回一个bool,以便您可以使用它来测试调用是否找到您要查找的节点。
如果您打算将最后一个节点包含在堆栈中C的路径中,那么您应该在添加到堆栈时删除字符串比较。
例如,你可以这样做。
bool Prefix(Node*root, stack *tas, char *search)
{
if (!isEmpty(root))
{
push(tas, root->data, search, root);
if (strcmp(search,root->data) == 0)
{
return True;
}
if (Prefix(root->left, tas, search))
return True;
if (Prefix(root->right, tas, search))
return True;
}
return False;
}