-1

I am learning about AVL trees, this makes scense to me, but i can't get it to work properly.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define LEFT -1
#define BAL   0
#define RIGHT 1


typedef int Key;
typedef void * Info;


struct avltree {
        int bal;
        Key key;
        Info info;
        struct avltree *left, *right;
};

typedef struct avltree *BTree;

BTree newBTree (Key k, Info i, BTree l, BTree r) {
        BTree n;

        n = (BTree) malloc (sizeof (struct avltree));
        if (n) {
                n->key   = k;
                n->info  = i;
                n->bal   = BAL;
                n->left  = l;
                n->right = r;
        }
        return n;
}
BTree fixLeft (BTree a);
BTree fixRight (BTree a);
BTree addAux (BTree a, Key k, Info i);


BTree rotateLeft (BTree a) {
        BTree b  = a->right;
        a->right = b->left;
        b->left  = a;
        return b;
}

BTree rotateRight (BTree a) {
        BTree b  = a->left;
        a->left  = b->right;
        b->right = a;
        return b;
}

BTree add (BTree a, Key k, Info i) {

        return (addAux (a,k,i));
}


int max (int x, int y){
        int m = x>y ? x : y;

        return m;
}

int height(BTree t){
        if(!t){
                return 0;
        }

        int m = max(height(t->left), height(t->right)) + 1;

        return m;
}


BTree addAux (BTree a, Key k, Info i) {
        if (a == NULL) {
                a = newBTree (k,i,NULL,NULL);
                a->bal = BAL;

        } else if (a->key > k) {
                a->left = addAux (a->left,k,i);

                                //once a->left gets his value, bellow i will compare
                                //the size of both left and right subtrees

                int l = height(a->left);
                int r = height(a->right);

                                //If the left one is bigger by just one unit , is ok
                                //as it gets a mark saying the left side is heavier
                                //and otherwise if it's bigger on the right

                if(l-r  == 1){
                                a->bal = LEFT;
                }else if(l-r  == -1){
                                a->bal = RIGHT;
                }

                                //Here i tell that if the left side has a heavy-factor of 2
                                //i get it fixed by calling fixLeft

                else if(l-r > 1){
                                a->bal = LEFT;
                                fixLeft(a);
                }else if(l-r < -1){
                                a->bal = RIGHT;
                                fixRight(a);
                }

                                //And vice-versa on this else

        } else { // (a->key < k)
                a->right = addAux (a->right,k,i);
                int l = height(a->left);
                int r = height(a->right);

                if(l-r  == 1){
                                a->bal = LEFT;
                }else if(l-r  == -1){
                                a->bal = RIGHT;
                }

                else if(l-r > 1){
                                a->bal = LEFT;
                                fixLeft(a);
                }else if(l-r < -1){
                                a->bal = RIGHT;
                                fixRight(a);
                }


                }
                return a;
}

BTree fixLeft (BTree a) {
        if (a->left->bal == LEFT) {
                a = rotateRight (a);
                a->bal = a->right->bal = BAL;
        }
        else {
                a->left = rotateLeft(a->left);
                a = rotateRight (a);
                a->bal = a->right->bal = BAL;
        }
        return a;
}

BTree fixRight (BTree a) {
        if (a->right->bal == RIGHT) {
                a = rotateLeft (a);
                a->bal = a->left->bal = BAL;
        }
        else {
                a->right = rotateRight(a->right);
                a = rotateLeft (a);
                a->bal = a->left->bal = a->right->bal = BAL;
        }
        return a;
}

void dumpKeys (BTree a, int level){
        int l;
        if (a) {
                dumpKeys (a->right, level+1);
                for (l=0;l<level;l++) printf ("%5c",' ');
                printf ("%5d\n", a->key);
            dumpKeys (a->left, level+1);
        }
}



int main(){
        BTree a = NULL;

        a=add(a,10,NULL);
        a=add(a,20,NULL);
        a=add(a,15,NULL);

        dumpKeys (a,0);
        return 0;
}

Somewhere i lose the pointer to the next nodes i guess, it outputs only the root, or the first element inserted. No errors on the debugger.

Thank you!

Minimal, Complete, and Verifiable example:

http://pastebin.com/zyziTyXJ

skills
  • 315
  • 5
  • 17
  • What do you mean by _but i can't get it to work properly_? – pzaenger Dec 12 '15 at 16:35
  • 1) This looks like C. Why added the C++ tag? Do not add tags for unrelated languages. If in doubt, use the tag for the language you compile. 2) TL;DR. Provide a [mcve], learn [ask]. "does not work" is not a **specific** problem statement. – too honest for this site Dec 12 '15 at 16:35
  • When you used the debugger, which statement is causing the issue? What are the values of the variables at that statement? – Thomas Matthews Dec 12 '15 at 16:43
  • @pzaenger The output is only 10, please see my file at the bottom, just added it . it compiles with no warnings or errors – skills Dec 12 '15 at 17:02
  • @Olaf , you are right, next time i will add a pastebin with the compilable code. Added now. Thank you – skills Dec 12 '15 at 17:02
  • 1
    Please don't do this: `typedef int Key;` and `typedef void * Info;` – pzaenger Dec 12 '15 at 17:18
  • @pzaenger I believe it's because it might confuse others while reading right? I will take that in consideration. – skills Dec 12 '15 at 17:26
  • Indeed. In my opionen these `typedef`s make it harder to understand your code. They might make sense to shorten more complex types, like `UINT` for `unsigned int` for example (which you can often see). – pzaenger Dec 12 '15 at 17:31
  • You have to add the code **in** your question. Just having the code in an an external link is against site-rules. – too honest for this site Dec 12 '15 at 18:12
  • @pzaenger: I agree about `typedef`ing pointers, but what would be the problem with `Key`? And for `unsigned int` there already is a short way: `unsigned`. `typedef`ing `Key` might make sense to clarify what it intends and to allow easy changes, e.g. to `long` later. – too honest for this site Dec 12 '15 at 18:13
  • @Olaf done. Can someone please point me to the right direction on what is wrong? – skills Dec 12 '15 at 18:54
  • "done." - what? You made it worse. Maybe you better take the [tour] and learn [ask]. After 2 years, you actually should know already. I will not tutor further here. – too honest for this site Dec 12 '15 at 18:57
  • Why have i made it worse? the code is now *in* the post, there is no compiler errors, so i haven't described them, and i tell what is happening, for some reason i get only the root value as the output. I am sorry if i have failed at some point, after hours around this, i really feel empty headed. – skills Dec 12 '15 at 19:05
  • A suggestion: you seem to have some trouble with this complex task. Try to implement a simple linked list, which can add nodes and print the whole list. This might be a good exercise for you. The above code seems a bit too much. – pzaenger Dec 13 '15 at 12:51
  • Thank you for the suggestion pzaenger, but i got it fixed. Cheers – skills Dec 13 '15 at 14:31

1 Answers1

0

The problem was very straightforward to solve, i got really light-headed after a few hours.

i am calling the functions fixRight and fixLeft when they return a BTree, but not assigning the returning value to nothing.

So, here is the error and fixed:

...
    else if(l-r > 1){
            a->bal = LEFT;
            a = fixLeft(a); //HERE
    }else if(l-r < -1){
            a->bal = RIGHT;
            a = fixRight(a);  //HERE
    }
...
skills
  • 315
  • 5
  • 17