Skip to content

Commit bc0ffff

Browse files
ClémentClément
authored andcommitted
Minor improvments on AVL trees.
1 parent a838d7f commit bc0ffff

7 files changed

Lines changed: 64 additions & 11 deletions

File tree

source/code/projects/AVLTree/AVLTree/AVLTree.cs

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@ public int Height
2525
}
2626

2727
public Node(
28-
T d = default(T),
28+
T dataP = default(T),
2929
Node leftP = null,
3030
Node rightP = null,
3131
int heightP = 0
3232
)
3333
{
34-
Data = d;
34+
Data = dataP;
3535
left = leftP;
3636
right = rightP;
3737
Height = heightP;
@@ -96,9 +96,7 @@ private int UpdateHeight(Node nodeP)
9696
return height;
9797
}
9898

99-
private int SubtreeBalance(Node nodeP)
100-
{
101-
// Will return
99+
// The following will return
102100
// a negative number if subtree is right-heavy
103101
// a positive number if subtree is left-heavy
104102
// 0 if the subtree is perfectly balanced.
@@ -107,6 +105,8 @@ private int SubtreeBalance(Node nodeP)
107105
// less than or equal to -2.
108106
// Stated differently, if the value returned is
109107
// -1, 0 or 1, then no re-balancing will take place.
108+
private int SubtreeBalance(Node nodeP)
109+
{
110110
UpdateHeight(nodeP.left);
111111
UpdateHeight(nodeP.right);
112112
int balance;
@@ -233,6 +233,18 @@ private Node RotaterightChild(Node nodeTop) // Aka right-right rotation
233233
* D C
234234
* / \
235235
* F G
236+
*
237+
* The simplified version is:
238+
* Before:
239+
* A
240+
* /
241+
* B
242+
* \
243+
* E
244+
* After:
245+
* E
246+
* / \
247+
* B A
236248
*/
237249

238250
private Node DoubleleftChild(Node nodeP)
@@ -292,7 +304,7 @@ private Node Insert(T valueP, Node nodeP)
292304
throw new ApplicationException(
293305
"Tree did not insert "
294306
+ valueP
295-
+ " since an item with that value is already in the tree"
307+
+ " since an item with that value is already in the tree."
296308
);
297309
}
298310

@@ -450,4 +462,4 @@ private string Stringify(Node nodeP, int depth)
450462
}
451463
return returned;
452464
}
453-
}
465+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
%%% A left-left heavy binary search tree
2+
3+
A((10))-->B((5))
4+
A-->C((20))
5+
B-->D((4))
6+
B-->E((6))
7+
D-->F((2))
8+
D~~~H1:::hidden

source/diag/gra/bstree_example_6.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
%%% The binary search tree obtained by inserting 1, 2, …, 1000 (in that order).
1+
%%% The binary search tree obtained by inserting 1, 2, …, 100 (in that order).
22

33
A((1))~~~H1:::hidden
44
A-->B((2))

source/diag/gra/bstree_example_7.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
%%% A balanced binary search tree containing 1, 2, …, 1000.
1+
%%% A balanced binary search tree containing 1, 2, …, 100.
22

33
A((64))-->B((32))
44
A-->C((80))
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
%%% An almost unbalanced binary search tree
2+
3+
A((10))-->B((5))
4+
A-->C((20))
5+
B-->D((4))
6+
B-->E((6))
7+
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
%%% A left-right heavy binary search tree
2+
3+
A((10))-->B((5))
4+
A-->C((20))
5+
B-->D((4))
6+
B-->E((6))
7+
E~~~H1:::hidden
8+
E-->F((7))

source/lectures/data/AVLtrees.md

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ The resulting tree would be much more efficient if we were leveraging the proper
2222

2323
This is precisely the point of AVL trees, which are binary search trees with the additional property:
2424

25-
> The heights of the two child subtrees of any node differ by at most one; if at any time they differ by more than one, rebalancing is done to restore this property.
25+
> The heights of the two child subtrees of any node differ by at most one; if at any time they differ by more than one, re-balancing is done to restore this property.
2626
2727
where
2828

@@ -33,6 +33,25 @@ A good way of [remembering the difference](https://stackoverflow.com/q/2603692)
3333

3434
## Possible Implementation
3535

36+
The main challenge is to "re-balance" the tree when needed.
37+
To determine if a tree needs to be re-balanced, one has to compute its "balance factor", obtained by substracting the right subtree height from the left subtree height. This is done below in the `SubtreeBalance` method.
38+
39+
Consider the following:
40+
41+
!include diag/gra/bstree_example_8.md
42+
43+
After inserting 2, the tree becomes:
44+
45+
!include diag/gra/bstree_example_10.md
46+
47+
which needs to be re-balanced using the `RotateleftChild` method given below. Indeed it is "left-heavy", on the left-hand side (because the left sub-tree, with root 5, is deeper, because of its left side).
48+
49+
If, re-using the same example, we insert 7, then the tree becomes:
50+
51+
!include diag/gra/bstree_example_9.md
52+
53+
which needs to be re-balanced using the `Doubleleftchild` method given below. Indeed it is "left-heavy", on the right-hand side (because the left sub-tree, with root 5, is deeper, because of its right side).
54+
3655
### Storing the height in the node
3756

3857
```{download="./code/projects/AVLTree.zip"}
@@ -43,4 +62,3 @@ A good way of [remembering the difference](https://stackoverflow.com/q/2603692)
4362

4463
It is also possible to compute the height of nodes "on the fly" instead of storing it.
4564
[This archive](./code/projects/AVLTree_I.zip) demonstrates this concept while additionally inheriting from the `BTree` class [explored previously](./lectures/data/trees).
46-

0 commit comments

Comments
 (0)