简体   繁体   English

该AVL平衡代码有什么问题?

[英]What is wrong with this AVL balancing code?

Everytime I use this my avlRotate function, it drops some elements from the tree. 每次我使用avlRotate函数时,它都会从树中删除一些元素。 z is the node in which imbalance was detected, y is its subtree node having the greater height, x is the newly inserted node. z是检测到不平衡的节点,y是其高度较大的子树节点,x是新插入的节点。 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 . 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. 您-树中将有一些细微的错误-对每个问题求助于SO将使您无处可寻。 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: 网上的AVL树上有很多资源,其中一些是:

  1. http://en.wikipedia.org/wiki/AVL_tree http://en.wikipedia.org/wiki/AVL_tree
  2. C implementation: http://www.stanford.edu/~blp/avl/libavl.html C实现: http//www.stanford.edu/~blp/avl/libavl.html
  3. Animation : http://www.cs.jhu.edu/~goodrich/dsa/trees/avltree.html 动画http//www.cs.jhu.edu/~goodrich/dsa/trees/avltree.html
  4. Animation : http://www.strille.net/works/media_technology_projects/avl-tree_2001/ 动画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 . 进一步继续Blank Xavier的回答 ,我建议将程序的转储输出与动画结果进行比较

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM