插入AVL BST

时间:2015-12-12 16:29:55

标签: c binary-search-tree avl-tree

我正在学习AVL树,这对我来说很有意思,但我无法让它正常工作。

#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;
}

在某些地方我失去了指向下一个节点的指针我猜,它只输出根或插入的第一个元素。调试器没有错误。

谢谢!

最小,完整且可验证的示例:

http://pastebin.com/zyziTyXJ

1 个答案:

答案 0 :(得分:0)

这个问题很容易解决,几个小时后我真的很轻松。

我在返回BTree时调用函数fixRight和fixLeft,但是没有将返回值赋值为空。

所以,这是错误并修复:

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