开发者

What is wrong with this AVL balancing code?

Everytime I use this my avlRotate function, it drops some elements from the tree. z is the node in which imbalance was detected, y is its subtree node having the greater height, x is the newly inserted node. This function is called immediately after a single insertion.

#define RESTRUCTURE  a->left = t0; a->right = t1; c->left = t2; c->right = t3; b->left = a; b->right = c;

avlTree avlRotate(avlTree z,avlTree y,avlTree x)
{
    avlTree a,b,c;  
    avlTree t0,t1,t2,t3;

    if(y==z->left && x==y->left)  //single rotation
    {
        a=x;b=y;c=z;
        t0=a->left;
        t1=a->right;
        t2=b->right;
        t3=c->right;
        RESTRUCTURE
        c->height[0] = y->height[1];

    }
    else if(y==z->right && x==y->right) //single rotation
    {
        a=z;b=y;c=x;
        t0=a->left;
        t1=b->left;
        t2=c->left;
        t3=c->right;
        RESTRUCTURE
        a->height[1] = y->height[0];

    }
    else if(y==z->right && x==y->left)  //double rotation
    {
        a=z;b=x;c=y;
        t0=a->left;
        t1=b->left;
        t2=b->right;
        t3=c->right;
        RESTRUCTURE
        a->height[1] = x->height[0];
        c->height[0] = x->height[1];
    }
    else if(y==z->left && x==y->right)  //double rotation
    {
        a=y;b=x;c=z;
        t0=a->left;
        t1=b->left;
        t2=b->right;
        t3=c->right;
        RESTRUCTURE
        a->height[1] = x->height[0];
        c->height[0] = x->height[1];    
    }

    printf("\nRem parts:\n");
    printf("{%d %d} {%d %d} {%d %d}\n",a->part->range[0],a->part->range[1],b->part->range[0],b->part->range[1],c->part->range[0],c->part->range[1]);
    printf("\n\n");

    b->height[0] = ( (a->height[0] > a->height[1]) ? (a->height[0])+1 : (a->height[1])+1 ); 
    b->height[1] = ( (c->height[0] > c->height[1]) ? (c->height[0])+1 : (c->height[1])+1 ); 
    a->balFactor = a->height[0] - a->height[1];
    b->balFactor = b->height[0] - b->height[1];
    c->balFactor = c->height[0] - c->height[1]; 
    return(b);
}

The function is called with:

if(a->balFactor > 1 || a->balFactor < -1)
    {
        printf("imbalance fside=%d pside=%d\n",*finalSide,*prevSide);

        if(*finalSide == 0)
        {yLike = a->left;}
        else
        {yLike = a->right;}
        if(*prevSide == 0)
        {xLike = yLike->left;}
        else
        {xLike = yLike->right;}
        printf("passing to rotate %u %u %u\n",a,yLike,xLike);
        printf("{%d %d} {%开发者_开发百科d %d} {%d %d}\n",a->part->range[0],a->part->range[1],yLike->part->range[0],yLike->part->range[1],xLike->part->range[0],xLike->part->range[1]);
        a = avlRotate(a,yLike,xLike);
        avlInOrderTraversal(a,0);           
        printf("{%d %d} {%d %d} {%d %d}\n",a->left->part->range[0],a->left->part->range[1],a->part->range[0],a->part->range[1],a->right->part->range[0],a->right->part->range[1]);
    }

in the insert function.

Output:

a->height[0]=1 a->height[1]=0
BALANCE FACTOR = 1



    16 to 18
51 to 53



a->height[0]=0 a->height[1]=1
BALANCE FACTOR = -1
a->height[0]=2 a->height[1]=0
BALANCE FACTOR = 2
imbalance fside=0 pside=1
passing to rotate 147992552 147992584 147992616
{51 53} {16 18} {41 41}

Rem parts:
{16 18} {41 41} {51 53}





51 to 53



a->height[0]=0 a->height[1]=1
BALANCE FACTOR = -1



51 to 53
    60 to 61



a->height[0]=1 a->height[1]=1
BALANCE FACTOR = 0



    4 to 6
51 to 53
    60 to 61

Is something obviously incorrect with this function?

Note: Each node stores a range, for eg. 3 to 5.


Write a function to dump your tree. For each node, display what it thinks its left, right, up and left/right subtree depths are.

Dump the tree before a rotation and then afterwards.

That's what I did when I wrote mine.

You -are- going to have subtle bugs in the tree - recourse to SO on each problem will get you nowhere fast. You are also going to need a dump function to debug rebalancing as you climb the tree - there are a number of unique rebalancing cases for add and delete which you need to verify. All of this requires a tree dump.


There are numerous resources on AVL tree in the web, a chosen few are:

  1. http://en.wikipedia.org/wiki/AVL_tree
  2. C implementation: http://www.stanford.edu/~blp/avl/libavl.html
  3. Animation: http://www.cs.jhu.edu/~goodrich/dsa/trees/avltree.html
  4. Animation: http://www.strille.net/works/media_technology_projects/avl-tree_2001/

Continuing Blank Xavier's answer further, I would suggest to compare the dump output of your program with the animation results.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