diff --git a/CHANGELOG.md b/CHANGELOG.md index a44e251..7adcd4e 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.48.4](https://github.com/zrwusa/data-structure-typed/compare/v1.35.0...main) (upcoming) +## [v1.48.5](https://github.com/zrwusa/data-structure-typed/compare/v1.35.0...main) (upcoming) ### Changes diff --git a/src/data-structures/binary-tree/avl-tree.ts b/src/data-structures/binary-tree/avl-tree.ts index 7aa7315..9413f47 100644 --- a/src/data-structures/binary-tree/avl-tree.ts +++ b/src/data-structures/binary-tree/avl-tree.ts @@ -99,7 +99,7 @@ export class AVLTree = AVLTreeN /** * 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. - * + * * The function overrides the add method of a binary tree node and balances the tree after inserting * a new node. * @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter can be either a key, a node, or an diff --git a/src/data-structures/binary-tree/binary-tree.ts b/src/data-structures/binary-tree/binary-tree.ts index 54b9a3f..bbdbc02 100644 --- a/src/data-structures/binary-tree/binary-tree.ts +++ b/src/data-structures/binary-tree/binary-tree.ts @@ -235,7 +235,7 @@ export class BinaryTree = Bi /** * Time Complexity O(log n) - O(n) * Space Complexity O(1) - * + * * The `add` function adds a new node to a binary tree, either by creating a new node or replacing an * existing node with the same key. * @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter can be one of the following: @@ -288,22 +288,38 @@ export class BinaryTree = Bi * Time Complexity: O(k log n) - O(k * n) * Space Complexity: O(1) * - * The function `addMany` takes in an iterable of `BTNodeExemplar` objects, adds each object to the - * current instance, and returns an array of the inserted nodes. - * @param nodes - The `nodes` parameter is an iterable (such as an array or a set) of - * `BTNodeExemplar` objects. - * @returns The function `addMany` returns an array of values, where each value is either of type - * `N`, `null`, or `undefined`. + * The `addMany` function takes in a collection of nodes and an optional collection of values, and + * adds each node with its corresponding value to the data structure. + * @param nodes - An iterable collection of BTNodeExemplar objects. + * @param [values] - An optional iterable of values that will be assigned to each node being added. + * @returns The function `addMany` returns an array of `N`, `null`, or `undefined` values. */ - addMany(nodes: Iterable>): (N | null | undefined)[] { + addMany(nodes: Iterable>, values?: Iterable): (N | null | undefined)[] { // TODO not sure addMany not be run multi times const inserted: (N | null | undefined)[] = []; - for (const kne of nodes) { - inserted.push(this.add(kne)); + + let valuesIterator: Iterator | undefined; + if (values) { + valuesIterator = values[Symbol.iterator](); } + + for (const kne of nodes) { + let value: V | undefined | null = undefined; + + if (valuesIterator) { + const valueResult = valuesIterator.next(); + if (!valueResult.done) { + value = valueResult.value; + } + } + + inserted.push(this.add(kne, value)); + } + return inserted; } + /** * Time Complexity: O(k * n) "n" is the number of nodes in the tree, and "k" is the number of keys to be inserted. * Space Complexity: O(1) diff --git a/src/data-structures/binary-tree/bst.ts b/src/data-structures/binary-tree/bst.ts index 9009509..a631fa7 100644 --- a/src/data-structures/binary-tree/bst.ts +++ b/src/data-structures/binary-tree/bst.ts @@ -192,7 +192,7 @@ export class BST = BSTNode = BSTNode>, + values?: Iterable, isBalanceAdd = true, iterationType = this.iterationType ): (N | undefined)[] { - const inserted: (N | undefined)[] = [] + const inserted: (N | undefined)[] = []; + + let valuesIterator: Iterator | undefined; + + if (values) { + valuesIterator = values[Symbol.iterator](); + } + if (!isBalanceAdd) { for (const kve of keysOrNodesOrEntries) { - const nn = this.add(kve) + const value = valuesIterator?.next().value; + const nn = this.add(kve, value); inserted.push(nn); } return inserted; } + const realBTNExemplars: BTNodePureExemplar[] = []; const isRealBTNExemplar = (kve: BTNodeExemplar): kve is BTNodePureExemplar => { @@ -292,22 +306,20 @@ export class BST = BSTNode[] = []; sorted = realBTNExemplars.sort((a, b) => { let aR: number, bR: number; - if (this.isEntry(a)) aR = this.extractor(a[0]) - else if (this.isRealNode(a)) aR = this.extractor(a.key) + if (this.isEntry(a)) aR = this.extractor(a[0]); + else if (this.isRealNode(a)) aR = this.extractor(a.key); else aR = this.extractor(a); - if (this.isEntry(b)) bR = this.extractor(b[0]) - else if (this.isRealNode(b)) bR = this.extractor(b.key) + if (this.isEntry(b)) bR = this.extractor(b[0]); + else if (this.isRealNode(b)) bR = this.extractor(b.key); else bR = this.extractor(b); return aR - bR; - }) - + }); const _dfs = (arr: BTNodePureExemplar[]) => { if (arr.length === 0) return; @@ -318,6 +330,7 @@ export class BST = BSTNode { const n = sorted.length; const stack: [[number, number]] = [[0, n - 1]]; @@ -335,6 +348,7 @@ export class BST = BSTNode = BSTNode /** * Time Complexity: O(log n) on average (where n is the number of nodes in the tree) * Space Complexity: O(1) - * + * * The `add` function adds a new node to a binary search tree and performs necessary rotations and * color changes to maintain the red-black tree properties. * @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter can be either a key, a node, or an diff --git a/src/data-structures/binary-tree/tree-multimap.ts b/src/data-structures/binary-tree/tree-multimap.ts index eb879da..79fb5a8 100644 --- a/src/data-structures/binary-tree/tree-multimap.ts +++ b/src/data-structures/binary-tree/tree-multimap.ts @@ -126,7 +126,7 @@ export class TreeMultimap /** * 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. - * + * * The function overrides the add method of a binary tree node and adds a new node to the tree. * @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter can be either a key, a node, or an * entry. It represents the key, node, or entry that you want to add to the binary tree. diff --git a/src/interfaces/binary-tree.ts b/src/interfaces/binary-tree.ts index d732890..16143bd 100644 --- a/src/interfaces/binary-tree.ts +++ b/src/interfaces/binary-tree.ts @@ -15,7 +15,7 @@ export interface IBinaryTree, value?: V, count?: number): N | null | undefined; - addMany(nodes: Iterable>): (N | null | undefined)[]; + addMany(nodes: Iterable>, values?: Iterable): (N | null | undefined)[]; delete>(identifier: ReturnType | null, callback: C): BiTreeDeleteResult[]; } diff --git a/test/performance/data-structures/linked-list/singly-linked-list.test.ts b/test/performance/data-structures/linked-list/singly-linked-list.test.ts index e1eaa6e..027a6e3 100644 --- a/test/performance/data-structures/linked-list/singly-linked-list.test.ts +++ b/test/performance/data-structures/linked-list/singly-linked-list.test.ts @@ -3,9 +3,20 @@ import * as Benchmark from 'benchmark'; import { magnitude } from '../../../utils'; const suite = new Benchmark.Suite(); -const { TEN_THOUSAND } = magnitude; +const { MILLION, TEN_THOUSAND } = magnitude; suite + .add(`${MILLION.toLocaleString()} push & shift`, () => { + const list = new SinglyLinkedList(); + + for (let i = 0; i < MILLION; i++) { + list.push(i); + } + + for (let i = 0; i < MILLION; i++) { + list.shift(); + } + }) .add(`${TEN_THOUSAND.toLocaleString()} push & pop`, () => { const list = new SinglyLinkedList(); diff --git a/test/unit/data-structures/binary-tree/bst.test.ts b/test/unit/data-structures/binary-tree/bst.test.ts index 216e94e..e684791 100644 --- a/test/unit/data-structures/binary-tree/bst.test.ts +++ b/test/unit/data-structures/binary-tree/bst.test.ts @@ -10,7 +10,7 @@ describe('BST operations test', () => { bst.add([11, 11]); bst.add([3, 3]); const idsAndValues: [number, number][] = [[15, 15], [1, 1], [8, 8], [13, 13], [16, 16], [2, 2], [6, 6], [9, 9], [12, 12], [14, 14], [4, 4], [7, 7], [10, 10], [5, 5]]; - bst.addMany(idsAndValues, false); + bst.addMany(idsAndValues, undefined, false); expect(bst.root).toBeInstanceOf(BSTNode); if (bst.root) expect(bst.root.key).toBe(11); @@ -189,28 +189,27 @@ describe('BST operations test', () => { }); it('should perform various operations on a Binary Search Tree with object values', () => { - const objBST = new BST(); + const objBST = new BST(); expect(objBST).toBeInstanceOf(BST); - objBST.add([11, { key: 11, keyA: 11 }]); - objBST.add([3, { key: 3, keyA: 3 }]); - const values: [number, { key: number; keyA: number }][] = [ - [15, { key: 15, keyA: 15 }], - [1, { key: 1, keyA: 1 }], - [8, { key: 8, keyA: 8 }], - [13, { key: 13, keyA: 13 }], - [16, { key: 16, keyA: 16 }], - [2, { key: 2, keyA: 2 }], - [6, { key: 6, keyA: 6 }], - [9, { key: 9, keyA: 9 }], - [12, { key: 12, keyA: 12 }], - [14, { key: 14, keyA: 14 }], - [4, { key: 4, keyA: 4 }], - [7, { key: 7, keyA: 7 }], - [10, { key: 10, keyA: 10 }], - [5, { key: 5, keyA: 5 }] - ]; + objBST.add([11, { name: '11', age: 11 }]); + objBST.add([3, { name: '3', age: 3 }]); - objBST.addMany(values, false); + objBST.addMany([15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5], [ + { "name": "Alice", "age": 15 }, + { "name": "Bob", "age": 1 }, + { "name": "Charlie", "age": 8 }, + { "name": "David", "age": 13 }, + { "name": "Emma", "age": 16 }, + { "name": "Frank", "age": 2 }, + { "name": "Grace", "age": 6 }, + { "name": "Hannah", "age": 9 }, + { "name": "Isaac", "age": 12 }, + { "name": "Jack", "age": 14 }, + { "name": "Katie", "age": 4 }, + { "name": "Liam", "age": 7 }, + { "name": "Mia", "age": 10 }, + { "name": "Noah", "age": 5 } + ], false); expect(objBST.root).toBeInstanceOf(BSTNode); @@ -232,7 +231,7 @@ describe('BST operations test', () => { expect(leftMost?.key).toBe(1); const node15 = objBST.getNode(15); - expect(node15?.value).toEqual({ key: 15, keyA: 15 }); + expect(node15?.value).toEqual({ name: 'Alice', age: 15 }); const minNodeBySpecificNode = node15 && objBST.getLeftMost(node15); expect(minNodeBySpecificNode?.key).toBe(12); @@ -256,7 +255,7 @@ describe('BST operations test', () => { objBST.perfectlyBalance(); expect(objBST.isPerfectlyBalanced()).toBe(true); - const bfsNodesAfterBalanced: BSTNode[] = []; + const bfsNodesAfterBalanced: BSTNode[] = []; objBST.bfs(node => bfsNodesAfterBalanced.push(node)); expect(bfsNodesAfterBalanced[0].key).toBe(8); expect(bfsNodesAfterBalanced[bfsNodesAfterBalanced.length - 1].key).toBe(16); @@ -381,7 +380,7 @@ describe('BST operations test', () => { expect(bfsIDs[1]).toBe(12); expect(bfsIDs[2]).toBe(16); - const bfsNodes: BSTNode[] = []; + const bfsNodes: BSTNode[] = []; objBST.bfs(node => bfsNodes.push(node)); expect(bfsNodes[0].key).toBe(2); expect(bfsNodes[1].key).toBe(12); @@ -396,7 +395,7 @@ describe('BST operations test recursively', () => { bst.add([11, 11]); bst.add([3, 3]); const idsAndValues = [15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5]; - bst.addMany(idsAndValues, false); + bst.addMany(idsAndValues, undefined, false); expect(bst.root).toBeInstanceOf(BSTNode); if (bst.root) expect(bst.root.key).toBe(11); @@ -580,7 +579,7 @@ describe('BST operations test recursively', () => { expect(objBST).toBeInstanceOf(BST); objBST.add([11, { key: 11, keyA: 11 }]); objBST.add([3, { key: 3, keyA: 3 }]); - const values: [number, { key: number; keyA: number }][] = [ + const entries: [number, { key: number; keyA: number }][] = [ [15, { key: 15, keyA: 15 }], [1, { key: 1, keyA: 1 }], [8, { key: 8, keyA: 8 }], @@ -598,7 +597,8 @@ describe('BST operations test recursively', () => { ]; objBST.addMany( - values, + entries, + undefined, false ); @@ -829,7 +829,7 @@ describe('BST Performance test', function () { it('should the lastKey of a BST to be the largest key', function () { const bst = new BST(); - bst.addMany([9, 8, 7, 3, 1, 2, 5, 4, 6], false); + bst.addMany([9, 8, 7, 3, 1, 2, 5, 4, 6], undefined, false); // TODO // expect(bst.lastKey()).toBe(9); }); diff --git a/test/unit/data-structures/binary-tree/overall.test.ts b/test/unit/data-structures/binary-tree/overall.test.ts index 24f58ce..8f2def1 100644 --- a/test/unit/data-structures/binary-tree/overall.test.ts +++ b/test/unit/data-structures/binary-tree/overall.test.ts @@ -5,7 +5,7 @@ describe('Overall BinaryTree Test', () => { const bst = new BST(); bst.add(11); bst.add(3); - bst.addMany([15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5], false); + bst.addMany([15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5], undefined, false); bst.size === 16; // true expect(bst.size).toBe(16); // true bst.has(6); // true