Skip to content

Commit d23e542

Browse files
committed
Update AVL Explanation 27 Feb
1 parent c694f88 commit d23e542

File tree

2 files changed

+178
-112
lines changed

2 files changed

+178
-112
lines changed

src/algorithms/explanations/AVLExp.md

Lines changed: 86 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -1,139 +1,113 @@
11
# AVL Trees
22

3-
An AVL tree is **self-balancing** binary search tree.
3+
An AVL tree is **self-balancing** **binary search tree**.
44

5-
Because the AVL tree is always balanced, search will be *O(log n)*,
6-
no matter what the order of the input data.
5+
Unlike the basic binary search tree, which can exhibit *O(n)* worst case behavior for certain inputs, the AVL tree is always balanced, so search will be *O(log n)*
6+
regardless of the order of the input data.
77

8-
### Binary Search Trees
8+
### The Binary Search Tree Invariant
99

10-
A **binary tree** is either is either empty (`Empty`) or else it
11-
it has a root node and two subtrees (which are binary trees).
12-
The root node `t` has a key `t.key`. Ordinarily it would also
13-
hold other data (`t.data`), which the user would like to find by
14-
searching for the key. Since this attribute has no impact on
15-
how insertion and search take place, we disregard it here.
16-
Note that a newly inserted node will always appear as a leaf
17-
in the tree.
10+
A **binary tree (BST)** is either is either empty (`Empty`) or else it
11+
it has a root node and two subtrees (which are binary trees, and can also be empty).
12+
The root node `t` has a key `t.key`. Ordinarily every node would also
13+
hold other data (`t.data`), which the user would like to find by
14+
searching for the key, `e.g.` search for Student ID Number (key) to find street address (data).
15+
16+
Since the `data` attribute has no impact on
17+
how insertion and search take place, we disregard it in this animation.
18+
19+
20+
Note that a newly inserted node will always appear as a leaf
21+
in the tree.
1822

19-
In a **binary search tree (BST)** the BST invariant is always maintained:\
23+
In a binary search tree the **BST invariant** is always maintained:\
2024
for each
21-
subtree t, with root key t.key, the left subtree, t.left,
22-
contains no node with key greater than k, and the right subtree,
23-
t.right, contains no node with key smaller than k.
25+
subtree `t`, with root key `t.key`, the left subtree, `t.left`,
26+
contains no node with key greater than `t.key`, and the right subtree,
27+
`t.right`, contains no node with key smaller than `t.key`.
28+
29+
### AVL tree balancing
30+
31+
An AVL tree is **balanced** when the difference in heights of the left and right subtrees is no greater than `1`.
32+
2433

25-
### AVL tree balancing
2634

2735
The AVL tree preserves the balance of the tree by (1) checking after every insertion to detect
2836
when the tree has become unbalanced
29-
and (2) performing one or more rotation operations to restore balance when necessary.
30-
Unbalanced is defined as a difference of more than `1` between the heights of the left and right subtrees.
37+
and (2) performing one or more **rotation operations** to restore balance when necessary.
38+
The imbalance may be located at
39+
any node along the search path from the root of the tree to the newly inserted node, possibly the grandparent of the newly inserted node, or
40+
possibly
41+
considerably closer to the root of the tree.
42+
3143

32-
(Here **MAYBE insert small pictures, thumbnails?** to show -- unbalanced at gp of new node,
33-
and also balanced at gp but unblanaced at ggp.)
3444

35-
A temporarily unbalanced AVL tree takes on one of two configurations, *zig-zag* or *zig-zig*. The
45+
### Imbalance configurations
46+
47+
When a new node is inserted in an AVL tree, the tree may become *temporarily* unbalanced.
48+
A temporarily unbalanced AVL tree takes on one of two **configurations**, *zig-zag* or *zig-zig*. The
3649
sequence of rotations depends on the configuration around the node where the imbalance is detected.
3750

38-
### Zig-zig case
3951

