**Java data structure and algorithm analysis (vi)--AVL tree**
We said before. The removal algorithm of common binary lookup tree will make the Supi right subtree deep because we always replace the deleted node with one of the right subtree. will result in a two fork lookup tree, a serious imbalance. **Introduction to AVL tree**

The AVL tree is to solve the common binary search tree drawbacks of the method, he is a balanced two-fork lookup tree, this balance must be easy to maintain, and it ensures that the depth of the tree must be O (Logn).

AVL trees are highly balanced and binary trees. It is characterized by: the maximum height difference of two subtrees of any node in the AVL tree is 1.

The two pictures above, the AVL tree on the left, the height difference of the two subtrees of any node is <=1; and the right is not the AVL tree, because 7 of the two subtree height difference is 2 (2 is the root node of the tree height is 3, and 8 as the root node of the tree height is 1). **the implementation of AVL tree** **1. Node**

AVL tree node (inner Class)
class Avltreenode<t extends comparable<t>> {
T element; value
int height; Height
avltreenode<t> left; Left child
avltreenode<t> right; Right child public
Avltreenode (T key, avltreenode<t> left, avltreenode<t> right-hand) {
this.element = key;< C11/>this.left = left;
This.right = right;
this.height = 0;
}
}

1 2 3 4, 5 6 7 8 9 10 11 12 13 14 15

The Avltree is the corresponding class of the AVL tree, and the Avltreenode is the AVL tree node, which is the internal class of the Avltree. The avltree contains the root node of the AVL tree, and the basic operation of the AVL tree is also defined in the AVL tree. Avltreenode consists of several constituent objects:

(1) key– is the keyword that is used to sort the nodes of the AVL tree.

(2) left– is the left child.

(3) right– is the right child.

(4) height– is the height. **2. Height of the tree**

* * Get the height of the tree
/private int height (avltreenode<t>) {
if (!= null) return
tree.height ;
return 0;
}
public int height () {return
height (mroot);
}

1 2 3 4 5 6 7 8 9 10 11 12-13

In some places "the height of the empty binary tree is-1", here we use another definition: the height of the tree is the maximum level. The height of the empty two-fork tree is 0, and the height of the Non-empty tree is equal to its maximum level (the level of the root is 1, the child nodes of the root are the 2nd layer, and so on). **3. Rotate**

If you insert or delete a node in the AVL tree, it may cause the AVL tree to lose balance. This loss of balance can be summed up in 4 kinds of gestures: LL (left-left), LR (about), RR (right right) and RL (right left).

The above 4 trees are "out of balance of the AVL tree", from left to right in turn is: LL, LR, RL, RR. In addition to the above, there are other unbalanced AVL trees, as shown below:

(1) Ll:leftleft, also known as "left-left". After inserting or deleting a node, the Zuozi of the left subtree of the root node also has a Non-empty node, resulting in a "height of the left subtree of the root" greater than "2 of the height of the right subtree of the root", causing the AVL tree to lose its balance.

For example, in the above ll case, because the "root node (8) of the Zuozi (4) of the Zuozi (2) and the nonempty node", the right subtree (12) of the root node (8) has no child nodes, causing the Zuozi (4) Height of the root node (8) to be 8 higher than the right subtree (12) of the root node (2).

(2) Lr:leftright, also known as "around." After inserting or deleting a node, the right subtree of the root node's left subtree also has a Non-empty node, causing the "Root's left subtree height" to be 2 larger than the "right subtree of the root", causing the AVL tree to lose its balance.

For example, in the LR case above, because "Zuozi (4) of the root node (8) has Zuozi (6) and a nonempty node", the right subtree (12) of the root node (8) has no child nodes, causing the Zuozi (4) Height of the root node (8) to be 8 higher than the right subtree (12) of the root node (2).

(3) Rl:rightleft, called "right left". After inserting or deleting a node, the Zuozi of the right subtree of the root node also has a Non-empty node, resulting in a 2 greater than the height of the left subtree of the root, causing the AVL tree to lose its balance.

For example, in the RL case above, because "Zuozi (10) of the right subtree (12) of the root node (8) also has a nonempty node", the Zuozi (4) of the root node (8) has no child nodes, causing the right subtree (12) Height of the root node (8) to be 8 higher than the Zuozi (4) of the root node (2).

