8
votes

I have implemented an AVL tree, but I have a problem.

Suppose I have following tree:

enter image description here

And after adding another node:

enter image description here

Now I must rotate node5 to left:

enter image description here

But after rotation, it is still unbalanced.

Where am I making a mistake?

2
It requires a double rotation, rotate 11, and then 5.StoryTeller - Unslander Monica
@StoryTeller Thanks, i don't know that. i read wikipedia article but i don't understand very well how to determine double rotation is requeried. Can you explain it in an easy way?MRB
BTW 7 should be drawn on in the right node.Grzegorz
@Grzegorz Why? it is less than 10 and i think it must be on the left.MRB
@MohammadRB: LOL! I did not know it is 10. I thought it is 1. (one with a dot) Sorry about that!Grzegorz

2 Answers

19
votes

The presented scenario conforms to the Right-Left case from this Wikipedia description.

Your mistake is that you rotate the imbalanced node (5) at once, without first performing a rotation of its sub-tree.

In general having P as the unbalanced node, L as its left sub-tree and R as its right sub-tree the following rules should be followed at insertion:

balance(N) = Depth(Nleft) - Depth(Nright)

if (balance(P) > 1)  // P is node 5 in this scenario
{
    if (balance(L) < 0)
    {
        rotate_left(L);
    }

    rotate_right(P);
}
else if (balance(P) < -1) // P is node 5 in this scenario
{
    if (balance(R) > 0)  // R is node 11 in this scenario
    {
        rotate_right(R); // This case conforms to this scenario
    }

    rotate_left(P);      // ... and of course this, after the above
}

So sometimes two rotations need to be performed, and sometimes only one.

This is nicely visualized at Wikipedia:

enter image description here

The top row shows situations when two rotations are needed. The middle row presents possible scenarios when one rotation is sufficient. Additional rotations transform any top-row scenario to the middle-row scenario.

In particular, for this tree:

enter image description here

After 7 is added:

enter image description here

The balance of 5 is 2. This conforms to the scenario marked with a comment above in the pseudo-code and also to the top-row scenario (the one on the right) in the Wikipedia picture. So before 5 is left-rotated, its right sub-tree 11 needs to be right-rotated:

enter image description here

And it becomes:

enter image description here

Only now, it's the simple case (middle-row right scenario in the Wikipedia picture) to restore balance at 5 by one left-rotation:

enter image description here

And the tree becomes balanced again:

enter image description here

0
votes

Let me try to analyse more comprehensively, For a binary tree to be avl tree, the height difference of each node from any left-most leaf to any right-most leaf must lie within {-1, 0, 1}.

Insertion for AVL:

There are four cases for AVL insertion- L - L L - R R - R R - L

Now, case (a). [if balance > 1] L-L(left - left) A node X violates the {-1, 0, 1} constraint and has left height more than right - gives first left of L has a left sub child Y whose left height is greater than right .. again L Action - Rotate about Y clockwise. ie. one right rotation.

case (b) (L -R case)Suppose some Z node is to be inserted, for Z, it is first evaluated, at which leaf, left or right, it is placed. Right, if more weight, Left if less weight. say, Z', new node, wt(Z') > wt(Z), ie, Z' is inserted as right child of Z, case of L - R, the whole link ZZ' is rotated anti clockwise, now it is L-L case and hence solved using above case (a). ie. one Left and then one right rotation.

case (c) [if balance < -1] (R - R case) Similarly, R - R case, simply apply the binary search rule for adjustments and this case works. ie. one left rotation.

case (d) (R - L case) It is first converted to R-R case and hence solved using above case (c). ie. one right and then one left rotation.