@@ -17,13 +17,9 @@ let utils;
17
17
( function ( _utils ) {
18
18
function comparator ( ) {
19
19
return function ( v1 , v2 ) {
20
- if ( v1 < v2 ) {
21
- return - 1
22
- } else if ( v2 < v1 ) {
23
- return 1
24
- } else {
25
- return 0
26
- }
20
+ if ( v1 < v2 ) return - 1
21
+ if ( v2 < v1 ) return 1
22
+ return 0
27
23
}
28
24
}
29
25
_utils . comparator = comparator
@@ -39,112 +35,118 @@ const AVLTree = (function () {
39
35
function _avl ( comp ) {
40
36
/** @public comparator function */
41
37
this . _comp = undefined
42
- if ( comp !== undefined ) {
43
- this . _comp = comp
44
- } else {
45
- this . _comp = utils . comparator ( )
46
- }
38
+ this . _comp = comp !== undefined ? comp : utils . comparator ( )
39
+
47
40
/** @public root of the AVL Tree */
48
41
this . root = null
49
42
/** @public number of elements in AVL Tree */
50
43
this . size = 0
51
44
}
45
+
52
46
// creates new Node Object
53
47
const Node = function ( val ) {
54
48
this . _val = val
55
49
this . _left = null
56
50
this . _right = null
57
51
this . _height = 1
58
52
}
53
+
59
54
// get height of a node
60
- const getH = function ( node ) {
55
+ const getHeight = function ( node ) {
61
56
if ( node == null ) { return 0 }
62
57
return node . _height
63
58
}
59
+
64
60
// height difference or balance factor of a node
65
- const getHDiff = function ( node ) {
66
- if ( node == null ) { return 0 } else { return getH ( node . _left ) - getH ( node . _right ) }
61
+ const getHeightDifference = function ( node ) {
62
+ return node == null ? 0 : getHeight ( node . _left ) - getHeight ( node . _right )
67
63
}
64
+
68
65
// update height of a node based on children's heights
69
- const updateH = function ( node ) {
70
- if ( node == null ) {
71
- return
72
- }
73
- node . _height = Math . max ( getH ( node . _left ) , getH ( node . _right ) ) + 1
66
+ const updateHeight = function ( node ) {
67
+ if ( node == null ) { return }
68
+ node . _height = Math . max ( getHeight ( node . _left ) , getHeight ( node . _right ) ) + 1
74
69
}
70
+
71
+ // Helper: To check if the balanceFactor is valid
72
+ const isValidBalanceFactor = ( balanceFactor ) => [ 0 , 1 , - 1 ] . includes ( balanceFactor )
73
+
75
74
// rotations of AVL Tree
76
75
const leftRotate = function ( node ) {
77
76
const temp = node . _right
78
77
node . _right = temp . _left
79
78
temp . _left = node
80
- updateH ( node )
81
- updateH ( temp )
79
+ updateHeight ( node )
80
+ updateHeight ( temp )
82
81
return temp
83
82
}
84
83
const rightRotate = function ( node ) {
85
84
const temp = node . _left
86
85
node . _left = temp . _right
87
86
temp . _right = node
88
- updateH ( node )
89
- updateH ( temp )
87
+ updateHeight ( node )
88
+ updateHeight ( temp )
90
89
return temp
91
90
}
91
+
92
92
// check if tree is balanced else balance it for insertion
93
93
const insertBalance = function ( node , _val , balanceFactor ) {
94
94
if ( balanceFactor > 1 && _val < node . _left . _val ) {
95
95
return rightRotate ( node ) // Left Left Case
96
- } else if ( balanceFactor < 1 && _val > node . _right . _val ) {
96
+ }
97
+ if ( balanceFactor < 1 && _val > node . _right . _val ) {
97
98
return leftRotate ( node ) // Right Right Case
98
- } else if ( balanceFactor > 1 && _val > node . _left . _val ) {
99
+ }
100
+ if ( balanceFactor > 1 && _val > node . _left . _val ) {
99
101
node . _left = leftRotate ( node . _left ) // Left Right Case
100
102
return rightRotate ( node )
101
103
}
102
104
node . _right = rightRotate ( node . _right )
103
105
return leftRotate ( node )
104
106
}
107
+
105
108
// check if tree is balanced after deletion
106
109
const delBalance = function ( node ) {
107
- const balanceFactor1 = getHDiff ( node )
108
- if ( balanceFactor1 === 0 || balanceFactor1 === 1 || balanceFactor1 === - 1 ) {
110
+ const balanceFactor1 = getHeightDifference ( node )
111
+ if ( isValidBalanceFactor ( balanceFactor1 ) ) {
109
112
return node
110
113
}
111
114
if ( balanceFactor1 > 1 ) {
112
- if ( getHDiff ( node . _left ) >= 0 ) {
115
+ if ( getHeightDifference ( node . _left ) >= 0 ) {
113
116
return rightRotate ( node ) // Left Left
114
117
}
115
118
node . _left = leftRotate ( node . _left )
116
119
return rightRotate ( node ) // Left Right
117
120
}
118
- if ( getHDiff ( node . _right ) > 0 ) {
121
+ if ( getHeightDifference ( node . _right ) > 0 ) {
119
122
node . _right = rightRotate ( node . _right )
120
123
return leftRotate ( node ) // Right Left
121
124
}
122
125
return leftRotate ( node ) // Right Right
123
126
}
127
+
124
128
// implement avl tree insertion
125
129
const insert = function ( root , val , tree ) {
126
130
if ( root == null ) {
127
131
tree . size ++
128
132
return new Node ( val )
129
- } else if ( tree . _comp ( root . _val , val ) < 0 ) {
133
+ }
134
+ if ( tree . _comp ( root . _val , val ) < 0 ) {
130
135
root . _right = insert ( root . _right , val , tree )
131
136
} else if ( tree . _comp ( root . _val , val ) > 0 ) {
132
137
root . _left = insert ( root . _left , val , tree )
133
138
} else {
134
139
return root
135
140
}
136
- updateH ( root )
137
- const balanceFactor = getHDiff ( root )
138
- if ( balanceFactor === 0 || balanceFactor === 1 || balanceFactor === - 1 ) {
139
- return root
140
- }
141
- return insertBalance ( root , val , balanceFactor )
141
+ updateHeight ( root )
142
+ const balanceFactor = getHeightDifference ( root )
143
+ return isValidBalanceFactor ( balanceFactor ) ? root : insertBalance ( root , val , balanceFactor )
142
144
}
143
- // delete a element
144
- const del = function ( root , _val , tree ) {
145
- if ( root == null ) {
146
- return root
147
- } else if ( tree . _comp ( root . _val , _val ) === 0 ) { // key found case
145
+
146
+ // delete am element
147
+ const deleteElement = function ( root , _val , tree ) {
148
+ if ( root == null ) { return root }
149
+ if ( tree . _comp ( root . _val , _val ) === 0 ) { // key found case
148
150
if ( root . _left === null && root . _right === null ) {
149
151
root = null
150
152
tree . size --
@@ -160,29 +162,29 @@ const AVLTree = (function () {
160
162
temp = temp . _left
161
163
}
162
164
root . _val = temp . _val
163
- root . _right = del ( root . _right , temp . _val , tree )
165
+ root . _right = deleteElement ( root . _right , temp . _val , tree )
164
166
}
165
167
} else {
166
168
if ( tree . _comp ( root . _val , _val ) < 0 ) {
167
- root . _right = del ( root . _right , _val , tree )
169
+ root . _right = deleteElement ( root . _right , _val , tree )
168
170
} else {
169
- root . _left = del ( root . _left , _val , tree )
171
+ root . _left = deleteElement ( root . _left , _val , tree )
170
172
}
171
173
}
172
- updateH ( root )
174
+ updateHeight ( root )
173
175
root = delBalance ( root )
174
176
return root
175
177
}
176
178
// search tree for a element
177
- const search = function ( root , val , tree ) {
178
- if ( root == null ) {
179
- return null
180
- } else if ( tree . _comp ( root . _val , val ) === 0 ) {
179
+ const searchAVLTree = function ( root , val , tree ) {
180
+ if ( root == null ) { return null }
181
+ if ( tree . _comp ( root . _val , val ) === 0 ) {
181
182
return root
182
- } else if ( tree . _comp ( root . _val , val ) < 0 ) {
183
- return search ( root . _right , val , tree )
184
183
}
185
- return search ( root . _left , val , tree )
184
+ if ( tree . _comp ( root . _val , val ) < 0 ) {
185
+ return searchAVLTree ( root . _right , val , tree )
186
+ }
187
+ return searchAVLTree ( root . _left , val , tree )
186
188
}
187
189
188
190
/* Public Functions */
@@ -196,22 +198,16 @@ const AVLTree = (function () {
196
198
_avl . prototype . add = function ( _val ) {
197
199
const prevSize = this . size
198
200
this . root = insert ( this . root , _val , this )
199
- if ( this . size === prevSize ) {
200
- return false
201
- }
202
- return true
201
+ return this . size !== prevSize
203
202
}
204
203
/**
205
204
* TO check is a particular element exists or not
206
205
* @param {any } _val
207
206
* @returns {Boolean } exists or not
208
207
*/
209
208
_avl . prototype . find = function ( _val ) {
210
- const temp = search ( this . root , _val , this )
211
- if ( temp != null ) {
212
- return true
213
- }
214
- return false
209
+ const temp = searchAVLTree ( this . root , _val , this )
210
+ return temp != null
215
211
}
216
212
/**
217
213
*
@@ -222,11 +218,8 @@ const AVLTree = (function () {
222
218
*/
223
219
_avl . prototype . remove = function ( _val ) {
224
220
const prevSize = this . size
225
- this . root = del ( this . root , _val , this )
226
- if ( prevSize === this . size ) {
227
- return false
228
- }
229
- return true
221
+ this . root = deleteElement ( this . root , _val , this )
222
+ return prevSize !== this . size
230
223
}
231
224
return _avl
232
225
} ( ) )
0 commit comments