1

I have a homework, done the most part of it but i'm stuck at a point. I have to search through a binary tree and find a keyword, if the keyword doesn't show up I have to find the lexicographically next string at the tree witch has as a prefix the keyword I wanted to find, until no other string satisfies the previous criteria.

The code bellow is for searching after I haven't found the exact word.

int successor(TreeNode *v,char* x){

int lenght = strlen(x);
printf("%d\n", lenght);
if (v != NULL) {

    if (strncmp(x , v->key, lenght) == 0)
    {
        // found
        printf("%s, %d\n", v->key, v->appears);
    }

    else if (strncmp(x , v->key, lenght) < 0)
        return successor(v->left, x); 

    else if (strncmp( x , v->key, lenght) > 0)
        return successor(v->right, x);      

    else 
        printf("Query string not found.\n");
    }
}
else return 0; }

EXAMPLE

If I have the words: tree traversal trees

         tree   <---(not root)
traversal    trees

If I search: "tr"

I get only traversal back.

I can't go left or right after traversal cause is a leaf, and i can't find a way to show up tree and trees too.

I have tried some things but it didn't work out so now I'm asking you, besides that I don't even know how to handle the lexicographically next keyword or what I have to do with it!

Any help appreciated! :D

4pie0
  • 29,204
  • 9
  • 82
  • 118
MDims.
  • 33
  • 1
  • 5
  • 1
    Isn't `traversal` where you want to end up? It is the word (of the three shown there) which would be lexicographically after "tr", right? – John Hascall Jan 12 '16 at 00:43
  • @MDims so what do you want to do? Your code does what you wanted, it searches lexicographically. Do you want to print strings if they contain searched word? – 4pie0 Jan 12 '16 at 00:50
  • Sorry mates, I made a change at the question. " ... lexicographically next string at the tree witch has as a prefix the keyword I wanted to find, until no other string satisfies the previous criteria." – MDims. Jan 12 '16 at 00:54
  • So based on example what should be the result? – 4pie0 Jan 12 '16 at 00:57
  • The three of em, the tree is bigger that this. Based on the example if I search for tr I have to get back these three words and not just the first one. – MDims. Jan 12 '16 at 01:00

1 Answers1

2

To print all the words that contain searched keyword you have to traverse the tree, as there is no way to know in advance whether any of descendants matches.

Basic approach

To traverse the tree you can use a function similar to this:

void
bin_tree_search_inorder(struct TreeNode *t)
{
    if (t == NULL)
        return;
    bin_tree_search_inorder(t->left);
    // do check here
    bin_tree_search_inorder(t->right);
}

This function works by traversing the binary tree to the left as far as possible and then traversing to first possible right from the bottom, repeatedly. To check if prefix is contained you may use strstr function:

if (strstr(t->key, key) != 0)
    printf("\nMatch: [%s]", t->key);
else
    printf("\nDoesn't match: [%s]", t->key);

Better approach

To limit the searching area you can take into account that you should continue search as long as there is a chance to find a match down the tree, and you can make this more precise: you know exactly when there is any use of going right, left, or both.

void
bin_tree_search_inorder(struct t *t, char *key)
{
    int res;
    if (t == NULL)
        return;
    if (strstr(t->key, key) != 0)
    {
        printf("\nMatch: [%s]", t->key);
        bin_tree_search_inorder(t->l, key);
        bin_tree_search_inorder(t->r, key);
    } else {
        printf("\nDoesn't match: [%s]", t->key);
        if (strlen(t->key) >= strlen(key))
        {
            res = strcmp(key, t->key);
            if (res > 0)
                bin_tree_search_inorder(t->l, key);
            else
                bin_tree_search_inorder(t->r, key);
        }
    }
} 

Working code

Usage:

int
main(void)
{
    struct t root, l, r, rl, rr, ll, lr;
    strcpy(&root.key, "tree");
    strcpy(&l.key, "traversal");
    strcpy(r.key, "trees");
    root.l = &l;
    root.r = &r;
    l.l = l.r = r.l = r.r = NULL;
    strcpy(rl.key, "tre");
    strcpy(rr.key, "tx");
    r.l = &rl;
    r.r = &rr;
    rl.l = rl.r = rr.l = rr.r = NULL;
    strcpy(ll.key, "ta");
    strcpy(lr.key, "travvv");
    l.l = &ll;
    l.r = &lr;
    ll.l = ll.r = lr.l = lr.r = NULL;
    bin_tree_search_inorder(&root, "tr");
    return 0;
}

Output:

Doesn't match: [ta]

Match: [traversal]

Match: [travvv]

Match: [tree]

Match: [tre]

Match: [trees]

Doesn't match: [tx]

4pie0
  • 29,204
  • 9
  • 82
  • 118
  • Hmm, it didn't work or I did something wrong. I have the same results. The changes i made was `void successor(TreeNode *v,char* x)` & `int lenght = strlen(x);` as well changed the recursion to mach. The if check is where you commented. – MDims. Jan 12 '16 at 01:30
  • @Mdims you should put code from the bottom in place of // do(...). I have attached link to working code. – 4pie0 Jan 12 '16 at 01:44
  • Sorry tinky, my code bugged cause I called `bin_tree_search_inorder` within another function and it showed only the first result. Thanks for your answer mate! :D – MDims. Jan 12 '16 at 01:58