40-
The *zig-zig* configuration has two mirror-image cases: the child and grandchild nodes or subtrees of the unbalanced node are
41-
either (1) both left subtrees or (2) both right subtrees.
52+
The **zig-zig** configuration has two mirror-image cases: the child and grandchild nodes or subtrees of the unbalanced node are
53+
either (1) both left subtrees or (2) both right subtrees. The **zig-zag** configuration also has two mirror-image cases: the child and grandchild nodes or subtrees of the unbalanced node are
54+
either (1) a left subtree and a right subtree or (2) a right subtrees and a left subtree.
55+
4256

4357

44-
## The left-left case
58+
59+
60+
Balance will be restored, using one or two **rotation**
61+
operations (see below).
62+
63+
### Insertion and rotation
64+
4565

46-
If the new key was added to the left child of a left child (the
47-
*left-left* case), the balance can be
48-
restored with a single _**Right Rotation**_ operation.
4966

50-
Note that the imbalance may be located further up the tree than the immediate grandparent of the newly inserted node:
5167

52-
**Insert very small diagrams showing (a) imbalance of the grandparent-parent and (b) imbalance of the great grandparent**
53-
*Note that all diagrams should hae nodes in BST order, and where the subtrees are not necessarily single nodes, represent them as subtree-triangles*
54-
*Have arrow showing which node is not in blanace*
5568

56-
In the diagrams below, t6 is the node where the imbalance is noted.
69+
**Insertion of a new item** into any binary tree requires (1) first the search to find the correct place to insert, then (2) the actual insertion.
5770

58-
As shown in the diagram below, t6 is the node at which the imbalance has been noted, and t2 is its left child. The clockwise rotation to restore balance makes t2 the parent of t6, while t6 is the *right* child of t2. Additionally, since t2 already had t4 as its right child, t4 is moved to become the left child of t6. Note that the BST invariant is preserved: t4, is bigger than t2, and is also smaller than t6. The rotation reduces the distance from the root to t1 (where the new node was added), so the tree is now
71+
In the **recursive implementation** shown in *AIA*, the first stage, determining
72+
the insertion point takes place
73+
during the *"wind up"* stage of the algorithm, where successive recursive *calls to `insert`* are made and accumulate on the machine stack. Search does not
74+
affect the balance of the tree. During the second stage, however, an imbalance may be introduced into the tree when the new node is actually inserted. The imbalance may be close to the new node, or may be
75+
considerably farther up the tree toward the root, along the search path. Therefore, during each successive *return* from the call to `insert`
76+
in the "unwind" stage of the algorithm, the height of the node is updated and the tree is checked for balance.
5977

60-
**I think there is something wrong with this diagram and the explanation**
61-
**unless t4 is empty, then the tree was already unbalance before 1 was added??**
78+
When an imbalance is detected, `i.e.` whenever the heights of the subtrees rooted at this node vary by more than `1`,
79+
a rotation
80+
or rotations are performed in order to bring the tree back into balance. **Rotation** is a **local operation**, involving only 6 pointer reassignments,
81+
yet it affects the balance of the tree overall.
82+
83+
Details of the **rotation**, **single** and **double** rotation are found in the AIA tab `More` for this algorithm.
6284

6385

6486

