简体   繁体   中英

using backtracking with tree

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 AB (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 ABF 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 ABF instead of R BF)

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM