Skip to content

Commit c9701e8

Browse files
rahulrajrdgithub-actions
andauthored
merge: Improving the coding standard for AvLTree Data Structure (#882)
* Improving the coding standard for AvLTree Data Structure * Test case creation for AVLTree ~ Created test cases for AVL Tree ~ Indentation fix for AVLTree.js * Auto-update DIRECTORY.md * Change in logic for data list * Style fix based on standard.js Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com>
1 parent 6bd2ac6 commit c9701e8

File tree

2 files changed

+90
-67
lines changed

2 files changed

+90
-67
lines changed

Data-Structures/Tree/AVLTree.js

Lines changed: 60 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,9 @@ let utils;
1717
(function (_utils) {
1818
function comparator () {
1919
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
2723
}
2824
}
2925
_utils.comparator = comparator
@@ -39,112 +35,118 @@ const AVLTree = (function () {
3935
function _avl (comp) {
4036
/** @public comparator function */
4137
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+
4740
/** @public root of the AVL Tree */
4841
this.root = null
4942
/** @public number of elements in AVL Tree */
5043
this.size = 0
5144
}
45+
5246
// creates new Node Object
5347
const Node = function (val) {
5448
this._val = val
5549
this._left = null
5650
this._right = null
5751
this._height = 1
5852
}
53+
5954
// get height of a node
60-
const getH = function (node) {
55+
const getHeight = function (node) {
6156
if (node == null) { return 0 }
6257
return node._height
6358
}
59+
6460
// 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)
6763
}
64+
6865
// 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
7469
}
70+
71+
// Helper: To check if the balanceFactor is valid
72+
const isValidBalanceFactor = (balanceFactor) => [0, 1, -1].includes(balanceFactor)
73+
7574
// rotations of AVL Tree
7675
const leftRotate = function (node) {
7776
const temp = node._right
7877
node._right = temp._left
7978
temp._left = node
80-
updateH(node)
81-
updateH(temp)
79+
updateHeight(node)
80+
updateHeight(temp)
8281
return temp
8382
}
8483
const rightRotate = function (node) {
8584
const temp = node._left
8685
node._left = temp._right
8786
temp._right = node
88-
updateH(node)
89-
updateH(temp)
87+
updateHeight(node)
88+
updateHeight(temp)
9089
return temp
9190
}
91+
9292
// check if tree is balanced else balance it for insertion
9393
const insertBalance = function (node, _val, balanceFactor) {
9494
if (balanceFactor > 1 && _val < node._left._val) {
9595
return rightRotate(node) // Left Left Case
96-
} else if (balanceFactor < 1 && _val > node._right._val) {
96+
}
97+
if (balanceFactor < 1 && _val > node._right._val) {
9798
return leftRotate(node) // Right Right Case
98-
} else if (balanceFactor > 1 && _val > node._left._val) {
99+
}
100+
if (balanceFactor > 1 && _val > node._left._val) {
99101
node._left = leftRotate(node._left) // Left Right Case
100102
return rightRotate(node)
101103
}
102104
node._right = rightRotate(node._right)
103105
return leftRotate(node)
104106
}
107+
105108
// check if tree is balanced after deletion
106109
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)) {
109112
return node
110113
}
111114
if (balanceFactor1 > 1) {
112-
if (getHDiff(node._left) >= 0) {
115+
if (getHeightDifference(node._left) >= 0) {
113116
return rightRotate(node) // Left Left
114117
}
115118
node._left = leftRotate(node._left)
116119
return rightRotate(node) // Left Right
117120
}
118-
if (getHDiff(node._right) > 0) {
121+
if (getHeightDifference(node._right) > 0) {
119122
node._right = rightRotate(node._right)
120123
return leftRotate(node) // Right Left
121124
}
122125
return leftRotate(node) // Right Right
123126
}
127+
124128
// implement avl tree insertion
125129
const insert = function (root, val, tree) {
126130
if (root == null) {
127131
tree.size++
128132
return new Node(val)
129-
} else if (tree._comp(root._val, val) < 0) {
133+
}
134+
if (tree._comp(root._val, val) < 0) {
130135
root._right = insert(root._right, val, tree)
131136
} else if (tree._comp(root._val, val) > 0) {
132137
root._left = insert(root._left, val, tree)
133138
} else {
134139
return root
135140
}
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)
142144
}
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
148150
if (root._left === null && root._right === null) {
149151
root = null
150152
tree.size--
@@ -160,29 +162,29 @@ const AVLTree = (function () {
160162
temp = temp._left
161163
}
162164
root._val = temp._val
163-
root._right = del(root._right, temp._val, tree)
165+
root._right = deleteElement(root._right, temp._val, tree)
164166
}
165167
} else {
166168
if (tree._comp(root._val, _val) < 0) {
167-
root._right = del(root._right, _val, tree)
169+
root._right = deleteElement(root._right, _val, tree)
168170
} else {
169-
root._left = del(root._left, _val, tree)
171+
root._left = deleteElement(root._left, _val, tree)
170172
}
171173
}
172-
updateH(root)
174+
updateHeight(root)
173175
root = delBalance(root)
174176
return root
175177
}
176178
// 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) {
181182
return root
182-
} else if (tree._comp(root._val, val) < 0) {
183-
return search(root._right, val, tree)
184183
}
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)
186188
}
187189

188190
/* Public Functions */
@@ -196,22 +198,16 @@ const AVLTree = (function () {
196198
_avl.prototype.add = function (_val) {
197199
const prevSize = this.size
198200
this.root = insert(this.root, _val, this)
199-
if (this.size === prevSize) {
200-
return false
201-
}
202-
return true
201+
return this.size !== prevSize
203202
}
204203
/**
205204
* TO check is a particular element exists or not
206205
* @param {any} _val
207206
* @returns {Boolean} exists or not
208207
*/
209208
_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
215211
}
216212
/**
217213
*
@@ -222,11 +218,8 @@ const AVLTree = (function () {
222218
*/
223219
_avl.prototype.remove = function (_val) {
224220
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
230223
}
231224
return _avl
232225
}())
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { AVLTree } from '../AVLTree'
2+
3+
describe('AVLTree Implementation: ', () => {
4+
const avlTree = new AVLTree()
5+
const dataList = []
6+
const demoData = [1, 4, 6, 22, 7, 99, 4, 66, 77, 98]
7+
8+
beforeAll(() => {
9+
demoData.forEach(item => {
10+
if (avlTree.add(item)) {
11+
dataList.push(item)
12+
}
13+
})
14+
})
15+
16+
it('checks if element is inserted properly', () => {
17+
expect(dataList.length).toEqual(avlTree.size)
18+
})
19+
20+
it('search if inserted element is present', () => {
21+
demoData.forEach(data => {
22+
expect(avlTree.find(data)).toBeTruthy()
23+
})
24+
})
25+
26+
it('deletes the inserted element', () => {
27+
const deleteElement = dataList[3]
28+
expect(avlTree.remove(deleteElement)).toBeTruthy()
29+
})
30+
})

0 commit comments

Comments
 (0)