Sie sind auf Seite 1von 27

AVL Trees

AVL Trees

Outline and Reading




AVL tree (9.2)


Definition  Height of an AVL tree


 

Update Operations Java implementation

AVL Tree
 

AVL trees are balanced. An AVL Tree is a binary search tree such that for every internal node v of T, the heights of the children of v can differ by at most 1.

4 44 2 17 1 32 1 48 62 2 50 1 88 78 1 3

An example of an AVL tree where the heights are shown next to the nodes:
3

Height of an AVL Tree


 

 

Proposition: The height of an AVL tree T storing n keys is O(log n). Justification: The easiest way to approach this problem is to find n(h): the minimum number of internal nodes of an AVL tree of height h. We see that n(1) = 1 and n(2) = 2 For n 3, an AVL tree of height h contains the root node, one AVL subtree of height n-1 and the other AVL subtree of height n-2. i.e. n(h) = 1 + n(h-1) + n(h-2)

Height of an AVL Tree (cont)




Knowing n(h-1) > n(h-2), we get n(h) > 2n(h-2)


n(h) > 2n(h-2) n(h) > 4n(h-4) n(h) > 8n(h-6) n(h) > 2in(h-2i) For any integer I such that h-2i u 1

  

Solving the base case we get: n(h) 2 h/2-1 Taking logarithms: h < 2log n(h) +2 Thus the height of an AVL tree is O(log n)
5

Insertion
 

 

A binary search tree T is called balanced if for every node v, the height of vs children differ by at most one. Inserting a node into an AVL tree involves performing an expandExternal(w) on T, which changes the heights of some of the nodes in T. If an insertion causes T to become unbalanced, we travel up the tree from the newly created node until we find the first node x such that its grandparent z is unbalanced node. Since z became unbalanced by an insertion in the subtree rooted at its child y, height(y) = height(sibling(y)) + 2 Now to rebalance...

Insertion: rebalancing
  

To rebalance the subtree rooted at z, we must perform a restructuring we rename x, y, and z to a, b, and c based on the order of the nodes in an in-order traversal. z is replaced by b, whose children are now a and c whose children, in turn, consist of the four other subtrees formerly children of x, y, and z.

Insertion (contd.)
unbalanced...
5 44 2 17 1 32 1 48 1 3

z 2 y
50 2 78

64 7
1 88

4 3
54 62

x
5

T3 T2
4 44 2 17 1 32 1 2 3

T0

...balanced
4 x
62

2y
50

z 6
2 78

1
48

3
1 54

7
1 88

T2 T0 T1 T3
8

Restructuring


The four ways to rotate nodes in an AVL tree, graphically represented -Single Rotations:
a=z b=y c=x T0 T1 T2
c y a x T3 T0 T1
9

single rotation

b=y a=z c=x T3

T3

T0

T1

T2

si

le r t ti

y a x c z

T3 T2 T1 T0

T2

double rotations:
a=

Restructuring (contd.)
doub c= b= T0 T2 T1
double rot tion

o a on a=

b= c= T2

T3

T0

T1

T3

c a y x

x a y T2 c z

T0 T3 T2 T1 T3

T1

T0
10

Restructure Algorithm
Algorithm restructure(x): Input: A node x of a binary search tree T that has both a parent y and a grandparent z Output: Tree T restructured by a rotation (either single or double) involving nodes x, y, and z. Let (a, b, c) be an inorder listing of the nodes x, y, and z, and let (T0, T1, T2, T3) be an inorder listing of the the four subtrees of x, y, and z, not rooted at x, y, or z. 2. Replace the subtree rooted at z with a new subtree rooted at b 3. Let a be the left child of b and let T0, T1 be the left and right subtrees of a, respectively. 4. Let c be the right child of b and let T2, T3 be the left and right subtrees of c, respectively.
11

1:

Cut/Link Restructure Algorithm


 

Lets go into a little more detail on this algorithm... Any tree that needs to be balanced can be grouped into 7 parts: x, y, z, and the 4 trees anchored at the children of those nodes (T0-3)
44

y
17 50 62

x
78

T0

48

54

88

T2 T1 T3
12

Cut/Link Restructure Algorithm


44 17 50

y
62

x
78

T0

48

54

88

T2 T1 T3

 

Make a new tree which is balanced and put the 7 parts from the old tree into the new tree so that the numbering is still correct when we do an in-order-traversal of the new tree. This works regardless of how the tree is originally unbalanced. Lets see how it works!
13

Cut/Link Restructure Algorithm




Number the 7 parts by doing an in-order-traversal. (note that x,y, and z are now renamed based upon their order within the traversal)

1
17

2 z (a)
44

y (b)

4
x (c)
78

3
50 48 54

62

6
88

T0

5
T2

7
14

T1

T3

