chore: convert functions to an ES2015 classes (#1656)

* chore: convert functions to an ES2015 classes

* remove unnecessary functions
This commit is contained in:
Hasan Al-Kaf
2024-04-13 20:51:54 +03:00
committed by GitHub
parent 314144fae6
commit 6fe21d21e9
8 changed files with 392 additions and 386 deletions

View File

@ -31,8 +31,8 @@ let utils
* @argument comp - A function used by AVL Tree For Comparison
* If no argument is sent it uses utils.comparator
*/
const AVLTree = (function () {
function _avl(comp) {
class AVLTree {
constructor(comp) {
/** @public comparator function */
this._comp = undefined
this._comp = comp !== undefined ? comp : utils.comparator()
@ -43,162 +43,6 @@ const AVLTree = (function () {
this.size = 0
}
// creates new Node Object
const Node = function (val) {
this._val = val
this._left = null
this._right = null
this._height = 1
}
// get height of a node
const getHeight = function (node) {
if (node == null) {
return 0
}
return node._height
}
// height difference or balance factor of a node
const getHeightDifference = function (node) {
return node == null ? 0 : getHeight(node._left) - getHeight(node._right)
}
// update height of a node based on children's heights
const updateHeight = function (node) {
if (node == null) {
return
}
node._height = Math.max(getHeight(node._left), getHeight(node._right)) + 1
}
// Helper: To check if the balanceFactor is valid
const isValidBalanceFactor = (balanceFactor) =>
[0, 1, -1].includes(balanceFactor)
// rotations of AVL Tree
const leftRotate = function (node) {
const temp = node._right
node._right = temp._left
temp._left = node
updateHeight(node)
updateHeight(temp)
return temp
}
const rightRotate = function (node) {
const temp = node._left
node._left = temp._right
temp._right = node
updateHeight(node)
updateHeight(temp)
return temp
}
// check if tree is balanced else balance it for insertion
const insertBalance = function (node, _val, balanceFactor, tree) {
if (balanceFactor > 1 && tree._comp(_val, node._left._val) < 0) {
return rightRotate(node) // Left Left Case
}
if (balanceFactor < 1 && tree._comp(_val, node._right._val) > 0) {
return leftRotate(node) // Right Right Case
}
if (balanceFactor > 1 && tree._comp(_val, node._left._val) > 0) {
node._left = leftRotate(node._left) // Left Right Case
return rightRotate(node)
}
node._right = rightRotate(node._right)
return leftRotate(node)
}
// check if tree is balanced after deletion
const delBalance = function (node) {
const balanceFactor1 = getHeightDifference(node)
if (isValidBalanceFactor(balanceFactor1)) {
return node
}
if (balanceFactor1 > 1) {
if (getHeightDifference(node._left) >= 0) {
return rightRotate(node) // Left Left
}
node._left = leftRotate(node._left)
return rightRotate(node) // Left Right
}
if (getHeightDifference(node._right) > 0) {
node._right = rightRotate(node._right)
return leftRotate(node) // Right Left
}
return leftRotate(node) // Right Right
}
// implement avl tree insertion
const insert = function (root, val, tree) {
if (root == null) {
tree.size++
return new Node(val)
}
if (tree._comp(root._val, val) < 0) {
root._right = insert(root._right, val, tree)
} else if (tree._comp(root._val, val) > 0) {
root._left = insert(root._left, val, tree)
} else {
return root
}
updateHeight(root)
const balanceFactor = getHeightDifference(root)
return isValidBalanceFactor(balanceFactor)
? root
: insertBalance(root, val, balanceFactor, tree)
}
// delete am element
const deleteElement = function (root, _val, tree) {
if (root == null) {
return root
}
if (tree._comp(root._val, _val) === 0) {
// key found case
if (root._left === null && root._right === null) {
root = null
tree.size--
} else if (root._left === null) {
root = root._right
tree.size--
} else if (root._right === null) {
root = root._left
tree.size--
} else {
let temp = root._right
while (temp._left != null) {
temp = temp._left
}
root._val = temp._val
root._right = deleteElement(root._right, temp._val, tree)
}
} else {
if (tree._comp(root._val, _val) < 0) {
root._right = deleteElement(root._right, _val, tree)
} else {
root._left = deleteElement(root._left, _val, tree)
}
}
updateHeight(root)
root = delBalance(root)
return root
}
// search tree for a element
const searchAVLTree = function (root, val, tree) {
if (root == null) {
return null
}
if (tree._comp(root._val, val) === 0) {
return root
}
if (tree._comp(root._val, val) < 0) {
return searchAVLTree(root._right, val, tree)
}
return searchAVLTree(root._left, val, tree)
}
/* Public Functions */
/**
* For Adding Elements to AVL Tree
@ -207,20 +51,22 @@ const AVLTree = (function () {
* if a element exists it return false
* @returns {Boolean} element added or not
*/
_avl.prototype.add = function (_val) {
add(_val) {
const prevSize = this.size
this.root = insert(this.root, _val, this)
return this.size !== prevSize
}
/**
* TO check is a particular element exists or not
* @param {any} _val
* @returns {Boolean} exists or not
*/
_avl.prototype.find = function (_val) {
find(_val) {
const temp = searchAVLTree(this.root, _val, this)
return temp != null
}
/**
*
* @param {any} _val
@ -228,13 +74,170 @@ const AVLTree = (function () {
* in that case it return false
* @returns {Boolean} if element was found and deleted
*/
_avl.prototype.remove = function (_val) {
remove(_val) {
const prevSize = this.size
this.root = deleteElement(this.root, _val, this)
return prevSize !== this.size
}
return _avl
})()
}
// creates new Node Object
class Node {
constructor(val) {
this._val = val
this._left = null
this._right = null
this._height = 1
}
}
// get height of a node
const getHeight = function (node) {
if (node == null) {
return 0
}
return node._height
}
// height difference or balance factor of a node
const getHeightDifference = function (node) {
return node == null ? 0 : getHeight(node._left) - getHeight(node._right)
}
// update height of a node based on children's heights
const updateHeight = function (node) {
if (node == null) {
return
}
node._height = Math.max(getHeight(node._left), getHeight(node._right)) + 1
}
// Helper: To check if the balanceFactor is valid
const isValidBalanceFactor = (balanceFactor) =>
[0, 1, -1].includes(balanceFactor)
// rotations of AVL Tree
const leftRotate = function (node) {
const temp = node._right
node._right = temp._left
temp._left = node
updateHeight(node)
updateHeight(temp)
return temp
}
const rightRotate = function (node) {
const temp = node._left
node._left = temp._right
temp._right = node
updateHeight(node)
updateHeight(temp)
return temp
}
// check if tree is balanced else balance it for insertion
const insertBalance = function (node, _val, balanceFactor, tree) {
if (balanceFactor > 1 && tree._comp(_val, node._left._val) < 0) {
return rightRotate(node) // Left Left Case
}
if (balanceFactor < 1 && tree._comp(_val, node._right._val) > 0) {
return leftRotate(node) // Right Right Case
}
if (balanceFactor > 1 && tree._comp(_val, node._left._val) > 0) {
node._left = leftRotate(node._left) // Left Right Case
return rightRotate(node)
}
node._right = rightRotate(node._right)
return leftRotate(node)
}
// check if tree is balanced after deletion
const delBalance = function (node) {
const balanceFactor1 = getHeightDifference(node)
if (isValidBalanceFactor(balanceFactor1)) {
return node
}
if (balanceFactor1 > 1) {
if (getHeightDifference(node._left) >= 0) {
return rightRotate(node) // Left Left
}
node._left = leftRotate(node._left)
return rightRotate(node) // Left Right
}
if (getHeightDifference(node._right) > 0) {
node._right = rightRotate(node._right)
return leftRotate(node) // Right Left
}
return leftRotate(node) // Right Right
}
// implement avl tree insertion
const insert = function (root, val, tree) {
if (root == null) {
tree.size++
return new Node(val)
}
if (tree._comp(root._val, val) < 0) {
root._right = insert(root._right, val, tree)
} else if (tree._comp(root._val, val) > 0) {
root._left = insert(root._left, val, tree)
} else {
return root
}
updateHeight(root)
const balanceFactor = getHeightDifference(root)
return isValidBalanceFactor(balanceFactor)
? root
: insertBalance(root, val, balanceFactor, tree)
}
// delete am element
const deleteElement = function (root, _val, tree) {
if (root == null) {
return root
}
if (tree._comp(root._val, _val) === 0) {
// key found case
if (root._left === null && root._right === null) {
root = null
tree.size--
} else if (root._left === null) {
root = root._right
tree.size--
} else if (root._right === null) {
root = root._left
tree.size--
} else {
let temp = root._right
while (temp._left != null) {
temp = temp._left
}
root._val = temp._val
root._right = deleteElement(root._right, temp._val, tree)
}
} else {
if (tree._comp(root._val, _val) < 0) {
root._right = deleteElement(root._right, _val, tree)
} else {
root._left = deleteElement(root._left, _val, tree)
}
}
updateHeight(root)
root = delBalance(root)
return root
}
// search tree for a element
const searchAVLTree = function (root, val, tree) {
if (root == null) {
return null
}
if (tree._comp(root._val, val) === 0) {
return root
}
if (tree._comp(root._val, val) < 0) {
return searchAVLTree(root._right, val, tree)
}
return searchAVLTree(root._left, val, tree)
}
/**
* A Code for Testing the AVLTree