Returning error when traversing through a tree

65 Views Asked by At

I am trying to calculate the frequency of each node as I add them to the tree, instead of inserting a new element. For some reason when a comparing a new key to every element in the current tree, the if statement will not return 1 if they are both identical. BUT, the function will still add 1 to the frequency of the existing node. This is very puzzling to me, as I don't know why it would skip over the return 1, and continue searching through the tree. Thank you for help/advice in advance.

struct:

typedef struct node {
    char* key;
    struct node *left;
    struct node *right;
    int height;
    int frequency;
}node;

This is my parsing function:

while(fgets(str, 100, textFile)) {

    token = strtok(str," \n");

    while (token != NULL)
    {
        key = strdup(token);
            if((sameFrequency(root, key)==1)&&root!=NULL) { 
                printf("%s", key);
                free(key);
                token = strtok (NULL, " \n");
            }
            else {
                root = insert(root, key);
                //printf("%s\n", key);
                free(key);
                token = strtok (NULL, " \n");
            }
    }
    if(ferror(textFile))
    {
        printf("you done messed up a-a-ron");
        return(0);
    }
}

Function to check the frequency of each node:

int sameFrequency(node *node, char* key) {
    if (node != NULL) {

        if(strcmp(key, node->key)==0){ //This statement is true in some cases, but will not return the 1
            node->frequency = node->frequency+1;
            printf("%d\n",node->frequency);
            return 1;
        }

        sameFrequency(node->left, key);
        sameFrequency(node->right, key);
    }
    else return 0;
}

Input would look something like this:

wrn69 flr830 flr662 flr830 flr830 
flr231

The output (after printing in preOrder):

key: wrn69, frequency: 1
key: flr830, frequency: 3
key: flr662, frequency: 1
key: flr231, frequency: 1
key: flr830, frequency: 1
key: flr830, frequency: 1

I want this to print everything shown, but I don't want the same key to be inserted into the tree, just incremement its frequency by 1.

TL;DR: Function skipping over return value, but still running code in the if statement, have no idea whats wrong, even after debugging.

1

There are 1 best solutions below

3
On BEST ANSWER

I'm not sure what your code is trying to do, since you do not define your node struct, however your function int sameFrequency(node *node, char* key) has an obvious bug: not all code paths return a value. Reformatting a bit for clarity, you can see that if strcmp(key, key)!=0 then the return is undefined:

int sameFrequency(node *node, char* key) {
    if (node != NULL) {

        if(strcmp(key, node->key)==0){
            node->frequency = node->frequency+1;
            printf("%d\n",node->frequency);
            return 1;
        }
        else { 
            sameFrequency(node->left, key);
            sameFrequency(node->right, key);
            // Continue on out of the "if" statements without returning anything.
        }
    }
    else {
        return 0;
    }
    // NO RETURN STATEMENT HERE
}

My compiler generates a warning for this:

warning C4715: 'sameFrequency' : not all control paths return a value

Surely yours must be doing so as well, unless you intentionally disabled them. Such warnings are important, and should always be cleared up before finishing your code.

I'm guessing you want to do something like this, perhaps?

int sameFrequency(node *node, char* key) {
    if (node != NULL) {

        if(strcmp(key, node->key)==0){
            node->frequency = node->frequency+1;
            printf("%d\n",node->frequency);
            return 1;
        }
        else { 
            int found;
            if ((found = sameFrequency(node->left, key)) != 0)
                return found;
            if ((found = sameFrequency(node->right, key)) != 0)
                return found;
            return 0;
        }
    }
    else {
        return 0;
    }
}

This clears the compiler warning.

Incidentally, the following if statement is probably in the wrong order:

        if((sameFrequency(root, key)==1)&&root!=NULL) { 

Since && statements in C execute left to right the following makes more sense:

        if(root!=NULL && (sameFrequency(root, key)==1)) {