使用回溯树

发布于 2024-11-18 14:18:54 字数 1395 浏览 2 评论 0原文

由于堆栈(带有推入和弹出),我在树中使用回溯算法。 它有效,但我有一个问题。堆栈给出的路径是“错误的”。

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 的路径时,此函数返回 RAB(适用于 R 和 A,而不是 B)。

我不知道它是来自这个函数还是push()函数。 如果您在函数中没有看到任何错误,我将粘贴push(),但它很长。

编辑:我现在更好理解了, 我已添加到该功能:
如果节点是叶子,则 pop()。 如果我搜索 F,它会返回 RABF 而不是 RB F。我不知道如何避免将 A 保留在堆栈中。

edit2:

这里是代码:(返回 RABF 而不是 RBF)

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 (Prefix(root->left, tas, search)) 的 else ?有人有主意吗?

谢谢 !

I'm using the backtracking algorithm in tree thanks to a stack (with push and pop).
It works but i've got a problem. The path given by the stack is "wrong".

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;
}

For example, i've got a tree as :

     Root
    /    \    
   A      B
  / \    / \
 C   D  E   F    

When I want the path of C for example, this function returns R A B (ok for R and A, not B).

I don't know if it comes from this function or the push() function.
If you don't see any error in the function, I will paste push() but it's quite long.

Edit: I better understand now,
I've added to the function :
if node is a leaf, pop().
If I search F, it returns me R A B F instead of R B F. I don't konw how to avoid to keep A in the stack.

edit2 :

Here is the code : (returns R A B F instead of 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;
}

I don't understand how I can pop traversing child node to obtain the good result, maybe adding
a else to if (Prefix(root->left, tas, search)) ? Anyone have an idea ?

thanks !

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

左耳近心 2024-11-25 14:18:54

至少有一个问题是您没有检查对 Prefix 调用的返回值,因此您不知道递归调用是否“完成”(并且您应该停止探索)。

查看此情况的一个简单方法是遍历函数调用(给定示例树):

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 将允许您在适当的时间退出。

At least one problem is that you're not checking the return values of your calls to Prefix, so you don't know if the recursive calls "finish" (and that you should stop exploring).

A simple way to see this is just walk through the function calls (given your sample tree):

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

This shows the order of the calls and indents correspond roughly to frames on the call stack.

You can see where checking if a call to Prefix returns true will allow you to exit at the appropriate time.

看海 2024-11-25 14:18:54

我必须同意@Mark Elliot 的观点,但乍一看,他的答案可能看起来令人困惑。您确实需要一个停止条件,这样您就不会继续探索其他节点并将它们添加到堆栈中。您将返回一个布尔值,以便您可以使用它来测试调用是否找到您要查找的节点。

如果您打算将 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;
}

I have to agree with @Mark Elliot but at first glance, his answer may seem confusing. You do need a stop condition so you don't keep exploring other nodes and adding them to the stack. You are returning a bool so you can use that to test if the call finds the node your looking for.

If it was your intention to include the last node in the path to C in the stack, then you should remove the string compare when adding to the stack.

For example, you could do this.

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文