diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e70010..5ee2402 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ All notable changes to this project will be documented in this file. - [Semantic Versioning](https://semver.org/spec/v2.0.0.html) - [`auto-changelog`](https://github.com/CookPete/auto-changelog) -## [v1.47.8](https://github.com/zrwusa/data-structure-typed/compare/v1.35.0...main) (upcoming) +## [v1.47.9](https://github.com/zrwusa/data-structure-typed/compare/v1.35.0...main) (upcoming) ### Changes diff --git a/README.md b/README.md index bb437f0..1e2291a 100644 --- a/README.md +++ b/README.md @@ -12,17 +12,7 @@ Data Structures of Javascript & TypeScript. Do you envy C++ with [STL]() (std::), Python with [collections](), and Java with [java.util]() ? Well, no need to envy -anymore! JavaScript and TypeScript now have [data-structure-typed](). - -Now you can use this in Node.js and browser environments - -CommonJS:**`require export.modules =`** - -ESModule:   **`import export`** - -Typescript:   **`import export`** - -UMD:           **`var Deque = dataStructureTyped.Deque`** +anymore! JavaScript and TypeScript now have [data-structure-typed]().**`Benchmark`** compared with C++ STL. **`API standards`** aligned with ES6 and Java. **`Usability`** is comparable to Python [//]: # (![Branches](https://img.shields.io/badge/branches-55.47%25-red.svg?style=flat)) @@ -35,6 +25,17 @@ UMD:           **`var Deq ## Installation and Usage +Now you can use it in Node.js and browser environments + +CommonJS:**`require export.modules =`** + +ESModule:   **`import export`** + +Typescript:   **`import export`** + +UMD:           **`var Deque = dataStructureTyped.Deque`** + + ### npm ```bash @@ -474,127 +475,127 @@ avl2.print(); Binary Tree -Binary Tree +View Binary Search Tree (BST) -BST +View AVL Tree -AVLTree +View Red Black Tree -RedBlackTree +View Tree Multiset -TreeMultimap +View Segment Tree -SegmentTree +View Binary Indexed Tree -BinaryIndexedTree +View Heap -Heap +View Priority Queue -PriorityQueue +View Max Priority Queue -MaxPriorityQueue +View Min Priority Queue -MinPriorityQueue +View Trie -Trie +View Graph -AbstractGraph +View Directed Graph -DirectedGraph +View Undirected Graph -UndirectedGraph +View Queue -Queue +View Deque -Deque +View Linked List -SinglyLinkedList +View Singly Linked List -SinglyLinkedList +View Doubly Linked List -DoublyLinkedList +View Stack -Stack +View diff --git a/package.json b/package.json index 52c08d7..fb00d29 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "data-structure-typed", - "version": "1.47.8", + "version": "1.47.9", "description": "Data Structures of Javascript & TypeScript. Heap, Binary Tree, RedBlack Tree, Linked List, Deque, Trie, HashMap, Directed Graph, Undirected Graph, Binary Search Tree(BST), AVL Tree, Priority Queue, Graph, Queue, Tree Multiset, Singly Linked List, Doubly Linked List, Max Heap, Max Priority Queue, Min Heap, Min Priority Queue, Stack.", "main": "dist/cjs/index.js", "module": "dist/mjs/index.js", diff --git a/src/data-structures/binary-tree/avl-tree.ts b/src/data-structures/binary-tree/avl-tree.ts index 3302ffb..d5e13b0 100644 --- a/src/data-structures/binary-tree/avl-tree.ts +++ b/src/data-structures/binary-tree/avl-tree.ts @@ -82,6 +82,15 @@ export class AVLTree = AVLTreeNode`. + * @returns a boolean value indicating whether the exemplar is an instance of the AVLTreeNode class. + */ + override isNode(exemplar: BTNodeExemplar): exemplar is N { + return exemplar instanceof AVLTreeNode; + } + /** * Time Complexity: O(log n) - logarithmic time, where "n" is the number of nodes in the tree. The add method of the superclass (BST) has logarithmic time complexity. * Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size. diff --git a/src/data-structures/binary-tree/binary-tree.ts b/src/data-structures/binary-tree/binary-tree.ts index ab42492..b1a8957 100644 --- a/src/data-structures/binary-tree/binary-tree.ts +++ b/src/data-structures/binary-tree/binary-tree.ts @@ -163,6 +163,47 @@ export class BinaryTree = BinaryTreeNode return new BinaryTree([], { iterationType: this.iterationType, ...options }) as TREE; } + /** + * The function "isNode" checks if an exemplar is an instance of the BinaryTreeNode class. + * @param exemplar - The `exemplar` parameter is a variable of type `BTNodeExemplar`. + * @returns a boolean value indicating whether the exemplar is an instance of the class N. + */ + isNode(exemplar: BTNodeExemplar): exemplar is N { + return exemplar instanceof BinaryTreeNode; + } + + /** + * The function `exemplarToNode` converts an exemplar of a binary tree node into an actual node + * object. + * @param exemplar - BTNodeExemplar - A generic type representing the exemplar parameter of the + * function. It can be any type. + * @returns a value of type `N` (which represents a node), or `null`, or `undefined`. + */ + exemplarToNode(exemplar: BTNodeExemplar): N | null | undefined { + if (exemplar === undefined) return; + + let node: N | null | undefined; + if (exemplar === null) { + node = null; + } else if (this.isEntry(exemplar)) { + const [key, value] = exemplar; + if (key === undefined) { + return; + } else if (key === null) { + node = null; + } else { + node = this.createNode(key, value); + } + } else if (this.isNode(exemplar)) { + node = exemplar; + } else if (this.isNodeKey(exemplar)) { + node = this.createNode(exemplar); + } else { + return; + } + return node; + } + /** * The function checks if a given value is an entry in a binary tree node. * @param kne - BTNodeExemplar - A generic type representing a node in a binary tree. It has @@ -188,7 +229,9 @@ export class BinaryTree = BinaryTreeNode */ add(keyOrNodeOrEntry: BTNodeExemplar): N | null | undefined { - let inserted: N | null | undefined, needInsert: N | null | undefined; + let inserted: N | null | undefined; + const newNode = this.exemplarToNode(keyOrNodeOrEntry); + if (newNode === undefined) return; const _bfs = (root: N, newNode: N | null): N | undefined | null => { const queue = new Queue([root]); @@ -205,30 +248,11 @@ export class BinaryTree = BinaryTreeNode } }; - if (keyOrNodeOrEntry === null) { - needInsert = null; - } else if (this.isNodeKey(keyOrNodeOrEntry)) { - needInsert = this.createNode(keyOrNodeOrEntry); - } else if (keyOrNodeOrEntry instanceof BinaryTreeNode) { - needInsert = keyOrNodeOrEntry; - } else if (this.isEntry(keyOrNodeOrEntry)) { - const [key, value] = keyOrNodeOrEntry; - if (key === undefined) { - return; - } else if (key === null) { - needInsert = null; - } else { - needInsert = this.createNode(key, value); - } - } else { - return; - } - if (this.root) { - inserted = _bfs(this.root, needInsert); + inserted = _bfs(this.root, newNode); } else { - this._setRoot(needInsert); - if (needInsert) { + this._setRoot(newNode); + if (newNode) { this._size = 1; } else { this._size = 0; diff --git a/src/data-structures/binary-tree/bst.ts b/src/data-structures/binary-tree/bst.ts index 0b69c1c..e46adc0 100644 --- a/src/data-structures/binary-tree/bst.ts +++ b/src/data-structures/binary-tree/bst.ts @@ -143,6 +143,42 @@ export class BST = BSTNode> }) as TREE; } + /** + * The function checks if an exemplar is an instance of BSTNode. + * @param exemplar - The `exemplar` parameter is a variable of type `BTNodeExemplar`. + * @returns a boolean value indicating whether the exemplar is an instance of the BSTNode class. + */ + override isNode(exemplar: BTNodeExemplar): exemplar is N { + return exemplar instanceof BSTNode; + } + + /** + * The function `exemplarToNode` takes an exemplar and returns a corresponding node if the exemplar + * is valid, otherwise it returns undefined. + * @param exemplar - The `exemplar` parameter is of type `BTNodeExemplar`. + * @returns a variable `node` which is of type `N` or `undefined`. + */ + override exemplarToNode(exemplar: BTNodeExemplar): N | undefined { + let node: N | undefined; + if (exemplar === null || exemplar === undefined) { + return; + } else if (this.isNode(exemplar)) { + node = exemplar; + } else if (this.isEntry(exemplar)) { + const [key, value] = exemplar; + if (key === undefined || key === null) { + return; + } else { + node = this.createNode(key, value); + } + } else if (this.isNodeKey(exemplar)) { + node = this.createNode(exemplar); + } else { + return; + } + return node; + } + /** * Time Complexity: O(log n) - Average case for a balanced tree. In the worst case (unbalanced tree), it can be O(n). * Space Complexity: O(1) - Constant space is used. @@ -159,25 +195,8 @@ export class BST = BSTNode> * (`keyOrNodeOrEntry`) is null, undefined, or does not match any of the expected types. */ override add(keyOrNodeOrEntry: BTNodeExemplar): N | undefined { - if (keyOrNodeOrEntry === null || keyOrNodeOrEntry === undefined) { - return undefined; - } - - let newNode: N | undefined; - if (keyOrNodeOrEntry instanceof BSTNode) { - newNode = keyOrNodeOrEntry; - } else if (this.isNodeKey(keyOrNodeOrEntry)) { - newNode = this.createNode(keyOrNodeOrEntry); - } else if (this.isEntry(keyOrNodeOrEntry)) { - const [key, value] = keyOrNodeOrEntry; - if (key === undefined || key === null) { - return; - } else { - newNode = this.createNode(key, value); - } - } else { - return; - } + const newNode = this.exemplarToNode(keyOrNodeOrEntry); + if (newNode === undefined) return; if (this.root === undefined) { this._setRoot(newNode); diff --git a/src/data-structures/binary-tree/rb-tree.ts b/src/data-structures/binary-tree/rb-tree.ts index 5ef9baf..1a629fe 100644 --- a/src/data-structures/binary-tree/rb-tree.ts +++ b/src/data-structures/binary-tree/rb-tree.ts @@ -106,12 +106,51 @@ export class RedBlackTree = RedBlackTr }) as TREE; } + /** + * The function checks if an exemplar is an instance of the RedBlackTreeNode class. + * @param exemplar - The `exemplar` parameter is of type `BTNodeExemplar`. + * @returns a boolean value indicating whether the exemplar is an instance of the RedBlackTreeNode + * class. + */ + override isNode(exemplar: BTNodeExemplar): exemplar is N { + return exemplar instanceof RedBlackTreeNode; + } + + /** + * The function `exemplarToNode` takes an exemplar and returns a node if the exemplar is valid, + * otherwise it returns undefined. + * @param exemplar - BTNodeExemplar - A generic type representing an exemplar of a binary tree + * node. It can be either a node itself, an entry (key-value pair), a node key, or any other value + * that is not a valid exemplar. + * @returns a variable `node` which is of type `N | undefined`. + */ + override exemplarToNode(exemplar: BTNodeExemplar): N | undefined { + let node: N | undefined; + + if (exemplar === null || exemplar === undefined) { + return; + } else if (this.isNode(exemplar)) { + node = exemplar; + } else if (this.isEntry(exemplar)) { + const [key, value] = exemplar; + if (key === undefined || key === null) { + return; + } else { + node = this.createNode(key, value, RBTNColor.RED); + } + } else if (this.isNodeKey(exemplar)) { + node = this.createNode(exemplar, undefined, RBTNColor.RED); + } else { + return; + } + return node; + } + /** * Time Complexity: O(log n) on average (where n is the number of nodes in the tree) * Space Complexity: O(1) */ - /** * The function adds a node to a Red-Black Tree data structure. * @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter can be one of the following: @@ -119,26 +158,11 @@ export class RedBlackTree = RedBlackTr * `undefined`. */ override add(keyOrNodeOrEntry: BTNodeExemplar): N | undefined { - let node: N; - if (this.isNodeKey(keyOrNodeOrEntry)) { - node = this.createNode(keyOrNodeOrEntry, undefined, RBTNColor.RED); - } else if (keyOrNodeOrEntry instanceof RedBlackTreeNode) { - node = keyOrNodeOrEntry; - } else if (keyOrNodeOrEntry === null || keyOrNodeOrEntry === undefined) { - return; - } else if (this.isEntry(keyOrNodeOrEntry)) { - const [key, value] = keyOrNodeOrEntry; - if (key === undefined || key === null) { - return; - } else { - node = this.createNode(key, value, RBTNColor.RED); - } - } else { - return; - } + const newNode = this.exemplarToNode(keyOrNodeOrEntry); + if (newNode === undefined) return; - node.left = this.Sentinel; - node.right = this.Sentinel; + newNode.left = this.Sentinel; + newNode.right = this.Sentinel; let y: N | undefined = undefined; let x: N | undefined = this.root; @@ -146,13 +170,13 @@ export class RedBlackTree = RedBlackTr while (x !== this.Sentinel) { y = x; if (x) { - if (node.key < x.key) { + if (newNode.key < x.key) { x = x.left; - } else if (node.key > x.key) { + } else if (newNode.key > x.key) { x = x?.right; } else { - if (node !== x) { - this._replaceNode(x, node) + if (newNode !== x) { + this._replaceNode(x, newNode) } return; } @@ -160,27 +184,27 @@ export class RedBlackTree = RedBlackTr } - node.parent = y; + newNode.parent = y; if (y === undefined) { - this._setRoot(node); - } else if (node.key < y.key) { - y.left = node; + this._setRoot(newNode); + } else if (newNode.key < y.key) { + y.left = newNode; } else { - y.right = node; + y.right = newNode; } - if (node.parent === undefined) { - node.color = RBTNColor.BLACK; + if (newNode.parent === undefined) { + newNode.color = RBTNColor.BLACK; this._size++; return; } - if (node.parent.parent === undefined) { + if (newNode.parent.parent === undefined) { this._size++; return; } - this._fixInsert(node); + this._fixInsert(newNode); this._size++; } diff --git a/src/data-structures/binary-tree/tree-multimap.ts b/src/data-structures/binary-tree/tree-multimap.ts index ac04e46..d190489 100644 --- a/src/data-structures/binary-tree/tree-multimap.ts +++ b/src/data-structures/binary-tree/tree-multimap.ts @@ -80,6 +80,45 @@ export class TreeMultimap = TreeMultim }) as TREE; } + /** + * The function checks if an exemplar is an instance of the TreeMultimapNode class. + * @param exemplar - The `exemplar` parameter is of type `BTNodeExemplar`. + * @returns a boolean value indicating whether the exemplar is an instance of the TreeMultimapNode + * class. + */ + override isNode(exemplar: BTNodeExemplar): exemplar is N { + return exemplar instanceof TreeMultimapNode; + } + + /** + * The function `exemplarToNode` converts an exemplar object into a node object. + * @param exemplar - The `exemplar` parameter is of type `BTNodeExemplar`, where `V` represents + * the value type and `N` represents the node type. + * @param [count=1] - The `count` parameter is an optional parameter that specifies the number of + * times the node should be created. If not provided, it defaults to 1. + * @returns a value of type `N` (the generic type parameter) or `undefined`. + */ + override exemplarToNode(exemplar: BTNodeExemplar, count = 1): N | undefined { + let node: N | undefined; + if (exemplar === undefined || exemplar === null) { + return; + } else if (this.isNode(exemplar)) { + node = exemplar; + } else if (this.isEntry(exemplar)) { + const [key, value] = exemplar; + if (key === undefined || key === null) { + return; + } else { + node = this.createNode(key, value, count); + } + } else if (this.isNodeKey(exemplar)) { + node = this.createNode(exemplar, undefined, count); + } else { + return; + } + return node; + } + /** * Time Complexity: O(log n) - logarithmic time, where "n" is the number of nodes in the tree. The add method of the superclass (AVLTree) has logarithmic time complexity. * Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size. @@ -98,23 +137,9 @@ export class TreeMultimap = TreeMultim * @returns either a node (`N`) or `undefined`. */ override add(keyOrNodeOrEntry: BTNodeExemplar, count = 1): N | undefined { - let newNode: N | undefined; - if (keyOrNodeOrEntry === undefined || keyOrNodeOrEntry === null) { - return; - } else if (keyOrNodeOrEntry instanceof TreeMultimapNode) { - newNode = keyOrNodeOrEntry; - } else if (this.isNodeKey(keyOrNodeOrEntry)) { - newNode = this.createNode(keyOrNodeOrEntry, undefined, count); - } else if (this.isEntry(keyOrNodeOrEntry)) { - const [key, value] = keyOrNodeOrEntry; - if (key === undefined || key === null) { - return; - } else { - newNode = this.createNode(key, value, count); - } - } else { - return; - } + const newNode = this.exemplarToNode(keyOrNodeOrEntry, count); + if (newNode === undefined) return; + const orgNodeCount = newNode?.count || 0; const inserted = super.add(newNode); if (inserted) {