0

Below is a program which first build Binary tree from inorder and preorder and then find the node which contain largest balanced tree.

My both function for Buildtree and IsBalanced is right.

I am reading inorder and preorder from input.txt file; so in first iteration my program is showing correct output, but in the second iteration, it is not working.

I think that there is problem in deleting root.

After running above program you will get which problem I am talking about :

/* Tree - Program to find largest Balanced tree in given tree
@Date : 15 July 2012

This program works only for one input sample
*/
#include<stdio.h>
#include<stdlib.h>
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
using namespace std;
struct node
{
  char data;
  struct node* left;
  struct node* right;
};

/* Prototypes for utility functions */
int search(string arr, int strt, int end, char value);
struct node* newNode(char data);

int isBalanced(struct node *root, int* height,int *max_size_ref, bool *is_bal_ref,char *val)
{
  /* lh = Height of left subtree ,rh = Height of right subtree */   
  int lh = 0, rh = 0;  
 int left_flag=0;
 int right_flag=0;
  /* l will be true if left subtree is balanced 
    and r will be true if right subtree is balanced */
  int l = 0, r = 0;

  if(root == NULL)
  {
    *height = 0;
    *is_bal_ref = 1;
     return 0;
  }

  l = isBalanced(root->left, &lh, max_size_ref,is_bal_ref, val);

  if (*is_bal_ref == 1)
  left_flag=true;

  r = isBalanced(root->right,&rh, max_size_ref,is_bal_ref, val);
  if (*is_bal_ref == 1)
  right_flag = true;

  *height = (lh > rh? lh: rh) + 1;
  if((lh - rh >= 2) || (rh - lh >= 2))
  *is_bal_ref= 0;

  /* If this node is balanced and left and right subtrees 
    are balanced then return true */
  if(left_flag && right_flag && *is_bal_ref ){
  *is_bal_ref= 1;
  if (l + r + 1 > *max_size_ref)
  {  
        *max_size_ref = l + r+ 1;
        *val = root->data;}
        return l + r + 1;
  }
  else
  {
    //Since this subtree is not Balanced, set is_bal flag for parent calls
     *is_bal_ref = 0; 
     return 0;
  }
}


struct node* buildTree(string in, string pre, int inStrt, int inEnd)
{
  static int preIndex = 0;

  if(inStrt > inEnd)
     return NULL;

  /* Pick current node from Preorder traversal using preIndex
    and increment preIndex */
  struct node *tNode = newNode(pre[preIndex++]);

  /* If this node has no children then return */
  if(inStrt == inEnd)
    return tNode;

  int inIndex = search(in, inStrt, inEnd, tNode->data);

  /* Using index in Inorder traversal, construct left and
     right subtress */
  tNode->left = buildTree(in, pre, inStrt, inIndex-1);
  tNode->right = buildTree(in, pre, inIndex+1, inEnd);

  return tNode;
}


/* Function to find index of value in arr[start...end]
   The function assumes that value is present in in[] */

int search(string arr, int strt, int end, char value)
{
  int i;
  for(i = strt; i <= end; i++)
  {
    if(arr[i] == value)
      return i;
  }
}

/* Helper function  */
struct node* newNode(char data)
{
  struct node* node = new (struct node);
  node->data = data;
  node->left = NULL;
  node->right = NULL;

  return(node);
}

/* This function is for inorder traversal */
void printInorder(struct node* node)
{
  if (node == NULL)
     return;


  printInorder(node->left);


  printf("%c ", node->data);


  printInorder(node->right);
}

// function to free binary tree
void freeT(struct node* t ) //get root
{
    if( t == NULL ) 
        return;
    if( t->left != NULL )
        freeT( t->left );
    if( t->right != NULL )
        freeT( t->right);

    delete(t);       /* free(t) if c */

    return;
}



