Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 3786c16

Browse files
avl tree docs
1 parent a4fee40 commit 3786c16

File tree

4 files changed

+86
-19
lines changed

4 files changed

+86
-19
lines changed

‎book/chapters/tree--avl.adoc‎

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,60 @@
11
= AVL Tree
22

3+
AVL Tree is named after their inventors (**A**delson-**V**elsky and **L**andis).
4+
This self-balancing tree keep track of subtree sizes to know if a rebalance is needed or not.
5+
We can compare the size of the left and right subtrees using a balance factor.
6+
7+
[NOTE]
8+
====
9+
10+
The *balanced factor* on each node is calculated recurviely as follows:
11+
12+
----
13+
Balance Factor = (left subtree height) - (right subtree height)
14+
----
15+
16+
====
17+
18+
The implementation will got into the BST node.
19+
We will need two methods to calculate the left and right subtree, and with those we can get the balance factor.
20+
21+
.Balance Factor methods on the BST node
22+
[source, javascript]
23+
----
24+
include::{codedir}/data-structures/trees/binary-tree-node.js[tag=avl, indent=0]
25+
----
26+
27+
28+
== Implementing AVL Tree
29+
30+
Implementing an AVL Tree is not too hard, since it builds upon what we did in the Binary Search Tree.
31+
32+
.AVL Tree class
33+
[source, javascript]
34+
----
35+
include::{codedir}/data-structures/trees/avl-tree.js[tag=AvlTree]
36+
----
37+
38+
As you can see, AVL tree inherits from the BST class.
39+
The insert and remove operations works the same as in the BST, except that at the end we call `balanceUptream`.
40+
This function makes balance the tree after every change if is needed. Let's see how it's implemented.
41+
42+
.Balance Upstream for AVL tree
43+
[source, javascript]
44+
----
45+
include::{codedir}/data-structures/trees/avl-tree.js[tag=balanceUptream]
46+
----
47+
48+
This function recurively goes from the modified node to the root checking if each node in between is balanced.
49+
Now, let's examine how does the balancing works on AVL tree.
50+
51+
.Balance method for AVL tree
52+
[source, javascript]
53+
----
54+
include::{codedir}/data-structures/trees/avl-tree.js[tag=balance]
55+
----
56+
57+
The first thing we do is to see if one subtree is longer than the other.
58+
If so, then we check the children balance to determine if need a single or double rotation and in which direction.
59+
60+
You can review <<Tree Roations>> in case you want a refresher.

‎src/data-structures/trees/avl-tree.js‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ function balanceUptream(node) {
6464
class AvlTree extends BinarySearchTree {
6565
/**
6666
* Add node to tree. It self-balance itself.
67-
*
6867
* @param {any} value node's value
6968
*/
7069
add(value) {

‎src/data-structures/trees/binary-tree-node.js‎

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,21 @@ class BinaryTreeNode {
114114
this.meta.color = value;
115115
}
116116

117+
// tag::avl[]
118+
/**
119+
* @returns {Number} left subtree height or 0 if no left child
120+
*/
121+
get leftSubtreeHeight() {
122+
return this.left ? this.left.height + 1 : 0;
123+
}
124+
125+
/**
126+
* @returns {Number} right subtree height or 0 if no right child
127+
*/
128+
get rightSubtreeHeight() {
129+
return this.right ? this.right.height + 1 : 0;
130+
}
131+
117132
/**
118133
* Get the max height of the subtrees.
119134
*
@@ -125,20 +140,13 @@ class BinaryTreeNode {
125140
return Math.max(this.leftSubtreeHeight, this.rightSubtreeHeight);
126141
}
127142

128-
get leftSubtreeHeight() {
129-
return this.left ? this.left.height + 1 : 0;
130-
}
131-
132-
get rightSubtreeHeight() {
133-
return this.right ? this.right.height + 1 : 0;
134-
}
135-
136143
/**
137144
* Returns the difference the heights on the left and right subtrees
138145
*/
139146
get balanceFactor() {
140147
return this.leftSubtreeHeight - this.rightSubtreeHeight;
141148
}
149+
// end::avl[]
142150

143151
/**
144152
* Serialize node's values

‎src/data-structures/trees/tree-rotations.js‎

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ function leftRotation(node) {
7777
* /
7878
* 1
7979
*
80-
* @param {TreeNode} node this is the node we want to rotate to the right. (E.g., node 3)
80+
* @param {TreeNode} node
81+
* this is the node we want to rotate to the right. (E.g., node 3)
8182
* @returns {TreeNode} new parent after the rotation (E.g., node 2)
8283
*/
8384
function rightRotation(node) {
@@ -103,14 +104,15 @@ function rightRotation(node) {
103104
*
104105
* @example LR rotation on node 3
105106
* 4 4
106-
* / / 4
107-
* 3 3* /
108-
* / / 2
109-
* 1* --left-rotation(1)-> 2 --right-rotation(3)-> / \
110-
* \ / 1 3*
107+
* / / 4
108+
* 3 3* /
109+
* / / 2
110+
* 1* --left-rotation(1)-> 2 --right-rotation(3)-> / \
111+
* \ / 1 3*
111112
* 2 1
112113
*
113-
* @param {TreeNode} node this is the node we want to rotate to the right. E.g., node 3
114+
* @param {TreeNode} node
115+
* this is the node we want to rotate to the right. E.g., node 3
114116
* @returns {TreeNode} new parent after the rotation
115117
*/
116118
function leftRightRotation(node) {
@@ -126,9 +128,9 @@ function leftRightRotation(node) {
126128
* @example RL rotation on 1
127129
*
128130
* 1* 1*
129-
* \ \ 2
130-
* 3 -right-rotation(3)-> 2 -left-rotation(1)-> / \
131-
* / \ 1* 3
131+
* \ \ 2
132+
* 3 -right-rotation(3)-> 2 -left-rotation(1)-> / \
133+
* / \ 1* 3
132134
* 2 3
133135
*
134136
* @param {TreeNode} node

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /