开发者

using backtracking with tree

开发者 https://www.devze.com 2023-03-18 22:58 出处:网络
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\".

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 !


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.


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

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号