简体   繁体   中英

How to reroot a tree which is allocated through malloc()

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.

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.

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.

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