简体   繁体   中英

Building Expression tree with negative nodes

I have troubles building a binary tree like this: view tree . You can see there are operand nodes like - who just have one child. Even with simple trees like +-a the code doesn't work.

My code is:

    // Represents a node of the required tree 
typedef struct node { char data; struct node *left, *right; } node; 

// Function to recursively build the expression tree 
char* add(node** p, char* a) 
{ 

// If its the end of the expression 
if (*a == '\0') 
    return '\0'; 

while (1) { 
    char* q = "null"; 
    if (*p == NULL) { 

        // Create a node with *a as the data and 
        // both the children set to null 
        node* nn = (node*)malloc(sizeof(node));
        nn->data = *a; 
        nn->left = NULL; 
        nn->right = NULL; 
        *p = nn; 
    } 
    else { 

        // If the character is an operand 
        if (*a >= 'a' && *a <= 'z') { 
            return a; 
        } 

        // Build the left sub-tree 
        q = add(&(*p)->left, a + 1); 

        // Build the right sub-tree 
        q = add(&(*p)->right, q + 1); 

        return q; 
    } 
  } 
} 

int main() 
    { 
    node* s = NULL; 
    char a[] = "+-a"; 
    add(&s, a); 
    return 0; 
    }

Thank for your help <3

There are contradictions on the snippet and things that don't make sense. It's hard to know where to start with explaining what is going on.

I guess one thing to start off with is that this is not a good place to apply recursion. A part of the problem is inherently iterative: you want to iterate through the character string. Combining this with a recursive algorithm is clearly giving you headaches because you don't do it well, at all. In general, recursion is a trap and making things iterative results in cleaner code. Data structures that "require" recursion are also frequently traps.

Regardless, I'll eventually present a recursive algorithm that works. For now, to dissect what you're doing wrong. returning a char pointer from add is immediately a huge red flag: getting pointer arithmetic to work in recursion is difficult because changes have to manifest across the call stack. Eliminating this from the code is an obvious start.

Next is the while loop. A loop is inherently an iterative thing, yet you include it in a recursive algorithm: hopefully the inherently iterative nature of this is starting to become clear. The reason you have the while loop is also really dumb: you split with an if-else that is completely unnecessary. The right thing to do is simply allocate a new node every call without having an if, because you'll never recur on an already extant node as is, and you definitely do not need an else because the recursion logic needs to happen regardless of whether a new node had to be allocated or not. So, remove the while loop, and the if-else.

Next is the q variable. I have no idea what you were trying to do with it, but it's garbage regardless. Removed. A minor point on when you allocate a new node is that you don't need a new variable to allocate a new node: you can simply use *p. This saves a line of code.

Finally we get to the recursion logic. I've already spoken about the q thing, so no elaboration needed. The logic here simply doesn't work because you're not iterating through the string in a proper way. Doing this in a recursive algorithm is, again, harder than if you wrote it in an iterative fashion.

So, here's the actually working code. I've taken extreme liberty with compressing the source so that the algorithm takes up less space vertically, as saving on LoC is a good thing.

int add(node** p, char* a, int i) {
    if (a[i] == '\0') return i; // If end of expression 
     *p = (node*) malloc(sizeof(node));
    (*p)->data = a[i];
    (*p)->left = (*p)->right = NULL;
    if (a[i] >= 'a' && a[i] <= 'z') return i;   // If the character is an operand 
    i = add(&(*p)->left , a, ++i);
    if (a[i] == '\0')   return i;   // If its the end of the expression 
    i = add(&(*p)->right, a, ++i);
    return i;
}

The i variable is used to count the way through the string. You'll have to modify your initial add call in main to accomodate.

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