Cut/Link Restructure Algorithm




Now create an Array, numbered 1 to 7 (the 0th element can be ignored with minimal waste of space)

Cut() the 4 T trees and place them in their inorder rank in the array T0 1 2 T1 3 4 T2 5 6 T3 7
15

Cut/Link Restructure Algorithm




Now cut x,y, and z in that order (child,parent,grandparent) and place them in their inorder rank in the array. T0
a
44

T1

62

b T2

78

c T 3

1 2 3 4 5 6 7 Now we can re-link these subtrees to the main tree. Link in rank 4 (b) where the subtrees root formerly

b
62

16

Cut/Link Restructure Algorithm




Link in ranks 2 (a) and 6 (c) as 4s children.

4b
62

2 44

a
78

17

Cut/Link Restructure Algorithm




Finally, link in ranks 1,3,5, and 7 as the children of 2 and 6.

4y
62

z 2 44

x
78

6
88

17

3
48

5
50

54

T2 T3

T0

Now you have a balanced tree!

T1
18

Cut/Link Restructure algorithm




This algorithm for restructuring has the exact same effect as using the four rotation cases discussed earlier. Advantages: no case analysis, more elegant Disadvantage: can be more code to write Same time complexity

19

Removal
 

We can easily see that performing a removeAboveExternal(w) can cause T to become unbalanced. Let z be the first unbalanced node encountered while travelling up the tree from w. Also, let y be the child of z with the larger height, and let x be the child of y with the larger height. We can perform operation restructure(x) to restore balance at the subtree rooted at z. As this restructuring may upset the balance of another node higher in the tree, we must continue checking for balance until the root of T is reached
20

Removal (contd.)

1 17 2 50 1 1 54 0

example of deletion from an AVL tree:


44 4

O
y
62 3

,u

x
78 2 1 88

T0
32

48

T2 T1
y
62 3 4

T3

z
44 2 0 1 48 54

x
78 50 1

2 1 88

1 17

W w,

T2 T3
21

T0

Removal (contd.) example of deletion from an AVL tree:


z
4 44 1 17 2 50 1 1 48 32 54 0 88

y
62

3 2 78 1

T0

Oh no unbalanced!

T1
4 50 2 1 17

T2
x y
62

T3

z
44 1 48 1 54

3 2 78 0 88 1

Whew balanced!
22

T0

T1

T2

Implementation


A Java-based implementation of an AVL tree requires the following node class: public class AVLItem extends Item { int height; AVLItem(Object k, Object e, int h) { super(k, e); height = h;} public int height () { return height;} public int setHeight(int h) { int oldHeight = height; height = h; return oldHeight;} }

23

Implementation (contd.)
public class SimpleAVLTree extends SimpleBinarySearchTree implements Dictionary { public SimpleAVLTree(Comparator c) { super(c); T = new RestructurableNodeBinaryTree();} private int height(Position p) { if (T .isExternal(p)) return 0; else return ((AVLItem) p.element()). height(); } private void setHeight(Position p) { // called only if p is internal ((AVLItem) p. element()). setHeight (1+Math.max(height(T .leftChild(p)), height(T .rightChild(p)))); }
24

private boolean isBalanced(Position p) { // test whether node p has balance factor // between -1 and 1 int bf = height(T.leftChild(p)) - height(T.rightChild(p)); return ((-1 <= bf) && (bf <= 1));} private Position tallerChild(Position p) { // return a child of p with height no // smaller than that of the other child if(height(T.leftChild(p)) >= height(T.rightChild(p)); return T.leftChild(p); else return T.leftChild(p);}

Implementation (contd.)

25

Implementation (contd.) private void rebalance(Position zPos) {


//traverse the path of T from zPos to the root; for each node encountered //recompute its height and perform a rotation if it is unbalanced while (! T.isRoot(zPos)) { zPos = T.parent(zPos); setHeight(zPos); if (!isBalanced(zPos)) { // perform a rotation Position xPos = tallerChild(tallerChild(zPos)); zPos = ((RestructurableNodeBinaryTree)T) .restructure(xPos); setHeight(T.leftChild(zPos)); setHeight(T.rightChild(zPos)); setHeight(zPos); }}}
26

Implementation (contd.) public void insertItem(Object key, Object element)


throws InvalidKeyException { super.insertItem(key, element);// may throw an InvalidKeyException Position zPos = actionPos; // start at the insertion position T.replace(zPos, new AVLItem(key, element, 1)); rebalance(zPos);} public Object remove(Object key) throws InvalidKeyException { Object toReturn = super.remove(key); // may throw an InvalidKeyException if (toReturn != NO_SUCH_KEY) { Position zPos = actionPos; // start at the removal position rebalance(zPos);} return toReturn; 27 }}

Das könnte Ihnen auch gefallen