65-
, as explained in the diagram The 6 and 4 nodes and the edge between them rotate clockwise, and
66-
the 5 node changes parents from 4 to 6. This reduces the distance from
67-
the root to the 1 (where the new node was added), restoring the balance
68-
(the distance to the node rooted at 7 is increased but this does not
69-
cause the AVL tree balance condition to be violated). Right rotation is
70-
done by calling rightRotate(t6), where t6 is the tree rooted at 6.
71-
72-
![Alt text if image doesn't open: AVL-left-left](images/AVL/AVL-left-left.jpg){width=120,height=50} This picture is from Greek for Geeks, and is only a placeholder to show proof of concept inserting diagrams, and to check things like size and cropping.
73-
74-
75-
![Alt text if image doesn't open: AVL-left-left](Linda Stern/GitHub/algorithms-in-action.github.io/src/algorithms/explanationsimag/images/AVL/AVL-left-left.jpg){width=120,height=50} This picture is from Greek for Geeks, and is only a placeholder to show proof of concept inserting diagrams, and to check things like size and cropping.
76-
77-
Test comment
78-
79-
[This shouldn't be seen if the comment signal is correct]: #)
80-
81-
**Check whether the numbering here is still the same in the animation**
82-
**Note I have added a link to the parent of t6 -- check, since the pointer to the left child of this anonymous node needs to be changed, have we given it a number?**
83-
84-
**Lee - is t4 empty in this case? If not, then the tree would already have been unbalanced previously, when t4 was added??**
85-
86-
```
87-
/ /
88-
t6 t2
89-
/ \ Right Rotation / \
90-
t2 7 - - - - - - - > 1 t6
91-
/ \ < - - - - - - - / \
92-
1 t4 Left Rotation t4 7
93-
```
94-
95-
**9 Jan 4PM I haven't gone beyond this**
96-
97-
98-
## The right-right case
99-
100-
The right-right case is the exact opposite. If the tree on the right in
101-
the diagram above is too unbalanced due to insertion into the subtree
102-
rooted at 7, we can call rightRotate(t2) to lift that subtree and lower
103-
the 1 subtree.
104-
105-
## The left-right case (double rotation)
106-
107-
If the new key was added to the right child of the left child (the
108-
left-right case) and the resulting tree is too unbalanced, the balance can be
109-
restored with a left rotation at node 2 followed by a right rotation at
110-
node 6.
111-
```
112-
6 Rotate 6 Rotate 4
113-
/ \ left at 2 / \ right at 6 / \
114-
2 7 - - - - - > 4 7 - - - - - > 2 6
115-
/ \ / \ / \ / \
116-
1 4 2 5 1 3 5 7
117-
/ \ / \
118-
3 5 1 3
119-
```
120-
Nodes in the subtree rooted at 4 (where the extra element was added,
121-
making the tree unbalanced) are moved closer to the root.
122-
Trees rooted at 1, 3, 5 and 7 are not affected, except the distances from
123-
the root of 3, 5 and 7 are changed by one, affecting the overall balance.
124-
125-
## The right-left case (double rotation):
126-
127-
If the new key was added to the left child of the right child (the
128-
right-left case) and the resulting tree is too unbalanced, it is a mirror
129-
image of the left-right case:
130-
131-
```
132-
2 Rotate 2 Rotate 4
133-
/ \ right at 6 / \ left at 2 / \
134-
1 6 - - - - - > 1 4 - - - - - > 2 6
135-
/ \ / \ / \ / \
136-
4 7 3 6 1 3 5 7
137-
/ \ / \
138-
3 5 5 7
139-
```
87+
88+
89+
_**Suggested exercises in AIA**_
90+
91+
To **zig-zig and zig-zag configurations** and **rotation corrections** in AIA:
92+
93+
-For a left-left zig-zig configuration, enter 50, 40, then with the code expanded enter 30, step by step, to see the temporary left-left zig-zig imbalance, followed by a single rotation.\
94+
-For right-right zig-zig and single rotation, enter 30, 40, then slowly 50.\
95+
-For left-right zig-zag and double rotation, enter 50, 30, then slowly 40.\
96+
-For right-left zig-zag and double rotation enter 30, 50, then slowly 40.
97+
98+
In the above exercises the imbalance takes place near the newly inserted node. To see how an imbalance can quite remote, and how this is handled:
99+
100+
101+
For imbalance further up the tree from the newly inserted node:
102+
-Input 60,40,80,20,50,70,90,15,25,45,55,10. Insert 60..55 quickly (use the speed bar and collapse the pseudocode), then expand the pseudocode and proceed step by step as 10 is inserted.
103+
104+
105+
106+
107+
108+
109+
110+
111+
112+
113+

src/algorithms/extra-info/AVLInfo.md

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,95 @@ a:hover{
2020

2121
Geeks for Geeks Link:
2222
<a href="https://www.w3schools.com/dsa/dsa_data_avltrees.php" target="_blank">AVL Tree</a>
23+
24+
Insert detailed information about rotations here.
25+
26+
Rework the following original:
27+
28+
# Rotation in AVL trees
29+
30+
31+
In the diagrams below, t6 is the node where the imbalance is noted.
32+
33+
As shown in the diagram below, t6 is the node at which the imbalance has been noted, and t2 is its left child. The clockwise rotation to restore balance makes t2 the parent of t6, while t6 is the *right* child of t2. Additionally, since t2 already had t4 as its right child, t4 is moved to become the left child of t6. Note that the BST invariant is preserved: t4, is bigger than t2, and is also smaller than t6. The rotation reduces the distance from the root to t1 (where the new node was added), so the tree is now
34+
35+
36+
37+
38+
39+
40+
, as explained in the diagram The 6 and 4 nodes and the edge between them rotate clockwise, and
41+
the 5 node changes parents from 4 to 6. This reduces the distance from
42+
the root to the 1 (where the new node was added), restoring the balance
43+
(the distance to the node rooted at 7 is increased but this does not
44+
cause the AVL tree balance condition to be violated). Right rotation is
45+
done by calling rightRotate(t6), where t6 is the tree rooted at 6.
46+
47+
![Alt text if image doesn't open: AVL-left-left](images/AVL/AVL-left-left.jpg){width=120,height=50} This picture is from Greek for Geeks, and is only a placeholder to show proof of concept inserting diagrams, and to check things like size and cropping.
48+
49+
50+
![Alt text if image doesn't open: AVL-left-left](Linda Stern/GitHub/algorithms-in-action.github.io/src/algorithms/explanationsimag/images/AVL/AVL-left-left.jpg){width=120,height=50} This picture is from Greek for Geeks, and is only a placeholder to show proof of concept inserting diagrams, and to check things like size and cropping.
51+
52+
Test comment
53+
54+
[This shouldn't be seen if the comment signal is correct]: #)
55+
56+
**Check whether the numbering here is still the same in the animation**
57+
**Note I have added a link to the parent of t6 -- check, since the pointer to the left child of this anonymous node needs to be changed, have we given it a number?**
58+
59+
**Lee - is t4 empty in this case? If not, then the tree would already have been unbalanced previously, when t4 was added??**
60+
61+
```
62+
/ /
63+
t6 t2
64+
/ \ Right Rotation / \
65+
t2 7 - - - - - - - > 1 t6
66+
/ \ < - - - - - - - / \
67+
1 t4 Left Rotation t4 7
68+
```
69+
70+
**9 Jan 4PM I haven't gone beyond this**
71+
72+
73+
## The right-right case
74+
75+
The right-right case is the exact opposite. If the tree on the right in
76+
the diagram above is too unbalanced due to insertion into the subtree
77+
rooted at 7, we can call rightRotate(t2) to lift that subtree and lower
78+
the 1 subtree.
79+
80+
## The left-right case (double rotation)
81+
82+
If the new key was added to the right child of the left child (the
83+
left-right case) and the resulting tree is too unbalanced, the balance can be
84+
restored with a left rotation at node 2 followed by a right rotation at
85+
node 6.
86+
```
87+
6 Rotate 6 Rotate 4
88+
/ \ left at 2 / \ right at 6 / \
89+
2 7 - - - - - > 4 7 - - - - - > 2 6
90+
/ \ / \ / \ / \
91+
1 4 2 5 1 3 5 7
92+
/ \ / \
93+
3 5 1 3
94+
```
95+
Nodes in the subtree rooted at 4 (where the extra element was added,
96+
making the tree unbalanced) are moved closer to the root.
97+
Trees rooted at 1, 3, 5 and 7 are not affected, except the distances from
98+
the root of 3, 5 and 7 are changed by one, affecting the overall balance.
99+
100+
## The right-left case (double rotation):
101+
102+
If the new key was added to the left child of the right child (the
103+
right-left case) and the resulting tree is too unbalanced, it is a mirror
104+
image of the left-right case:
105+
106+
```
107+
2 Rotate 2 Rotate 4
108+
/ \ right at 6 / \ left at 2 / \
109+
1 6 - - - - - > 1 4 - - - - - > 2 6
110+
/ \ / \ / \ / \
111+
4 7 3 6 1 3 5 7
112+
/ \ / \
113+
3 5 5 7
114+
```

0 commit comments

Comments
 (0)