Content-Length: 36958 | pFad | http://github.com/TheAlgorithms/JavaScript/pull/1656.patch
thub.com
From 0144e775ba498a4cc604d941b52ccd866f074a91 Mon Sep 17 00:00:00 2001
From: hasanalkaf3
Date: Sun, 7 Apr 2024 09:56:39 +0300
Subject: [PATCH 1/2] chore: convert functions to an ES2015 classes
---
Conversions/RailwayTimeConversion.js | 4 +-
Data-Structures/Array/Reverse.js | 8 +-
Data-Structures/Stack/Stack.js | 68 +++---
Data-Structures/Tree/AVLTree.js | 99 ++++----
Data-Structures/Tree/BinarySearchTree.js | 184 +++++++--------
Data-Structures/Tree/Trie.js | 215 +++++++++---------
.../NumberOfSubsetEqualToGivenSum.js | 2 +-
Project-Euler/Problem004.js | 2 +-
8 files changed, 297 insertions(+), 285 deletions(-)
diff --git a/Conversions/RailwayTimeConversion.js b/Conversions/RailwayTimeConversion.js
index 15f837b0da..b499023223 100644
--- a/Conversions/RailwayTimeConversion.js
+++ b/Conversions/RailwayTimeConversion.js
@@ -24,8 +24,8 @@ const RailwayTimeConversion = (timeString) => {
const [hour, minute, secondWithShift] = timeString.split(':')
// split second and shift value.
const [second, shift] = [
- secondWithShift.substr(0, 2),
- secondWithShift.substr(2)
+ secondWithShift.substring(0, 2),
+ secondWithShift.substring(2)
]
// convert shifted time to not-shift time(Railway time) by using the above explanation.
if (shift === 'PM') {
diff --git a/Data-Structures/Array/Reverse.js b/Data-Structures/Array/Reverse.js
index 79a789c017..a889c67e4b 100644
--- a/Data-Structures/Array/Reverse.js
+++ b/Data-Structures/Array/Reverse.js
@@ -7,11 +7,9 @@
const Reverse = (arr) => {
// limit specifies the amount of Reverse actions
- for (let i = 0, j = arr.length - 1; i < arr.length / 2; i++, j--) {
- const temp = arr[i]
- arr[i] = arr[j]
- arr[j] = temp
- }
+ for (let i = 0, j = arr.length - 1; i < arr.length / 2; i++, j--)
+ [arr[i], arr[j]] = [arr[j], arr[i]] // Swapping elements ES6 way
+
return arr
}
export { Reverse }
diff --git a/Data-Structures/Stack/Stack.js b/Data-Structures/Stack/Stack.js
index d3001e8020..129f3898c0 100644
--- a/Data-Structures/Stack/Stack.js
+++ b/Data-Structures/Stack/Stack.js
@@ -9,45 +9,47 @@
// Creates a stack constructor
const Stack = (function () {
- function Stack() {
- // The top of the Stack
- this.top = 0
- // The array representation of the stack
- this.stack = []
- }
-
- // Adds a value onto the end of the stack
- Stack.prototype.push = function (value) {
- this.stack[this.top] = value
- this.top++
- }
+ class Stack {
+ constructor() {
+ // The top of the Stack
+ this.top = 0
+ // The array representation of the stack
+ this.stack = []
+ }
- // Removes and returns the value at the end of the stack
- Stack.prototype.pop = function () {
- if (this.top === 0) {
- return 'Stack is Empty'
+ // Adds a value onto the end of the stack
+ push(value) {
+ this.stack[this.top] = value
+ this.top++
}
- this.top--
- const result = this.stack[this.top]
- this.stack = this.stack.splice(0, this.top)
- return result
- }
+ // Removes and returns the value at the end of the stack
+ pop() {
+ if (this.top === 0) {
+ return 'Stack is Empty'
+ }
- // Returns the size of the stack
- Stack.prototype.size = function () {
- return this.top
- }
+ this.top--
+ const result = this.stack[this.top]
+ this.stack = this.stack.splice(0, this.top)
+ return result
+ }
- // Returns the value at the end of the stack
- Stack.prototype.peek = function () {
- return this.stack[this.top - 1]
- }
+ // Returns the size of the stack
+ size() {
+ return this.top
+ }
+
+ // Returns the value at the end of the stack
+ peek() {
+ return this.stack[this.top - 1]
+ }
- // To see all the elements in the stack
- Stack.prototype.view = function (output = (value) => console.log(value)) {
- for (let i = 0; i < this.top; i++) {
- output(this.stack[i])
+ // To see all the elements in the stack
+ view(output = (value) => console.log(value)) {
+ for (let i = 0; i < this.top; i++) {
+ output(this.stack[i])
+ }
}
}
diff --git a/Data-Structures/Tree/AVLTree.js b/Data-Structures/Tree/AVLTree.js
index e5abbf3e55..5418c576e4 100644
--- a/Data-Structures/Tree/AVLTree.js
+++ b/Data-Structures/Tree/AVLTree.js
@@ -32,23 +32,62 @@ let utils
* If no argument is sent it uses utils.comparator
*/
const AVLTree = (function () {
- function _avl(comp) {
- /** @public comparator function */
- this._comp = undefined
- this._comp = comp !== undefined ? comp : utils.comparator()
+ class _avl {
+ constructor(comp) {
+ /** @public comparator function */
+ this._comp = undefined
+ this._comp = comp !== undefined ? comp : utils.comparator()
- /** @public root of the AVL Tree */
- this.root = null
- /** @public number of elements in AVL Tree */
- this.size = 0
+ /** @public root of the AVL Tree */
+ this.root = null
+ /** @public number of elements in AVL Tree */
+ this.size = 0
+ }
+
+ /* Public Functions */
+ /**
+ * For Adding Elements to AVL Tree
+ * @param {any} _val
+ * Since in AVL Tree an element can only occur once so
+ * if a element exists it return false
+ * @returns {Boolean} element added or not
+ */
+ 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
+ */
+ find(_val) {
+ const temp = searchAVLTree(this.root, _val, this)
+ return temp != null
+ }
+ /**
+ *
+ * @param {any} _val
+ * It is possible that element doesn't exists in tree
+ * in that case it return false
+ * @returns {Boolean} if element was found and deleted
+ */
+ remove(_val) {
+ const prevSize = this.size
+ this.root = deleteElement(this.root, _val, this)
+ return prevSize !== this.size
+ }
}
// creates new Node Object
- const Node = function (val) {
- this._val = val
- this._left = null
- this._right = null
- this._height = 1
+ class Node {
+ constructor(val) {
+ this._val = val
+ this._left = null
+ this._right = null
+ this._height = 1
+ }
}
// get height of a node
@@ -199,40 +238,6 @@ const AVLTree = (function () {
return searchAVLTree(root._left, val, tree)
}
- /* Public Functions */
- /**
- * For Adding Elements to AVL Tree
- * @param {any} _val
- * Since in AVL Tree an element can only occur once so
- * if a element exists it return false
- * @returns {Boolean} element added or not
- */
- _avl.prototype.add = function (_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) {
- const temp = searchAVLTree(this.root, _val, this)
- return temp != null
- }
- /**
- *
- * @param {any} _val
- * It is possible that element doesn't exists in tree
- * in that case it return false
- * @returns {Boolean} if element was found and deleted
- */
- _avl.prototype.remove = function (_val) {
- const prevSize = this.size
- this.root = deleteElement(this.root, _val, this)
- return prevSize !== this.size
- }
return _avl
})()
diff --git a/Data-Structures/Tree/BinarySearchTree.js b/Data-Structures/Tree/BinarySearchTree.js
index c86a2995c0..abbcc3fb62 100644
--- a/Data-Structures/Tree/BinarySearchTree.js
+++ b/Data-Structures/Tree/BinarySearchTree.js
@@ -13,77 +13,79 @@
// class Node
const Node = (function Node() {
// Node in the tree
- function Node(val) {
- this.value = val
- this.left = null
- this.right = null
- }
-
- // Search the tree for a value
- Node.prototype.search = function (val) {
- if (this.value === val) {
- return this
- } else if (val < this.value && this.left !== null) {
- return this.left.search(val)
- } else if (val > this.value && this.right !== null) {
- return this.right.search(val)
+ class Node {
+ constructor(val) {
+ this.value = val
+ this.left = null
+ this.right = null
}
- return null
- }
- // Visit a node
- Node.prototype.visit = function (output = (value) => console.log(value)) {
- // Recursively go left
- if (this.left !== null) {
- this.left.visit()
- }
- // Print out value
- output(this.value)
- // Recursively go right
- if (this.right !== null) {
- this.right.visit()
+ // Search the tree for a value
+ search(val) {
+ if (this.value === val) {
+ return this
+ } else if (val < this.value && this.left !== null) {
+ return this.left.search(val)
+ } else if (val > this.value && this.right !== null) {
+ return this.right.search(val)
+ }
+ return null
}
- }
- // Add a node
- Node.prototype.addNode = function (n) {
- if (n.value < this.value) {
- if (this.left === null) {
- this.left = n
- } else {
- this.left.addNode(n)
+ // Visit a node
+ visit(output = (value) => console.log(value)) {
+ // Recursively go left
+ if (this.left !== null) {
+ this.left.visit()
}
- } else if (n.value > this.value) {
- if (this.right === null) {
- this.right = n
- } else {
- this.right.addNode(n)
+ // Print out value
+ output(this.value)
+ // Recursively go right
+ if (this.right !== null) {
+ this.right.visit()
}
}
- }
- // remove a node
- Node.prototype.removeNode = function (val) {
- if (val === this.value) {
- if (!this.left && !this.right) {
- return null
- } else {
- if (this.left) {
- const leftMax = maxVal(this.left)
- this.value = leftMax
- this.left = this.left.removeNode(leftMax)
+ // Add a node
+ addNode(n) {
+ if (n.value < this.value) {
+ if (this.left === null) {
+ this.left = n
} else {
- const rightMin = minVal(this.right)
- this.value = rightMin
- this.right = this.right.removeNode(rightMin)
+ this.left.addNode(n)
+ }
+ } else if (n.value > this.value) {
+ if (this.right === null) {
+ this.right = n
+ } else {
+ this.right.addNode(n)
}
}
- } else if (val < this.value) {
- this.left = this.left && this.left.removeNode(val)
- } else if (val > this.value) {
- this.right = this.right && this.right.removeNode(val)
}
- return this
+
+ // remove a node
+ removeNode(val) {
+ if (val === this.value) {
+ if (!this.left && !this.right) {
+ return null
+ } else {
+ if (this.left) {
+ const leftMax = maxVal(this.left)
+ this.value = leftMax
+ this.left = this.left.removeNode(leftMax)
+ } else {
+ const rightMin = minVal(this.right)
+ this.value = rightMin
+ this.right = this.right.removeNode(rightMin)
+ }
+ }
+ } else if (val < this.value) {
+ this.left = this.left && this.left.removeNode(val)
+ } else if (val > this.value) {
+ this.right = this.right && this.right.removeNode(val)
+ }
+ return this
+ }
}
// find maximum value in the tree
@@ -107,44 +109,46 @@ const Node = (function Node() {
// class Tree
const Tree = (function () {
- function Tree() {
- // Just store the root
- this.root = null
- }
+ class Tree {
+ constructor() {
+ // Just store the root
+ this.root = null
+ }
- // Inorder traversal
- Tree.prototype.traverse = function () {
- if (!this.root) {
- // No nodes are there in the tree till now
- return
+ // Inorder traversal
+ traverse() {
+ if (!this.root) {
+ // No nodes are there in the tree till now
+ return
+ }
+ this.root.visit()
}
- this.root.visit()
- }
- // Start by searching the root
- Tree.prototype.search = function (val) {
- const found = this.root.search(val)
- if (found !== null) {
- return found.value
+ // Start by searching the root
+ search(val) {
+ const found = this.root.search(val)
+ if (found !== null) {
+ return found.value
+ }
+ // not found
+ return null
}
- // not found
- return null
- }
- // Add a new value to the tree
- Tree.prototype.addValue = function (val) {
- const n = new Node(val)
- if (this.root === null) {
- this.root = n
- } else {
- this.root.addNode(n)
+ // Add a new value to the tree
+ addValue(val) {
+ const n = new Node(val)
+ if (this.root === null) {
+ this.root = n
+ } else {
+ this.root.addNode(n)
+ }
}
- }
- // remove a value from the tree
- Tree.prototype.removeValue = function (val) {
- // remove something if root exists
- this.root = this.root && this.root.removeNode(val)
+ // remove a value from the tree
+ removeValue(val) {
+ // remove something if root exists
+ this.root = this.root && this.root.removeNode(val)
+ }
}
// returns the constructor
diff --git a/Data-Structures/Tree/Trie.js b/Data-Structures/Tree/Trie.js
index ea59e53846..0d4018f74f 100644
--- a/Data-Structures/Tree/Trie.js
+++ b/Data-Structures/Tree/Trie.js
@@ -1,129 +1,132 @@
-const TrieNode = function TrieNode(key, parent) {
- this.key = key
- this.count = 0
- this.children = Object.create(null)
- if (parent === undefined) {
- this.parent = null
- } else {
- this.parent = parent
+class TrieNode {
+ constructor(key, parent) {
+ this.key = key
+ this.count = 0
+ this.children = Object.create(null)
+ if (parent === undefined) {
+ this.parent = null
+ } else {
+ this.parent = parent
+ }
}
}
-function Trie() {
- // create only root with null key and parent
- this.root = new TrieNode(null, null)
-}
+class Trie {
+ constructor() {
+ // create only root with null key and parent
+ this.root = new TrieNode(null, null)
+ }
-// Recursively finds the occurrence of all words in a given node
-Trie.findAllWords = function (root, word, output) {
- if (root === null) return
- if (root.count > 0) {
- if (typeof output === 'object') {
- output.push({ word, count: root.count })
+ // Recursively finds the occurrence of all words in a given node
+ static findAllWords(root, word, output) {
+ if (root === null) return
+ if (root.count > 0) {
+ if (typeof output === 'object') {
+ output.push({ word, count: root.count })
+ }
+ }
+ let key
+ for (key in root.children) {
+ word += key
+ this.findAllWords(root.children[key], word, output)
+ word = word.slice(0, -1)
}
}
- let key
- for (key in root.children) {
- word += key
- this.findAllWords(root.children[key], word, output)
- word = word.slice(0, -1)
- }
-}
-Trie.prototype.insert = function (word) {
- if (typeof word !== 'string') return
- if (word === '') {
- this.root.count += 1
- return
- }
- let node = this.root
- const len = word.length
- let i
- for (i = 0; i < len; i++) {
- if (node.children[word.charAt(i)] === undefined) {
- node.children[word.charAt(i)] = new TrieNode(word.charAt(i), node)
+ insert(word) {
+ if (typeof word !== 'string') return
+ if (word === '') {
+ this.root.count += 1
+ return
+ }
+ let node = this.root
+ const len = word.length
+ let i
+ for (i = 0; i < len; i++) {
+ if (node.children[word.charAt(i)] === undefined) {
+ node.children[word.charAt(i)] = new TrieNode(word.charAt(i), node)
+ }
+ node = node.children[word.charAt(i)]
}
- node = node.children[word.charAt(i)]
+ node.count += 1
}
- node.count += 1
-}
-Trie.prototype.findPrefix = function (word) {
- if (typeof word !== 'string') return null
- let node = this.root
- const len = word.length
- let i
- // After end of this loop node will be at desired prefix
- for (i = 0; i < len; i++) {
- if (node.children[word.charAt(i)] === undefined) return null // No such prefix exists
- node = node.children[word.charAt(i)]
+ findPrefix(word) {
+ if (typeof word !== 'string') return null
+ let node = this.root
+ const len = word.length
+ let i
+ // After end of this loop node will be at desired prefix
+ for (i = 0; i < len; i++) {
+ if (node.children[word.charAt(i)] === undefined) return null // No such prefix exists
+ node = node.children[word.charAt(i)]
+ }
+ return node
}
- return node
-}
-Trie.prototype.remove = function (word, count) {
- if (typeof word !== 'string') return
- if (typeof count !== 'number') count = 1
- else if (count <= 0) return
+ remove(word, count) {
+ if (typeof word !== 'string') return
+ if (typeof count !== 'number') count = 1
+ else if (count <= 0) return
- // for empty string just delete count of root
- if (word === '') {
- if (this.root.count >= count) this.root.count -= count
- else this.root.count = 0
- return
- }
+ // for empty string just delete count of root
+ if (word === '') {
+ if (this.root.count >= count) this.root.count -= count
+ else this.root.count = 0
+ return
+ }
- let child = this.root
- const len = word.length
- let i, key
- // child: node which is to be deleted
- for (i = 0; i < len; i++) {
- key = word.charAt(i)
- if (child.children[key] === undefined) return
- child = child.children[key]
- }
+ let child = this.root
+ const len = word.length
+ let i, key
+ // child: node which is to be deleted
+ for (i = 0; i < len; i++) {
+ key = word.charAt(i)
+ if (child.children[key] === undefined) return
+ child = child.children[key]
+ }
- // Delete no of occurrences specified
- if (child.count >= count) child.count -= count
- else child.count = 0
+ // Delete no of occurrences specified
+ if (child.count >= count) child.count -= count
+ else child.count = 0
- // If some occurrences are left we don't delete it or else
- // if the object forms some other objects prefix we don't delete it
- // For checking an empty object
- // https://stackoverflow.com/questions/679915/how-do-i-test-for-an-empty-javascript-object
- if (
- child.count <= 0 &&
- Object.keys(child.children).length &&
- child.children.constructor === Object
- ) {
- child.parent.children[child.key] = undefined
+ // If some occurrences are left we don't delete it or else
+ // if the object forms some other objects prefix we don't delete it
+ // For checking an empty object
+ // https://stackoverflow.com/questions/679915/how-do-i-test-for-an-empty-javascript-object
+ if (
+ child.count <= 0 &&
+ Object.keys(child.children).length &&
+ child.children.constructor === Object
+ ) {
+ child.parent.children[child.key] = undefined
+ }
}
-}
-Trie.prototype.findAllWords = function (prefix) {
- const output = []
- // find the node with provided prefix
- const node = this.findPrefix(prefix)
- // No such prefix exists
- if (node === null) return output
- Trie.findAllWords(node, prefix, output)
- return output
-}
-
-Trie.prototype.contains = function (word) {
- // find the node with given prefix
- const node = this.findPrefix(word)
- // No such word exists
+ findAllWords(prefix) {
+ const output = []
+ // find the node with provided prefix
+ const node = this.findPrefix(prefix)
+ // No such prefix exists
+ if (node === null) return output
+ Trie.findAllWords(node, prefix, output)
+ return output
+ }
- return node !== null && node.count !== 0
-}
+ contains(word) {
+ // find the node with given prefix
+ const node = this.findPrefix(word)
+ // No such word exists
+ return node !== null && node.count !== 0
+ }
-Trie.prototype.findOccurrences = function (word) {
- // find the node with given prefix
- const node = this.findPrefix(word)
- // No such word exists
- if (node === null) return 0
- return node.count
+ findOccurrences(word) {
+ // find the node with given prefix
+ const node = this.findPrefix(word)
+ // No such word exists
+ if (node === null) return 0
+ return node.count
+ }
}
export { Trie }
diff --git a/Dynamic-Programming/NumberOfSubsetEqualToGivenSum.js b/Dynamic-Programming/NumberOfSubsetEqualToGivenSum.js
index dee12f8de9..48905c39e2 100644
--- a/Dynamic-Programming/NumberOfSubsetEqualToGivenSum.js
+++ b/Dynamic-Programming/NumberOfSubsetEqualToGivenSum.js
@@ -4,7 +4,7 @@ determine the total number of the subset with sum
equal to the given sum.
*/
/*
- Given solution is O(n*sum) Time complexity and O(sum) Space complexity
+ Given solution is O(n*sum) Time complexity and O(sum) Space complexity
*/
function NumberOfSubsetSum(array, sum) {
const dp = [] // create an dp array where dp[i] denote number of subset with sum equal to i
diff --git a/Project-Euler/Problem004.js b/Project-Euler/Problem004.js
index 34fa87471d..7c85dfdb85 100644
--- a/Project-Euler/Problem004.js
+++ b/Project-Euler/Problem004.js
@@ -1,6 +1,6 @@
// https://projecteuler.net/problem=4
/* A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99.
- Find the largest palindrome made from the product of two 3-digit numbers.
+ Find the largest palindrome made from the product of two 3-digit numbers.
*/
export const largestPalindromic = (digits) => {
let i
From 554a002f3bb5145ee0fa50b4942ad032c4212d01 Mon Sep 17 00:00:00 2001
From: hasanalkaf3
Date: Tue, 9 Apr 2024 00:59:21 +0300
Subject: [PATCH 2/2] remove unnecessary functions
---
Data-Structures/Array/Reverse.js | 2 +-
Data-Structures/Stack/Stack.js | 74 +++----
Data-Structures/Tree/AVLTree.js | 358 +++++++++++++++----------------
3 files changed, 214 insertions(+), 220 deletions(-)
diff --git a/Data-Structures/Array/Reverse.js b/Data-Structures/Array/Reverse.js
index a889c67e4b..ca08f35f8a 100644
--- a/Data-Structures/Array/Reverse.js
+++ b/Data-Structures/Array/Reverse.js
@@ -8,7 +8,7 @@
const Reverse = (arr) => {
// limit specifies the amount of Reverse actions
for (let i = 0, j = arr.length - 1; i < arr.length / 2; i++, j--)
- [arr[i], arr[j]] = [arr[j], arr[i]] // Swapping elements ES6 way
+ [arr[i], arr[j]] = [arr[j], arr[i]]
return arr
}
diff --git a/Data-Structures/Stack/Stack.js b/Data-Structures/Stack/Stack.js
index 129f3898c0..d8531fdebf 100644
--- a/Data-Structures/Stack/Stack.js
+++ b/Data-Structures/Stack/Stack.js
@@ -8,52 +8,48 @@
// Functions: push, pop, peek, view, length
// Creates a stack constructor
-const Stack = (function () {
- class Stack {
- constructor() {
- // The top of the Stack
- this.top = 0
- // The array representation of the stack
- this.stack = []
- }
-
- // Adds a value onto the end of the stack
- push(value) {
- this.stack[this.top] = value
- this.top++
- }
+class Stack {
+ constructor() {
+ // The top of the Stack
+ this.top = 0
+ // The array representation of the stack
+ this.stack = []
+ }
- // Removes and returns the value at the end of the stack
- pop() {
- if (this.top === 0) {
- return 'Stack is Empty'
- }
+ // Adds a value onto the end of the stack
+ push(value) {
+ this.stack[this.top] = value
+ this.top++
+ }
- this.top--
- const result = this.stack[this.top]
- this.stack = this.stack.splice(0, this.top)
- return result
+ // Removes and returns the value at the end of the stack
+ pop() {
+ if (this.top === 0) {
+ return 'Stack is Empty'
}
- // Returns the size of the stack
- size() {
- return this.top
- }
+ this.top--
+ const result = this.stack[this.top]
+ this.stack = this.stack.splice(0, this.top)
+ return result
+ }
- // Returns the value at the end of the stack
- peek() {
- return this.stack[this.top - 1]
- }
+ // Returns the size of the stack
+ size() {
+ return this.top
+ }
- // To see all the elements in the stack
- view(output = (value) => console.log(value)) {
- for (let i = 0; i < this.top; i++) {
- output(this.stack[i])
- }
- }
+ // Returns the value at the end of the stack
+ peek() {
+ return this.stack[this.top - 1]
}
- return Stack
-})()
+ // To see all the elements in the stack
+ view(output = (value) => console.log(value)) {
+ for (let i = 0; i < this.top; i++) {
+ output(this.stack[i])
+ }
+ }
+}
export { Stack }
diff --git a/Data-Structures/Tree/AVLTree.js b/Data-Structures/Tree/AVLTree.js
index 5418c576e4..dd673a9330 100644
--- a/Data-Structures/Tree/AVLTree.js
+++ b/Data-Structures/Tree/AVLTree.js
@@ -31,215 +31,213 @@ let utils
* @argument comp - A function used by AVL Tree For Comparison
* If no argument is sent it uses utils.comparator
*/
-const AVLTree = (function () {
- class _avl {
- constructor(comp) {
- /** @public comparator function */
- this._comp = undefined
- this._comp = comp !== undefined ? comp : utils.comparator()
+class AVLTree {
+ constructor(comp) {
+ /** @public comparator function */
+ this._comp = undefined
+ this._comp = comp !== undefined ? comp : utils.comparator()
- /** @public root of the AVL Tree */
- this.root = null
- /** @public number of elements in AVL Tree */
- this.size = 0
- }
+ /** @public root of the AVL Tree */
+ this.root = null
+ /** @public number of elements in AVL Tree */
+ this.size = 0
+ }
- /* Public Functions */
- /**
- * For Adding Elements to AVL Tree
- * @param {any} _val
- * Since in AVL Tree an element can only occur once so
- * if a element exists it return false
- * @returns {Boolean} element added or not
- */
- 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
- */
- find(_val) {
- const temp = searchAVLTree(this.root, _val, this)
- return temp != null
- }
- /**
- *
- * @param {any} _val
- * It is possible that element doesn't exists in tree
- * in that case it return false
- * @returns {Boolean} if element was found and deleted
- */
- remove(_val) {
- const prevSize = this.size
- this.root = deleteElement(this.root, _val, this)
- return prevSize !== this.size
- }
+ /* Public Functions */
+ /**
+ * For Adding Elements to AVL Tree
+ * @param {any} _val
+ * Since in AVL Tree an element can only occur once so
+ * if a element exists it return false
+ * @returns {Boolean} element added or not
+ */
+ add(_val) {
+ const prevSize = this.size
+ this.root = insert(this.root, _val, this)
+ return this.size !== prevSize
}
- // creates new Node Object
- class Node {
- constructor(val) {
- this._val = val
- this._left = null
- this._right = null
- this._height = 1
- }
+ /**
+ * TO check is a particular element exists or not
+ * @param {any} _val
+ * @returns {Boolean} exists or not
+ */
+ find(_val) {
+ const temp = searchAVLTree(this.root, _val, this)
+ return temp != null
}
- // get height of a node
- const getHeight = function (node) {
- if (node == null) {
- return 0
- }
- return node._height
+ /**
+ *
+ * @param {any} _val
+ * It is possible that element doesn't exists in tree
+ * in that case it return false
+ * @returns {Boolean} if element was found and deleted
+ */
+ remove(_val) {
+ const prevSize = this.size
+ this.root = deleteElement(this.root, _val, this)
+ return prevSize !== this.size
}
+}
- // height difference or balance factor of a node
- const getHeightDifference = function (node) {
- return node == null ? 0 : getHeight(node._left) - getHeight(node._right)
+// creates new Node Object
+class Node {
+ constructor(val) {
+ this._val = val
+ this._left = null
+ this._right = null
+ this._height = 1
}
+}
- // 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
+// 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)
- // 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
+}
- // 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
+// 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
}
- const rightRotate = function (node) {
- const temp = node._left
- node._left = temp._right
- temp._right = node
- updateHeight(node)
- updateHeight(temp)
- return temp
+ 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 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)
+// 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)
+ return leftRotate(node) // Right Left
}
+ return leftRotate(node) // Right Right
+}
- // 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)
}
-
- // 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)
+ 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)
- }
+// 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 {
- if (tree._comp(root._val, _val) < 0) {
- root._right = deleteElement(root._right, _val, tree)
- } else {
- root._left = deleteElement(root._left, _val, tree)
+ 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)
+ }
+ 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
}
- // 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)
+ if (tree._comp(root._val, val) < 0) {
+ return searchAVLTree(root._right, val, tree)
}
-
- return _avl
-})()
+ return searchAVLTree(root._left, val, tree)
+}
/**
* A Code for Testing the AVLTree
--- a PPN by Garber Painting Akron. With Image Size Reduction included!Fetched URL: http://github.com/TheAlgorithms/JavaScript/pull/1656.patch
Alternative Proxies:
Alternative Proxy
pFad Proxy
pFad v3 Proxy
pFad v4 Proxy