/* Driver program to test above functions */
int main()
{

 string line , inorder;
 ifstream myfile ("input.txt");
 ofstream myofile ("output.txt" );
 if (myfile.is_open())
 { 
   int len=0;
   char data=NULL;
   int height=0;
   int max_size_ref=0;
   bool is=false;
   int size=0;
   struct node *root = NULL;
   while ( myfile.good() )
    {
      getline (myfile,line);
      //cout << line << endl;
      inorder=line;
      getline (myfile,line);
      //cout << line << endl;

      len = line.size();
      //cout<<"len="<<len;

      root= buildTree(inorder, line, 0, len - 1);

      data=NULL;
      height=0;
      max_size_ref=0;
      is=false;
      size=isBalanced(root, &height ,&max_size_ref, &is, &data);
      if(data!=NULL)
      {
      myofile<<data;
      myofile<<"\n";
      //std::cout<<data;
      }
      else
      {
      myofile<<-1;
      myofile<<"\n";
      }
      //printf("\n Inorder traversal of the constructed tree is \n");
      //printInorder(root);
      getchar();
      //freeT(root);
      //root=NULL;
   }
    myfile.close();
    myofile.close();
  }

  //getchar();
  return 0;
}

First run this program with input.txt containing below content and see output.txt

FDBGEHAC
ABDFEGHC

Then run above program with

    FDBGEHAC
    ABDFEGHC
    FDCEBAJHGI
    ABCDFEGHJI

Now see output.txt

You will get what I really want.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
  • 1
    "Freeing" and "re-rooting" are two different things. – Dave Newton Jul 15 '12 at 15:20
  • @Dave Newton Actually in first iteration root is null , so it does not create any problem and in second iteration as root is not null so it creates problem , can you please suggest me any solution. – user1485933 Jul 15 '12 at 15:30
  • Your function `freeT()` is invalid in C++ and only borderline valid in C (it is not strictly C99 or C11; C89 allows it as a concession to code that was prevalent but bad even in 1989). Why are you using `malloc()` and `free()` in a C++ program; you should be using `new` and `delete`. – Jonathan Leffler Jul 15 '12 at 15:48
  • 1
    What do you mean by "in the second iteration, it is not working"? – amdn Jul 15 '12 at 15:51
  • `malloc` and `free` have **no** place in C++ (…). Fix this by using C++ memory management and smart pointers. – Konrad Rudolph Jul 15 '12 at 15:55
  • @Jonathan Leffler i have changed new and delete in my program , and still it is not working in second iteration. – user1485933 Jul 15 '12 at 15:56
  • by second iteration i mean that first it read two lines from input.txt file and then after this it again read next two lines from text file , so after reading next two lines it is not working beacuse there is some problem in re rooting of root of tree – user1485933 Jul 15 '12 at 15:59
  • No this is not homework, i have done almost complete problem just stuck in rerooting. – user1485933 Jul 15 '12 at 15:59
  • On the second iteration of the loop, the variables are all fresh. That means that between the code in `buildTree()` (and the perhaps the code in `printInorder()` and `isBalanced()`, if either of those does memory allocation or modifies the tree) and the `freeT()`, there is an inconsistency. How have you demonstrated that `buildTree()` works? What does `printInorder()` show immediately after `builtTree()` returns? How big an example does it take to trigger the problem? One node, two nodes, three nodes, four nodes, or more? – Jonathan Leffler Jul 15 '12 at 16:04
  • You declare "data" to be "char" and assign "NULL" to it. What does isBalanced expect for its 5th argument? Should "data" be "char*" instead? – amdn Jul 15 '12 at 16:29
  • @all I have edit above question and now i have written my whole program , i think everything is clear now. – user1485933 Jul 15 '12 at 17:59

2 Answers2

0

When using a tree or hierarchical structure ( collection ), you should keep the "root" variable, outside of the "while" loop, or other nodes.

This is a pseudocode, not intended to be full valid code, just an example:

int main()
{
   ...

   struct node *root = NULL;

   while ( myfile.good() )
   {

     // load tree, maybe change root

   } // while

   ...
} // int main()

As you already check. "Root" is a pointer to an structure, and even that may change which node is root, you should have an external variable.

umlcat
  • 4,091
  • 3
  • 19
  • 29
0

It seems you have a bug in buildTree that is triggered by the 2nd set of data. The bug causes infinite recursion, you get a "stackoverflow" :-) and your program crashes. You can confirm this by swapping lines 3 and 4 with lines 1 and 2 of the second input.txt sample data, your program will then die on the first iteration. You can run your program with gdb and will catch the stackoverflow. You can also put a print statement in buildTree and will see that it gets caught in infinite recursion.

amdn
  • 11,314
  • 33
  • 45