Thread: Functions Max in binary tree

  1. #1
    Registered User
    Join Date
    May 2013
    Posts
    13

    Angry Functions Max in binary tree

    Hello everyone, I have a problem with the C code . I created two functions, one that runs through the tree inorder, the other that returns the maximum value in the tree. The problem is when I use in the main the method "max", which goes in a loop and not print anything on the screen . If I remove the call to method "max" it works fine. Here's the code:
    Code:
    #include<stdio.h>
    #include<stdlib.h>
    #define bool int
    
    
    /* A binary tree tNode has data, pointer to left child
       and a pointer to right child */
    struct tNode
    {
       int data;
       struct tNode* left;
       struct tNode* right;
    };
     
    /* Structure of a stack node. Linked List implementation is used for 
       stack. A stack node contains a pointer to tree node and a pointer to 
       next stack node */
    struct sNode
    {
      struct tNode *t;
      struct sNode *next;
    };
     
    /* Stack related functions */
    int Fmax(struct tNode *root);
    void push(struct sNode** top_ref, struct tNode *t);
    struct tNode *pop(struct sNode** top_ref);
    bool isEmpty(struct sNode *top);
     int max(struct tNode*r);
     int lessthan(struct tNode * r,int val);
    /* Iterative function for inorder tree traversal */
    void inOrder(struct tNode *root)
    {
      /* set current to root of binary tree */
      struct tNode *current = root;
        /* Initialize stack s */
      bool done = 0;
     struct sNode *s = NULL;
      while (!done)
      {
        /* Reach the left most tNode of the current tNode */
        if(current !=  NULL)
        {
          /* place pointer to a tree node on the stack before traversing 
            the node's left subtree */
          push(&s, current);                                               
          current = current->left;  
        }
            
        /* backtrack from the empty subtree and visit the tNode 
           at the top of the stack; however, if the stack is empty,
          you are done */
        else                                                             
        {
          if (!isEmpty(s))
          {
            current = pop(&s);
            printf("%d ", current->data);
     
            /* we have visited the node and its left subtree.
              Now, it's right subtree's turn */
            current = current->right;
          }
          else
            done = 1; 
        }
      } /* end of while */ 
    }     
     
    /* UTILITY FUNCTIONS */
    /* Function to push an item to sNode*/
    void push(struct sNode** top_ref, struct tNode *t)
    {
      /* allocate tNode */
      struct sNode* new_tNode =
                (struct sNode*) malloc(sizeof(struct sNode));
     
      if(new_tNode == NULL)
      {
         printf("Stack Overflow \n");
         getchar();
         exit(0);
      }            
     
      /* put in the data  */
      new_tNode->t  = t;
     
      /* link the old list off the new tNode */
      new_tNode->next = (*top_ref);   
     
      /* move the head to point to the new tNode */
      (*top_ref)    = new_tNode;
    }
     
    /* The function returns true if stack is empty, otherwise false */
    bool isEmpty(struct sNode *top)
    {
       return (top == NULL)? 1 : 0;
    }   
     
    /* Function to pop an item from stack*/
    struct tNode *pop(struct sNode** top_ref)
    {
      struct tNode *res;
      struct sNode *top;
     
      /*If sNode is empty then error */
      if(isEmpty(*top_ref))
      {
         printf("Stack Underflow \n");
         getchar();
         exit(0);
      }
      else
      {
         top = *top_ref;
         res = top->t;
         *top_ref = top->next;
         free(top);
         return res;
      }
    }
     
    /* Helper function that allocates a new tNode with the
       given data and NULL left and right pointers. */
    struct tNode* newtNode(int data)
    {
      struct tNode* tNode = (struct tNode*)
                           malloc(sizeof(struct tNode));
      tNode->data = data;
      tNode->left = NULL;
      tNode->right = NULL;
     
      return(tNode);
    }
     
    /* Driver program to test above functions*/
    int main()
    {
        
       
     
      /* Constructed binary tree is
                1
              /   \
            2      3
          /  \
        4     5
      */
      struct tNode *root = newtNode(1);
      root->left        = newtNode(2);
      root->right       = newtNode(3);
      root->left->left  = newtNode(4);
      root->left->right = newtNode(5); 
     
      int maxValue=0;
     
      inOrder(root);
      maxValue= max(root);
      printf("%d",maxValue);
      
      
      getchar();
       
      return 0;
    }
    
    
    int max(struct tNode *r){
     if(r==NULL)
        return 0;
    struct sNode *s = NULL;
        int max=r->data;
         push(&s,r);
         while(!isEmpty(s)){
         if(r->data>max)
            max=r->data;
            pop(&s);
            if(r->right!=NULL)
                        push(&s,r->right);
            if(r->left!=NULL)
                        push(&s,r->left);
         
                    
         }
         return max;
    
    
    }
    Someone can help me please??Thank u!!!

  2. #2
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    Perhaps your compiler is getting confused:

    Code:
    int max(struct tNode *r){
        int max=r->data;
    Naming variables with the same name as your functions is a very bad practice. I get the following warning from my complier:
    main.c||In function ‘max’:|
    main.c|173|warning: declaration of ‘max’ shadows a global declaration [-Wshadow]|
    main.c|169|warning: shadowed declaration is here [-Wshadow]|
    Jim

  3. #3
    Registered User
    Join Date
    May 2013
    Posts
    13

    New code

    I changed the method's name but the problem remains.The new code:
    Code:
    #include<stdio.h>
    #include<stdlib.h>
    #define bool int
    
    
    /* A binary tree tNode has data, pointer to left child
       and a pointer to right child */
    struct tNode
    {
       int data;
       struct tNode* left;
       struct tNode* right;
    };
     
    /* Structure of a stack node. Linked List implementation is used for 
       stack. A stack node contains a pointer to tree node and a pointer to 
       next stack node */
    struct sNode
    {
      struct tNode *t;
      struct sNode *next;
    };
     
    /* Stack related functions */
    void push(struct sNode** top_ref, struct tNode *t);
    struct tNode *pop(struct sNode** top_ref);
    bool isEmpty(struct sNode *top);
     int findMax(struct tNode*r);
    /* Iterative function for inorder tree traversal */
    void inOrder(struct tNode *root)
    {
      /* set current to root of binary tree */
      struct tNode *current = root;
        /* Initialize stack s */
      bool done = 0;
     struct sNode *s = NULL;
      while (!done)
      {
        /* Reach the left most tNode of the current tNode */
        if(current !=  NULL)
        {
          /* place pointer to a tree node on the stack before traversing 
            the node's left subtree */
          push(&s, current);                                               
          current = current->left;  
        }
            
        /* backtrack from the empty subtree and visit the tNode 
           at the top of the stack; however, if the stack is empty,
          you are done */
        else                                                             
        {
          if (!isEmpty(s))
          {
            current = pop(&s);
            printf("%d ", current->data);
     
            /* we have visited the node and its left subtree.
              Now, it's right subtree's turn */
            current = current->right;
          }
          else
            done = 1; 
        }
      } /* end of while */ 
    }     
     
    /* UTILITY FUNCTIONS */
    /* Function to push an item to sNode*/
    void push(struct sNode** top_ref, struct tNode *t)
    {
      /* allocate tNode */
      struct sNode* new_tNode =
                (struct sNode*) malloc(sizeof(struct sNode));
     
      if(new_tNode == NULL)
      {
         printf("Stack Overflow \n");
         getchar();
         exit(0);
      }            
     
      /* put in the data  */
      new_tNode->t  = t;
     
      /* link the old list off the new tNode */
      new_tNode->next = (*top_ref);   
     
      /* move the head to point to the new tNode */
      (*top_ref)    = new_tNode;
    }
     
    /* The function returns true if stack is empty, otherwise false */
    bool isEmpty(struct sNode *top)
    {
       return (top == NULL)? 1 : 0;
    }   
     
    /* Function to pop an item from stack*/
    struct tNode *pop(struct sNode** top_ref)
    {
      struct tNode *res;
      struct sNode *top;
     
      /*If sNode is empty then error */
      if(isEmpty(*top_ref))
      {
         printf("Stack Underflow \n");
         getchar();
         exit(0);
      }
      else
      {
         top = *top_ref;
         res = top->t;
         *top_ref = top->next;
         free(top);
         return res;
      }
    }
     
    /* Helper function that allocates a new tNode with the
       given data and NULL left and right pointers. */
    struct tNode* newtNode(int data)
    {
      struct tNode* tNode = (struct tNode*)
                           malloc(sizeof(struct tNode));
      tNode->data = data;
      tNode->left = NULL;
      tNode->right = NULL;
     
      return(tNode);
    }
     
    /* Driver program to test above functions*/
    int main()
    {
        
       
     
      /* Constructed binary tree is
                1
              /   \
            2      3
          /  \
        4     5
      */
      struct tNode *root = newtNode(1);
      root->left        = newtNode(2);
      root->right       = newtNode(3);
      root->left->left  = newtNode(4);
      root->left->right = newtNode(5); 
     
      int maxValue=0;
     
      inOrder(root);
      maxValue= findMax(root);
      printf("%d",maxValue);
      
      
      getchar();
       
      return 0;
    }
    
    
    int findMax(struct tNode *r){
     if(r==NULL)
        return 0;
    struct sNode *s = NULL;
        int max=r->data;
         push(&s,r);
         while(!isEmpty(s)){
         if(r->data>max)
            max=r->data;
            pop(&s);
            if(r->right!=NULL)
                        push(&s,r->right);
            if(r->left!=NULL)
                        push(&s,r->left);
         
                    
         }
         return max;
    
    
    
    
    }

  4. #4
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    Have you run your program with your debugger? You seem to have an endless loop in your findmax() function. You may want to look at your inorder() function, these two functions could be basically the same.

    Jim

  5. #5
    Registered User
    Join Date
    May 2013
    Posts
    13
    The program works perfectly if the functionfindMax is not called ! How can I solve this problem?

  6. #6
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    Are you sure the tree is constructed as you believe it is?
    Code - functions and small libraries I use


    It’s 2014 and I still use printf() for debugging.


    "Programs must be written for people to read, and only incidentally for machines to execute. " —Harold Abelson

  7. #7
    Registered User
    Join Date
    May 2013
    Posts
    13
    if u delete from the code
    Code:
    maxValue= findMax(root);
      printf("%d",maxValue);


    the program run...What does your post?

  8. #8
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    Well take a look at treemanagement.c.

    You will find a print function there. Try it. Then print in different parts of your program to see what's wrong
    Code - functions and small libraries I use


    It’s 2014 and I still use printf() for debugging.


    "Programs must be written for people to read, and only incidentally for machines to execute. " —Harold Abelson

  9. #9
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    Run the program with your debugger. You should see that you have an endless loop in your findmax() function.

    Why are you always pushing twice and only popping once.

    Jim

  10. #10
    Registered User
    Join Date
    May 2013
    Posts
    13
    During the debug i have these problem!Functions Max in binary tree-error-jpgFunctions Max in binary tree-error2-jpg

  11. #11
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    you have a segmentation fault, isn't this enough to be convinced that your program is wrong?

    Run a debugger, or use the print function I suggested.
    Code - functions and small libraries I use


    It’s 2014 and I still use printf() for debugging.


    "Programs must be written for people to read, and only incidentally for machines to execute. " —Harold Abelson

  12. #12
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    As I said your findmax() function could be quite similar to your inorder() function. I tried this code for your findmax() function and it seems to work. I'll leave it to you to eliminate all the duplicate code but it does seem work. It may not be the most efficient, but that's something you can try to determine.

    Code:
    int findmax(struct tNode *root)
    {
       int max = 0;
       /* set current to root of binary tree */
       struct tNode *current = root;
       /* Initialize stack s */
       bool done = 0;
       struct sNode *s = NULL;
       while (!done)
       {
          /* Reach the left most tNode of the current tNode */
          if(current !=  NULL)
          {
             /* place pointer to a tree node on the stack before traversing
               the node's left subtree */
             push(&s, current);
             current = current->left;
          }
    
          /* backtrack from the empty subtree and visit the tNode
             at the top of the stack; however, if the stack is empty,
            you are done */
          else
          {
             if (!isEmpty(s))
             {
                current = pop(&s);
                if(current->data > max)
                   max = current->data;
    
                /* we have visited the node and its left subtree.
                  Now, it's right subtree's turn */
                current = current->right;
             }
             else
                done = 1;
          }
       } /* end of while */
       return(max);
    
    }

    Jim

  13. #13
    Registered User
    Join Date
    May 2013
    Posts
    13
    Thank u Jim,u are the best

  14. #14
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    Don't forget you still need to find a way to eliminate the duplicate code.

    Jim

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Need Help with Binary Tree Functions
    By Highwind7 in forum C Programming
    Replies: 6
    Last Post: 08-02-2007, 06:23 PM
  2. Replies: 2
    Last Post: 08-01-2007, 01:08 PM
  3. Replies: 17
    Last Post: 11-16-2006, 09:06 PM
  4. Replies: 0
    Last Post: 11-04-2006, 11:07 AM
  5. display tree data in binary tree format
    By xddxogm3 in forum C++ Programming
    Replies: 4
    Last Post: 12-11-2003, 12:47 AM