Thread: Helo with building binary trees using pointers

  1. #1
    Registered User
    Join Date
    Jan 2011
    Posts
    5

    Helo with building binary trees using pointers

    Hi to everyone. I'm currently working on a school homework using binary trees. I feel as though I'm almost finished, but I have a problem I couldn't figure out to solve.

    Although I have a general idea of how structures and pointers work, I still get confused with their usage. I've been searching the internet for a comprehensive explanation of how they work but most of what I've found lack the details that I need to know. So I came here hoping someone can explain these things better. Forgive me 'coz I really have a poor comprehension when it comes to pointers.

    My algorithm constructs a binary tree given the preorder and inorder sequence (in the form of strings).

    So I have a global structure declared this way:

    Code:
    struct Node{
     
      char letter;
      struct Node *left;
      struct Node *right;  
          
    };
    and a global pointer to the root.

    Code:
    struct Node *root;
    this is the rest of the code:

    Code:
    int main(){
      
      char preorder[5]="RASIN"; preorder[5]='\0';
      char inorder[5]="SAIRN"; inorder[5]='\0';
    
      root=malloc(sizeof(struct Node));
      *root=buildTree(preorder, inorder); //this line starts the construction of the tree from the root to its branches
      
      getch();
    }
    
    struct Node buildTree(char *preorder, char *inorder){ //I'm using a recursive method to build the tree. This is how I visualize the algorithm:
         
         struct Node *newNode=malloc(sizeof(struct Node));
         
         if(strlen(inorder)==1){
             newNode->left=NULL;
             newNode->right=NULL;
             newNode->letter=inorder[0];
             return *newNode;
         }
           
         int index = findLetterToPut(preorder, inorder);
         *newNode->left = buildTree(preorder, substr(inorder, 0, index));
         *newNode->right = buildTree(preorder, substr(inorder, index+1, strlen(inorder)-1));
         
         newNode->letter = inorder[index];
         
         
         return *newNode;
         
    }
    this is the function findLetterToPut(...):

    Code:
    int findLetterToPut(char *preorder, char *inorder){
         
         int index1, index2;
         
         for(index1=0; index1<strlen(preorder); index1++){
                      
            for(index2=0; index2<strlen(inorder); index2++){
                
                if(preorder[index1]==inorder[index2] )
                    return index2;
                    
            }
            
         }
    }
    The program works properly if I remove this line from the buildTree function:

    Code:
    *newNode->right = buildTree(preorder, substr(inorder, index+1, strlen(inorder)-1));
    However, only the left nodes are constructed without that line. The good thing is that these nodes are constructed properly. All pointers to the right node (starting from the root)are therefore NULL without this line.

    My question is: what's the problem with that line? If I include that line, an execution error occurs, e.g., illegal operation. That line is essential for constructing the right nodes.

    Thanks for your time.

  2. #2
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Lose the stars before newnode->

  3. #3
    Registered User
    Join Date
    Jan 2011
    Posts
    5
    Thanks, but I still get the same errors. It must be my algorithm. this is my current buildTree function:

    Code:
    struct Node buildTree(char *preorder, char *inorder){
         
         struct Node newNode; 
         
         if(strlen(inorder)<=1){
             newNode.letter=inorder[0];
             return newNode;
         }
           
         int index = findLetterToPut(preorder, inorder);
     
        *newNode.left = buildTree(preorder, substr(inorder, 0, index));
        *newNode.right= buildTree(preorder, substr(inorder, index+1, strlen(inorder)-1));
         newNode.letter = inorder[index];
    
         return newNode;
         
    }

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by croman View Post

    Although I have a general idea of how structures and pointers work, I still get confused with their usage. I've been searching the internet for a comprehensive explanation of how they work but most of what I've found lack the details that I need to know. So I came here hoping someone can explain these things better. Forgive me 'coz I really have a poor comprehension when it comes to pointers.
    Point at a poster on your wall. Ponder the difference between your hand (the pointer) and the poster (the thing pointed to). Ponder the similarities between them (this won't take long because there aren't any). And that's pointers.

    Quote Originally Posted by croman View Post

    this is the rest of the code:

    Code:
    int main(){
      
      char preorder[5]="RASIN"; preorder[5]='\0';
      char inorder[5]="SAIRN"; inorder[5]='\0';
    I hope you weren't expecting all those letters in your final program. Hint: putting a six-character string into a five-character array may lead you to wonder where your last letter went. Bonus hint: preorder[5] doesn't exist, despite your attempts to assign to it.

    Quote Originally Posted by croman View Post
    Code:
    struct Node buildTree(char *preorder, char *inorder){ //I'm using a recursive method to build the tree. This is how I visualize the algorithm:
         
         struct Node *newNode=malloc(sizeof(struct Node));
         
         if(strlen(inorder)==1){
             newNode->left=NULL;
             newNode->right=NULL;
             newNode->letter=inorder[0];
             return *newNode;
         }
           
         int index = findLetterToPut(preorder, inorder);
         *newNode->left = buildTree(preorder, substr(inorder, 0, index));
         *newNode->right = buildTree(preorder, substr(inorder, index+1, strlen(inorder)-1));
         
         newNode->letter = inorder[index];
    I am surprised and alarmed that even part of this code works. You need to store pointers to the nodes, not try to write into the memory pointed to by newNode->left, because currently newNode->left (and newNode->right, for that matter) point to somewhere in eastern New Jersey, and unless you also happen to be in eastern New Jersey this could be problematic. Instead you want your buildTree function to return the address of (i.e., the pointer to) the data, and store those addresses in your node.

  5. #5
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by croman View Post
    Thanks, but I still get the same errors. It must be my algorithm. this is my current buildTree function:

    Code:
    struct Node buildTree(char *preorder, char *inorder){
         
         struct Node newNode; 
         
         if(strlen(inorder)<=1){
             newNode.letter=inorder[0];
             return newNode;
         }
           
         int index = findLetterToPut(preorder, inorder);
     
        *newNode.left = buildTree(preorder, substr(inorder, 0, index));
        *newNode.right= buildTree(preorder, substr(inorder, index+1, strlen(inorder)-1));
         newNode.letter = inorder[index];
    
         return newNode;
         
    }
    I agree with tabstop, this should not work at all, but I'm also wondering what part of "lose the star before newnode" you didn't understand...

  6. #6
    Registered User
    Join Date
    Jan 2011
    Posts
    5
    thanks for the observations tabstop and CommonTater.

    Point at a poster on your wall. Ponder the difference between your hand (the pointer) and the poster (the thing pointed to). Ponder the similarities between them (this won't take long because there aren't any). And that's pointers.
    I apologize for my ignorance on this thing. Haha. Thanks for pointing that out. I know exactly the difference between the pointer and the address (assuming what I know is right -- well maybe not). It just really sucks I can't get them right in the implementation.

    I hope you weren't expecting all those letters in your final program. Hint: putting a six-character string into a five-character array may lead you to wonder where your last letter went. Bonus hint: preorder[5] doesn't exist, despite your attempts to assign to it.
    This was more a code that I arrived at out of trial and error (i.e, without understanding the background behind this). My problem was that when I print the preorder string in the buildTree function without the statement preorder[5]='\0'; I get an output of the exact string with a concatenation of 2 garbage values at its end. So I thought of terminating it. And it worked ("worked" in the sense that when I printed it again using printf, there were no longer garbage values at its end). So yeah, something must be really wrong with my code.

    I am surprised and alarmed that even part of this code works. You need to store pointers to the nodes, not try to write into the memory pointed to by newNode->left, because currently newNode->left (and newNode->right, for that matter) point to somewhere in eastern New Jersey, and unless you also happen to be in eastern New Jersey this could be problematic. Instead you want your buildTree function to return the address of (i.e., the pointer to) the data, and store those addresses in your node.
    Thanks. It's a shame, really. It's a shame that I don't get the whole pointer-address implementation thing. What I wanted this function to do was to create a node and return that node to the calling function. In this statement:

    Code:
    *newNode->left = buildTree(preorder, substr(inorder, 0, index));
    I wanted the newNode to point to another node (which will be generated by the called function). I'm just not sure if I did it right.


    Or should it be more like this?

    Code:
    struct Node newNode; 
    
    *newNode.left = buildTree(preorder, substr(inorder, 0, index));
    I agree with tabstop, this should not work at all, but I'm also wondering what part of "lose the star before newnode" you didn't understand...
    I tried removing the stars before it but it still didn't work. So I did a workaround that I thought was parallel to the idea that you were raising. But then I guess, I didn't really get it.

  7. #7
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by croman View Post
    thanks for the observations tabstop and CommonTater.
    \This was more a code that I arrived at out of trial and error (i.e, without understanding the background behind this). My problem was that when I print the preorder string in the buildTree function without the statement preorder[5]='\0'; I get an output of the exact string with a concatenation of 2 garbage values at its end. So I thought of terminating it. And it worked ("worked" in the sense that when I printed it again using printf, there were no longer garbage values at its end). So yeah, something must be really wrong with my code.
    What it is, is that you need to count.
    Code:
    preorder[6] = "AINRS";
    Code:
    *newNode->left = buildTree(preorder, substr(inorder, 0, index));
    I wanted the newNode to point to another node (which will be generated by the called function). I'm just not sure if I did it right.
    So if you want to know what it does, maybe you should read the code. newNode->left is a pointer, as per your struct. * means "follow the address and get the data there". Therefore "*newNode->left" means "look at newNode->left, which gives you an address, and go to that address and put the data there". If you want to change the pointer, you need to change the pointer; the pointer is "newNode->left", so that's what you need to have on the left side of the equal sign.

  8. #8
    Registered User
    Join Date
    Jan 2011
    Posts
    5
    Quote Originally Posted by tabstop View Post
    What it is, is that you need to count.
    Code:
    preorder[6] = "AINRS";

    So if you want to know what it does, maybe you should read the code. newNode->left is a pointer, as per your struct. * means "follow the address and get the data there". Therefore "*newNode->left" means "look at newNode->left, which gives you an address, and go to that address and put the data there". If you want to change the pointer, you need to change the pointer; the pointer is "newNode->left", so that's what you need to have on the left side of the equal sign.

    Thanks mate! I just solved the problem! Your ideas helped a lot. This is now the new code:

    Code:
    int main(){
        
      char preorder[6]="RASIN"; 
      char inorder[6]="AINRS";
      
      
      root=malloc(sizeof(struct Node));
      root=buildTree(preorder, inorder);
      
    }
    Code:
    struct Node *buildTree(char *preorder, char *inorder){
         
         struct Node *newNode=malloc(sizeof(struct Node));
         
         if(strlen(inorder)<=1){
             newNode->letter=inorder[0];
             
             return newNode;
         }
           
         int index = findLetterToPut(preorder, inorder);
     
         newNode->left = buildTree(preorder, substr(inorder, 0, index));
         newNode->right= buildTree(preorder, substr(inorder, index+1, strlen(inorder)-1));
         newNode->letter = inorder[index];
         
         
         return newNode;
         
         
    }
    It's working well. But I wonder if there are still flaws here.

  9. #9
    Bit Fiddler
    Join Date
    Sep 2009
    Posts
    79
    You're allocating the root node twice. You don't have to allocate the root node explicitly, since buildTree does it for you.

  10. #10
    Registered User
    Join Date
    Jan 2011
    Posts
    5
    Quote Originally Posted by Fader_Berg View Post
    You're allocating the root node twice. You don't have to allocate the root node explicitly, since buildTree does it for you.
    Thanks for pointing that out.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Binary Trees MINI MAXING, probability trees
    By curlious in forum General AI Programming
    Replies: 3
    Last Post: 09-30-2005, 10:57 AM
  2. Merging binary search trees
    By ibdutta in forum C Programming
    Replies: 2
    Last Post: 04-16-2004, 07:31 AM
  3. binary search trees
    By sweets in forum C++ Programming
    Replies: 3
    Last Post: 04-05-2004, 11:02 AM
  4. Binary Expression Trees
    By Kanji in forum C++ Programming
    Replies: 0
    Last Post: 03-12-2003, 10:01 PM
  5. binary trees
    By binary tree in forum C Programming
    Replies: 8
    Last Post: 11-26-2002, 06:19 AM