Thread: Find balanced BST with max height

  1. #1
    Registered User
    Join Date
    Jun 2017
    Posts
    4

    Find balanced BST with max height

    Hello all!

    I am trying to come up with the code to find the balanced BST with max height within a given BST. So far, I have some preliminaries:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <malloc.h>
    
    typedef struct Tree {     int key;
        struct Tree *left;
        struct Tree *right;
    } Tree;
    
    Tree* InsertBST(Tree* t, int k)
    {
        if (t == NULL) {
            Tree* w = (Tree*) malloc(sizeof(Tree));
            w->key = k;
            w->left = NULL;
            w->right = NULL;
            return w;
        }
    
        if (k <= t->key)
            t->left = InsertBST(t->left, k);
        else
            t->right = InsertBST(t->right, k);
    
        return t;
    }
    
    int max(int a, int b)
    {
        if (a >= b)
            return a;
        else
            return b;
    }
    
    int height(Tree* t)
    {
        if (t == NULL)
            return 0;
    
        return 1 + max(height(t->left), height(t->right));
    }
    
    int IsBalanced(Tree *t)
    {
        int lheight;
        int rheight;
    
        if (t == NULL)
            return 1;
    
        lheight = height(t->left);
        rheight = height(t->right);
    
        if (abs(lheight-rheight) <= 1 &&
            IsBalanced(t->left) &&
            IsBalanced(t->right))
            return 1;
    
        return 0;
    }
    These work fine. The problem lies within the following function:

    Code:
    void MaxBalanced(Tree *t, Tree *maxBal, int *maxBal_height)
    {
        int t_height;
    
        if (t == NULL)
            *maxBal_height += 0;
    
        if (IsBalanced(t) == 1){
            t_height = height(t);
            if (t_height >= *maxBal_height){
                maxBal = t;
                *maxBal_height = t_height;
            }
        }
        else{
            MaxBalanced(t->left, maxBal, maxBal_height);
            MaxBalanced(t->right, maxBal, maxBal_height);
        }
    }
    
    int main()
    {
        int i;
    
        Tree* t = NULL;
    
        int j[20] = { 993, 591, 2, 4, 395, 97, 446, 38, 279, 587, 28, 50, 265, 502, 114, 493, 808, 716, 897, 987 };
    
        for (i = 0; i < 20; i++)
            t = InsertBST(t, j[i]);
    
        DisplayTree(t);
    
        Tree* maxBal = NULL;
        int maxBal_height = 0;
        MaxBalanced(t, maxBal, &maxBal_height);
    
        DisplayTree(maxBal);
    
        return 0;
    }
    The code runs without errors but I get an empty tree. DisplayTree is a funtion which allows to present the tree graphically (too long to post here). I would appreciate any hints as to what is wrong with this approach.

  2. #2
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    Also posted here, and here.

    I also find this interesting:
    I started out finding functions to get the height of a given tree and check whether it is balanced.
    I guess "finding" code is much easier than writing it.

    Jim

  3. #3
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    A guess from someone who never learned about trees in C.

    Code:
    void MaxBalanced(Tree *t, Tree *maxBal, int *maxBal_height)
    The above looks wrong; you are trying to return a pointer.
    To return a pointer you need to pass a pointer to a pointer.

    Tim S.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  4. #4
    Registered User
    Join Date
    Jun 2017
    Posts
    4
    Quote Originally Posted by jimblumberg View Post

    I guess "finding" code is much easier than writing it.

    Jim
    Not being proficient in C I have spent a fair amount of time trying to understand the code I have found. Also, I have put in considerable effort into writing my own functions and it is because of the fact that I hit a snag that I am asking help of more experienced programmers.

  5. #5
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    Try fixing these two lines of code.

    Code:
    if (t == NULL)
            *maxBal_height += 0;
    If you do NOT see the problem describe in words what the second line does.

    If you can NOT fix the second line; then, you have no business trying to fix the code you found. And, you need to learn to C and give up finding code to use or learn from.

    Tim S.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    > Not being proficient in C I have spent a fair amount of time trying to understand the code I have found.
    You have to understand that 90% of the code you 'find' is crap to start with. You're building a house on sand if you use that as your starting template.

    If you found it on a forum, then the person was basically in the same position as you, with half an answer.
    If you found a 'tutorial' (there are many rubbish ones of these as well), it's probably not much better. If you saw "void main", "include conio.h", "gets(buff)" or "fflush(stdin)" anywhere on the tutorial site, then it's best left alone.


    There really is no short-cut to proficiency except lots of confusion, lots of hard work, and sudden moments of blinding clarity when you finally get it.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User
    Join Date
    Jun 2017
    Posts
    4
    Quote Originally Posted by stahta01 View Post
    Try fixing these two lines of code.

    Code:
    if (t == NULL)
            *maxBal_height += 0;
    If you do NOT see the problem describe in words what the second line does.

    Tim S.
    If I'm not mistaken, I can get rid of these two lines since they do nothing. I tested this on different trees of different size and it would seem to me that the function passes the correct maximum height of a balanced subtree via pointer. So, it is my suspicion that the logic behind my code is not completely wrong (even if it is not the most efficient solution).

    Right now, it seems to me that what's off is my use of pointers in

    Code:
    maxBal = t;

  8. #8
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    Quote Originally Posted by Zelazny View Post
    If I'm not mistaken, I can get rid of these two lines since they do nothing. I tested this on different trees of different size and it would seem to me that the function passes the correct maximum height of a balanced subtree via pointer. So, it is my suspicion that the logic behind my code is not completely wrong (even if it is not the most efficient solution).

    Right now, it seems to me that what's off is my use of pointers in

    Code:
    maxBal = t;
    The proper fix is this.

    Code:
    if (t == NULL)
            *maxBal_height = 0;
    And the problem is what I already told you.
    Quote Originally Posted by stahta01 View Post
    A guess from someone who never learned about trees in C.

    Code:
    void MaxBalanced(Tree *t, Tree *maxBal, int *maxBal_height)
    The above looks wrong; you are trying to return a pointer.
    To return a pointer you need to pass a pointer to a pointer.

    Tim S.
    Tim S.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  9. #9
    Registered User
    Join Date
    Jun 2017
    Posts
    4
    Quote Originally Posted by stahta01 View Post
    The proper fix is this.

    Code:
    if (t == NULL)
            *maxBal_height = 0;
    And the problem is what I already told you.


    Tim S.
    Thanks for the pointer-to-pointer structure suggestion. With that in mind, I rewrote the code:

    Code:
    void MaxBalanced(Tree *t, Tree **maxBal, int *maxBal_height)
    {
        int t_height;
    
        if (IsBalanced(t) == 1){
            t_height = height(t);
            if (t_height > *maxBal_height){
                maxBal = &t;
                *maxBal_height = t_height;
            }
        }
        else{
            MaxBalanced(t->left, maxBal, maxBal_height);
            MaxBalanced(t->right, maxBal, maxBal_height);
        }
    }
    
    int main()
    {
        int i;
        srand (time(NULL));
    
        Tree* t = NULL;
    
        for (i = 0; i < 20; i++)
            t = InsertBST(t, rand() % 1000);
    
        Tree** maxBal = NULL;
        int maxh = 0;
        MaxBalanced(t, maxBal, &maxh);
        PrintTreeRoot(*maxBal);
        printf("%d", maxh);
        DisplayTree(*maxBal);
    
        return 0;
    }
    I get the idea why a pointer to pointer might be the way to go. However, I am clearly still missing something since this executes with segfault.

  10. #10
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    You have no idea on how to use pointers!

    MaxBalanced(t, maxBal, &maxh);

    Why did you put an address of operator in front of maxh?
    Then, why did you NOT put an address of operator in front of maxBal?

    Edit: Are you a human being or a monkey trying to write code using random or trial and error method?

    Tim S.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. binary tree - find height with recursive function
    By Bjorn in forum C++ Programming
    Replies: 3
    Last Post: 02-22-2015, 10:55 AM
  2. Create a balanced (not BST) tree
    By kr0n1x in forum C Programming
    Replies: 9
    Last Post: 09-13-2011, 03:38 PM
  3. How do you create a balanced binary tree?
    By Mr_Jack in forum C++ Programming
    Replies: 3
    Last Post: 01-13-2004, 03:02 PM
  4. Code to test if a tree is balanced
    By rahuls in forum C Programming
    Replies: 1
    Last Post: 03-20-2003, 02:41 PM

Tags for this Thread