(4) Rr:rightright, called "Right Right". After inserting or deleting a node, the right subtree of the root node has a Non-empty node, causing the "right subtree of the root" to be 2 larger than "the height of the left subtree of the root", causing the AVL tree to lose its balance.

For example, in the above RR case, because the right subtree (14) of the right subtree (12) of the root node (8) also has a nonempty node, the Zuozi (4) of the root node (8) has no child nodes, causing the right subtree (12) Height of the root node (8) to be 8 higher than the Zuozi (4) of the root node (2).

If you insert or delete a node in the AVL tree, it may cause the AVL tree to lose balance. After the AVL loses its balance, it can be rotated to restore balance, and the following rotation methods are described in the 4 cases, "LL (left-left), LR (right and left) and RL (right left)."

ll the rotation

ll loses the balance, allowing the AVL tree to be balanced by a single spin. The following figure:

The left side of the picture is the tree before the rotation, and the right is the tree after the rotation. It can be found that after the rotation of the tree has become an AVL tree, and the rotation only need one time to complete.

For ll rotation, you can understand this as: ll rotation around the "loss of the balance of the AVL root node", that is, node K2, and because it is ll situation, that is left-left situation, with the hands of the "left child, that is K1" shake hard. Turning the K1 into a root node, the K2 becomes the right subtree of K1, and the "right subtree of K1" becomes the "left subtree of K2".

ll's rotation code

/**
* LL: Left-left corresponding case (left single rotation).
* @param K2
* @return After the rotation of the root node * *
private avltreenode<t> leftleftrotation (avltreenode<t> K2) {
avltreenode<t> k1;
K1 = k2.left;
K2.left = k1.right;
K1.right = K2;
K2.height = Math.max (height (k2.left), height (k2.right)) + 1;
K1.height = Math.max (height (k1.left), k2.height) + 1;
return k1;
}

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16-17

Rotation of RR

After I understand ll, the RR is fairly easy to understand. RR is the case with LL symmetry. The RR recovery balance rotation method is as follows:

The left side of the picture is the tree before the rotation, and the right is the tree after the rotation. RR rotation can be done only once.

Private avltreenode<t> rightrightrotation (avltreenode<t> K1) {
avltreenode<t> K2;
K2 = k1.right;
K1.right = K2.left;
K2.left = K1;
K1.height = Math.max (height (k1.left), height (k1.right)) + 1;
K2.height = Math.max (height (k2.right), k1.height) + 1;
return K2;
}

1 2 3 4 5 6 7 8 9 10 11-12

LR's rotation

LR loses balance, it takes two rotations to restore the AVL tree to its equilibrium.

The first rotation is "RR rotation" around "K1", and the second is "ll rotation" around "K3".

LR's rotation code

/**
* LR: Left and right situation (double rotation).
* @param K3
* @return After the rotation of the root node * *
private avltreenode<t> leftrightrotation (avltreenode< T> K3) {
k3.left = rightrightrotation (k3.left);
Return leftleftrotation (K3);
}

1 2 3 4 5 6 7 8 9 10

The spin of the RL

The RL is symmetric with LR. The RL restore balance rotation method is as follows:

The first rotation is "ll rotation" around "K3", and the second is "RR rotation" around "K1".

RL's spin Code

/**
* RL: Right left corresponds to the case (right double rotation).
* @param K1
* @return After the rotation of the root node * *
private avltreenode<t> rightleftrotation (avltreenode<t > K1) {
k1.right = leftleftrotation (k1.right);
return rightrightrotation (k1);
}

1 2 3 4 5 6 7 8 9 10

**4. Insert**
public void Insert (T key) {mroot = insert (Mroot, key);
/** * Inserts the node into the AVL tree and returns the root node * * @param the root nodes of the tree AVL trees * @param key value of the node inserted by key * @return the root node * Private avltreenode<t> Insert (avltreenode<t> tree, T key) {if (tree = = null) {/
/new node return tree = new avltreenode<t> (key, NULL, NULL);
int cmp = Key.compareto (tree.element);
if (CMP < 0) {//Insert key into "tree's left subtree" tree.left = insert (Tree.left, key);
else if (cmp > 0) {//Insert key into the tree's right subtree Tree.right = insert (tree.right, key); }