fix: Fix the bug where the binary tree repeatedly adds elements with the same key in map mode and the bug where the node’s value is instantiated simultaneously. Enable map mode by default.

This commit is contained in:
Revone 2024-11-03 16:38:07 +13:00
parent 37ff9207fe
commit 5adf75f99c
20 changed files with 172 additions and 95 deletions

View file

@ -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.52.9](https://github.com/zrwusa/data-structure-typed/compare/v1.51.5...main) (upcoming)
## [v1.53.0](https://github.com/zrwusa/data-structure-typed/compare/v1.51.5...main) (upcoming)
### Changes

4
package-lock.json generated
View file

@ -1,12 +1,12 @@
{
"name": "data-structure-typed",
"version": "1.52.9",
"version": "1.53.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "data-structure-typed",
"version": "1.52.9",
"version": "1.53.0",
"license": "MIT",
"devDependencies": {
"@eslint/compat": "^1.2.2",

View file

@ -129,7 +129,7 @@ export class AVLTreeMultiMap<
* @returns a new instance of the AVLTreeMultiMapNode class, casted as NODE.
*/
override createNode(key: K, value?: V, count?: number): NODE {
return new AVLTreeMultiMapNode(key, value, count) as NODE;
return new AVLTreeMultiMapNode(key, this._isMapMode ? undefined : value, count) as NODE;
}
/**

View file

@ -99,7 +99,7 @@ export class AVLTree<
* type NODE.
*/
override createNode(key: K, value?: V): NODE {
return new AVLTreeNode<K, V, NODE>(key, value) as NODE;
return new AVLTreeNode<K, V, NODE>(key, this._isMapMode ? undefined : value) as NODE;
}
/**

View file

@ -135,7 +135,7 @@ export class BinaryTree<
if (keysNodesEntriesOrRaws) this.addMany(keysNodesEntriesOrRaws);
}
protected _isMapMode = false;
protected _isMapMode = true;
get isMapMode() {
return this._isMapMode;
@ -181,7 +181,7 @@ export class BinaryTree<
* as NODE.
*/
createNode(key: K, value?: V): NODE {
return new BinaryTreeNode<K, V, NODE>(key, value) as NODE;
return new BinaryTreeNode<K, V, NODE>(key, this._isMapMode ? undefined : value) as NODE;
}
/**

View file

@ -141,7 +141,7 @@ export class BST<
* @returns The method is returning a new instance of the BSTNode class, casted as the NODE type.
*/
override createNode(key: K, value?: V): NODE {
return new BSTNode<K, V, NODE>(key, value) as NODE;
return new BSTNode<K, V, NODE>(key, this._isMapMode ? undefined : value) as NODE;
}
/**
@ -174,9 +174,9 @@ export class BST<
keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R,
value?: V
): [OptNode<NODE>, V | undefined] {
const [node, tValue] = super.keyValueNodeEntryRawToNodeAndValue(keyNodeEntryOrRaw, value);
const [node, entryValue] = super.keyValueNodeEntryRawToNodeAndValue(keyNodeEntryOrRaw, value);
if (node === null) return [undefined, undefined];
return [node, tValue ?? value];
return [node, value ?? entryValue];
}
/**
@ -250,6 +250,7 @@ export class BST<
while (current !== undefined) {
if (this.comparator(current.key, newNode.key) === 0) {
this._replaceNode(current, newNode);
if (this._isMapMode) this._setValue(current.key, newValue);
return true;
} else if (this.comparator(current.key, newNode.key) > 0) {
if (current.left === undefined) {

View file

@ -106,7 +106,7 @@ export class RedBlackTree<
* returned.
*/
override createNode(key: K, value?: V, color: RBTNColor = 'BLACK'): NODE {
return new RedBlackTreeNode<K, V, NODE>(key, value, color) as NODE;
return new RedBlackTreeNode<K, V, NODE>(key, this._isMapMode ? undefined : value, color) as NODE;
}
/**
@ -218,7 +218,12 @@ export class RedBlackTree<
if (this._isMapMode) this._setValue(newNode.key, newValue);
this._size++;
return true;
} else return insertStatus === 'UPDATED';
}
if (insertStatus === 'UPDATED') {
if (this._isMapMode) this._setValue(newNode.key, newValue);
return true;
}
return false;
}
/**

View file

@ -124,7 +124,7 @@ export class TreeMultiMap<
* @returns A new instance of the TreeMultiMapNode class, casted as NODE.
*/
override createNode(key: K, value?: V, color: RBTNColor = 'BLACK', count?: number): NODE {
return new TreeMultiMapNode(key, value, count, color) as NODE;
return new TreeMultiMapNode(key, this._isMapMode ? undefined : value, count, color) as NODE;
}
/**

View file

@ -1,5 +1,5 @@
import { AVLTreeMultiMap, AVLTreeMultiMapNode } from '../../../data-structures';
import type { AVLTreeOptions } from './avl-tree';
import {AVLTreeMultiMap, AVLTreeMultiMapNode} from '../../../data-structures';
import type {AVLTreeOptions} from './avl-tree';
export type AVLTreeMultiMapNodeNested<K, V> = AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

View file

@ -1,5 +1,5 @@
import { AVLTree, AVLTreeNode } from '../../../data-structures';
import { BSTOptions } from './bst';
import {AVLTree, AVLTreeNode} from '../../../data-structures';
import {BSTOptions} from './bst';
export type AVLTreeNodeNested<K, V> = AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

View file

@ -1,6 +1,6 @@
import { BinaryTree, BinaryTreeNode } from '../../../data-structures';
import { IterationType, OptValue } from '../../common';
import { DFSOperation } from '../../../constants';
import {BinaryTree, BinaryTreeNode} from '../../../data-structures';
import {IterationType, OptValue} from '../../common';
import {DFSOperation} from '../../../constants';
export type BinaryTreeNodeNested<K, V> = BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
@ -9,9 +9,9 @@ export type BinaryTreeNested<K, V, R, NODE extends BinaryTreeNode<K, V, NODE>> =
export type ToEntryFn<K, V, R> = (rawElement: R) => BTNEntry<K, V>;
export type BinaryTreeOptions<K, V, R> = {
iterationType?: IterationType;
toEntryFn?: ToEntryFn<K, V, R>;
isMapMode?: boolean;
iterationType?: IterationType;
toEntryFn?: ToEntryFn<K, V, R>;
isMapMode?: boolean;
}
export type BinaryTreePrintOptions = { isShowUndefined?: boolean; isShowNull?: boolean; isShowRedBlackNIL?: boolean };

View file

@ -1,13 +1,13 @@
import { BST, BSTNode } from '../../../data-structures';
import type { BinaryTreeOptions } from './binary-tree';
import { Comparator } from '../../common';
import {BST, BSTNode} from '../../../data-structures';
import type {BinaryTreeOptions} from './binary-tree';
import {Comparator} from '../../common';
export type BSTNodeNested<K, V> = BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
export type BSTNested<K, V, R, NODE extends BSTNode<K, V, NODE>> = BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
export type BSTOptions<K, V, R> = BinaryTreeOptions<K, V, R> & {
comparator?: Comparator<K>
comparator?: Comparator<K>
}
export type BSTNOptKey<K> = K | undefined;

View file

@ -1,5 +1,5 @@
import { RedBlackTree, RedBlackTreeNode } from '../../../data-structures';
import type { BSTOptions } from "./bst";
import {RedBlackTree, RedBlackTreeNode} from '../../../data-structures';
import type {BSTOptions} from "./bst";
export type RBTNColor = 'RED' | 'BLACK';

View file

@ -1,5 +1,5 @@
import { TreeMultiMap, TreeMultiMapNode } from '../../../data-structures';
import type { RBTreeOptions } from './rb-tree';
import {TreeMultiMap, TreeMultiMapNode} from '../../../data-structures';
import type {RBTreeOptions} from './rb-tree';
export type TreeMultiMapNodeNested<K, V> = TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

View file

@ -75,7 +75,7 @@ describe('AVLTreeMultiMap operations test1', () => {
const nodeId10 = treeMultimap.getNode(10);
expect(nodeId10?.key).toBe(10);
const nodeVal9 = treeMultimap.getNode(node => node.value === 9);
const nodeVal9 = treeMultimap.getNode(node => node.key === 9);
expect(nodeVal9?.key).toBe(9);
const nodesByCount1 = treeMultimap.getNodes(node => node.count === 1);
@ -331,7 +331,7 @@ describe('AVLTreeMultiMap operations test recursively1', () => {
const nodeId10 = treeMultimap.getNode(10);
expect(nodeId10?.key).toBe(10);
const nodeVal9 = treeMultimap.getNode(node => node.value === 9);
const nodeVal9 = treeMultimap.getNode(node => node.key === 9);
expect(nodeVal9?.key).toBe(9);
const nodesByCount1 = treeMultimap.getNodes(node => node.count === 1);
@ -762,10 +762,10 @@ describe('AVLTree toEntryFn', () => {
});
});
describe('AVLTreeMultiMap map mode count', () => {
describe('AVLTreeMultiMap not map mode count', () => {
let tm: AVLTreeMultiMap<number>;
beforeEach(() => {
tm = new AVLTreeMultiMap<number>([], { isMapMode: true });
tm = new AVLTreeMultiMap<number>([], { isMapMode: false });
});
it('Should added isolated node count ', () => {
tm.addMany([
@ -781,9 +781,9 @@ describe('AVLTreeMultiMap map mode count', () => {
});
});
describe('AVLTreeMultiMap map mode operations test1', () => {
describe('AVLTreeMultiMap not map mode operations test1', () => {
it('should perform various operations on a Binary Search Tree with numeric values1', () => {
const treeMultimap = new AVLTreeMultiMap<number>([], { isMapMode: true });
const treeMultimap = new AVLTreeMultiMap<number>([], { isMapMode: false });
expect(treeMultimap instanceof AVLTreeMultiMap);
treeMultimap.add([11, 11]);
@ -826,11 +826,11 @@ describe('AVLTreeMultiMap map mode operations test1', () => {
});
});
describe('AVLTreeMultiMap map mode operations test recursively1', () => {
describe('AVLTreeMultiMap not map mode operations test recursively1', () => {
it('should perform various operations on a Binary Search Tree with numeric values1', () => {
const treeMultimap = new AVLTreeMultiMap<number>([], {
iterationType: 'RECURSIVE',
isMapMode: true
isMapMode: false
});
expect(treeMultimap instanceof AVLTreeMultiMap);

View file

@ -32,7 +32,7 @@ describe('AVL Tree Test', () => {
expect(lesserSum).toBe(45);
// node15 has type problem. After the uniform design, the generics of containers (DirectedGraph, BST) are based on the type of value. However, this design has a drawback: when I attempt to inherit from the Vertex or BSTNode classes, the types of the results obtained by all methods are those of the parent class.
expect(node15?.value).toBe(15);
expect(node15?.value).toBe(undefined);
const dfs = tree.dfs(node => node, 'IN');
expect(dfs[0].key).toBe(1);
expect(dfs[dfs.length - 1].key).toBe(16);
@ -106,6 +106,25 @@ describe('AVL Tree Test', () => {
expect(lastBFSNodes[1].key).toBe(2);
expect(lastBFSNodes[2].key).toBe(16);
});
it('should replace value', () => {
const tree = new AVLTree<number, string>([4, 5, [1, '1'], 2, 3], { isMapMode: false });
expect(tree.get(1)).toBe('1');
expect(tree.getNode(1)?.value).toBe('1');
tree.add(1, 'a');
expect(tree.get(1)).toBe('a');
tree.add([1, 'b']);
expect(tree.getNode(1)?.value).toBe('b');
expect(tree.get(1)).toBe('b');
const treeMap = new AVLTree<number>([4, 5, [1, '1'], 2, 3]);
expect(treeMap.get(1)).toBe('1');
expect(treeMap.getNode(1)?.value).toBe(undefined);
treeMap.add(1, 'a');
expect(treeMap.get(1)).toBe('a');
treeMap.add([1, 'b']);
expect(treeMap.getNode(1)?.value).toBe(undefined);
expect(treeMap.get(1)).toBe('b');
});
});
describe('AVL Tree Test recursively', () => {
@ -139,7 +158,7 @@ describe('AVL Tree Test recursively', () => {
expect(lesserSum).toBe(45);
// node15 has type problem. After the uniform design, the generics of containers (DirectedGraph, BST) are based on the type of value. However, this design has a drawback: when I attempt to inherit from the Vertex or BSTNode classes, the types of the results obtained by all methods are those of the parent class.
expect(node15?.value).toBe(15);
expect(node15?.value).toBe(undefined);
const dfs = tree.dfs(node => node, 'IN');
expect(dfs[0].key).toBe(1);
@ -418,7 +437,7 @@ describe('AVLTree iterative methods test', () => {
it('should clone work well', () => {
const cloned = avl.clone();
expect(cloned.root?.left?.key).toBe(1);
expect(cloned.root?.right?.value).toBe('c');
expect(cloned.root?.right?.value).toBe(undefined);
});
it('should keys', () => {
@ -437,10 +456,10 @@ describe('AVLTree iterative methods test', () => {
});
});
describe('AVL Tree map mode', () => {
describe('AVL Tree not map mode', () => {
it('should perform various operations on a AVL Tree', () => {
const arr = [11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5];
const tree = new AVLTree<number>([], { isMapMode: true });
const tree = new AVLTree<number>([], { isMapMode: false });
for (const i of arr) tree.add([i, i]);
@ -473,10 +492,10 @@ describe('AVL Tree map mode', () => {
});
});
describe('AVL Tree map mode test recursively', () => {
describe('AVL Tree not map mode test recursively', () => {
it('should perform various operations on a AVL Tree', () => {
const arr = [11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5];
const tree = new AVLTree<number>([], { iterationType: 'RECURSIVE', isMapMode: true });
const tree = new AVLTree<number>([], { iterationType: 'RECURSIVE', isMapMode: false });
for (const i of arr) tree.add([i, i]);
@ -508,10 +527,10 @@ describe('AVL Tree map mode test recursively', () => {
});
});
describe('AVLTree iterative methods map mode', () => {
describe('AVLTree iterative methods not map mode', () => {
let avl: AVLTree<number, string>;
beforeEach(() => {
avl = new AVLTree<number, string>([], { isMapMode: true });
avl = new AVLTree<number, string>([], { isMapMode: false });
avl.add([1, 'a']);
avl.add([2, 'b']);
avl.add([3, 'c']);

View file

@ -102,10 +102,10 @@ describe('BinaryTree addMany', () => {
],
[undefined, 22, 44, 33]
);
expect(tree.getNodeByKey(2)?.value).toBe(22);
expect(tree.getNodeByKey(3)?.value).toBe(33);
expect(tree.getNodeByKey(4)?.value).toBe(44);
expect(tree.getNodeByKey(1)?.value).toBe(1);
expect(tree.get(2)).toBe(22);
expect(tree.get(tree.getNodeByKey(3))).toBe(33);
expect(tree.get(tree.getNodeByKey(4))).toBe(44);
expect(tree.get(tree.getNodeByKey(1))).toBe(1);
});
it('should addMany undefined and null', () => {
@ -193,7 +193,7 @@ describe('BinaryTree', () => {
const node4 = tree.getNode(4);
expect(tree.has(node4)).toBe(false);
expect(tree.has(node => node === node4)).toBe(false);
expect(tree.has(node => node.value?.toString() === '3')).toBe(true);
expect(tree.has(node => node.key?.toString() === '3')).toBe(true);
});
it('should the clone method work fine', () => {
@ -768,6 +768,25 @@ describe('BinaryTree', () => {
});
expect(bTree.keyValueNodeEntryRawToNodeAndValue({ obj: { id: 1 } })).toEqual([undefined, undefined]);
});
it('should replace value', () => {
const tree = new BinaryTree<number, string>([4, 5, [1, '1'], 2, 3], { isMapMode: false });
expect(tree.get(1)).toBe('1');
expect(tree.getNode(1)?.value).toBe('1');
tree.add(1, 'a');
expect(tree.get(1)).toBe('a');
tree.add([1, 'b']);
expect(tree.getNode(1)?.value).toBe('b');
expect(tree.get(1)).toBe('b');
const treeMap = new BinaryTree<number>([4, 5, [1, '1'], 2, 3]);
expect(treeMap.get(1)).toBe('1');
expect(treeMap.getNode(1)?.value).toBe(undefined);
treeMap.add(1, 'a');
expect(treeMap.get(1)).toBe('a');
treeMap.add([1, 'b']);
expect(treeMap.getNode(1)?.value).toBe(undefined);
expect(treeMap.get(1)).toBe('b');
});
});
describe('BinaryTree ensureNode', () => {
@ -1049,9 +1068,9 @@ describe('BinaryTree', () => {
const nodeB = tree.getNode(3);
expect(nodeA?.key).toBe(5);
expect(nodeA?.value).toBe('A');
expect(nodeA?.value).toBe(undefined);
expect(nodeB?.key).toBe(3);
expect(nodeB?.value).toBe('B');
expect(tree.get(nodeB)).toBe('B');
});
it('should return null when getting a non-existent node', () => {
@ -1160,21 +1179,17 @@ describe('BinaryTree', () => {
tree.add([2, 'B']);
tree.add([null, 'null']);
const nodes = tree.isMapMode ? tree.getNodes(node => node.key === 2) : tree.getNodes(node => node.value === 'B');
const nodes = tree.getNodes(node => node.key === 2);
expect(nodes.length).toBe(1);
expect(nodes[0].key).toBe(2);
const nodesRec = tree.isMapMode
? tree.getNodes(node => node.key === 2, false, tree.root, 'RECURSIVE')
: tree.getNodes(node => node.value === 'B', false, tree.root, 'RECURSIVE');
const nodesRec = tree.getNodes(node => node.key === 2, false, tree.root, 'RECURSIVE');
expect(nodesRec.length).toBe(1);
expect(nodesRec[0].key).toBe(2);
const nodesItr = tree.isMapMode
? tree.getNodes(node => node.key === 2, false, tree.root, 'ITERATIVE')
: tree.getNodes(node => node.value === 'B', false, tree.root, 'ITERATIVE');
const nodesItr = tree.getNodes(node => node.key === 2, false, tree.root, 'ITERATIVE');
expect(nodesItr.length).toBe(1);
expect(nodesItr[0].key).toBe(2);
@ -1220,13 +1235,13 @@ describe('BinaryTree', () => {
});
});
describe('BinaryTree map mode', () => {
describe('BinaryTree not map mode', () => {
let tree: BinaryTree<number, string>;
beforeEach(() => {
tree = new BinaryTree<number, string>([], {
iterationType: 'RECURSIVE',
isMapMode: true
isMapMode: false
});
});
@ -1247,8 +1262,7 @@ describe('BinaryTree map mode', () => {
const node4 = tree.getNode(4);
expect(tree.has(node4)).toBe(false);
expect(tree.has(node => node === node4)).toBe(false);
if (tree.isMapMode) expect(tree.has(node => node.key?.toString() === '3')).toBe(true);
else expect(tree.has(node => node.value?.toString() === '3')).toBe(true);
expect(tree.has(node => node.value?.toString() === '3')).toBe(true);
});
it('should isSubtreeBST', () => {
@ -1379,8 +1393,8 @@ describe('BinaryTree iterative methods test', () => {
it('should clone work well', () => {
const cloned = binaryTree.clone();
expect(cloned.root?.left?.key).toBe(2);
if (cloned.isMapMode) expect(cloned.get(cloned.root?.right)).toBe('c');
else expect(cloned.root?.right?.value).toBe('c');
expect(cloned.root?.right?.value).toBe(undefined);
expect(cloned.get(cloned.root?.right)).toBe('c');
});
it('should keys', () => {
@ -1423,10 +1437,10 @@ describe('BinaryTree iterative methods test', () => {
});
});
describe('BinaryTree map mode iterative methods test', () => {
describe('BinaryTree not map mode iterative methods test', () => {
let binaryTree: BinaryTree<number, string>;
beforeEach(() => {
binaryTree = new BinaryTree<number, string>([], { isMapMode: true });
binaryTree = new BinaryTree<number, string>([], { isMapMode: false });
binaryTree.add([1, 'a']);
binaryTree.add(2, 'b');
binaryTree.add([3, 'c']);

View file

@ -74,7 +74,7 @@ describe('BST operations test', () => {
const nodeId10 = bst.getNode(10);
expect(nodeId10?.key).toBe(10);
const nodeVal9 = bst.getNode(node => node.value === 9);
const nodeVal9 = bst.getNode(node => node.key === 9);
expect(nodeVal9?.key).toBe(9);
const leftMost = bst.getLeftMost();
@ -86,7 +86,7 @@ describe('BST operations test', () => {
const minNodeBySpecificNode = node15 && bst.getLeftMost(node => node, node15);
expect(minNodeBySpecificNode?.key).toBe(12);
const nodes = bst.getNodes(node => node.value === 15);
const nodes = bst.getNodes(node => node.key === 15);
expect(nodes.map(node => node.key)).toEqual([15]);
let subTreeSum = 0;
@ -291,7 +291,7 @@ describe('BST operations test', () => {
expect(leftMost).toBe(1);
const node15 = objBST.getNode(15);
expect(node15?.value).toEqual({
expect(objBST.get(node15)).toEqual({
name: 'Alice',
age: 15
});
@ -470,6 +470,25 @@ describe('BST operations test', () => {
const nodeNull = bst.keyValueNodeEntryRawToNodeAndValue(null);
expect(nodeNull).toEqual([undefined, undefined]);
});
it('should replace value', () => {
const tree = new BST<number, string>([4, 5, [1, '1'], 2, 3], { isMapMode: false });
expect(tree.get(1)).toBe('1');
expect(tree.getNode(1)?.value).toBe('1');
tree.add(1, 'a');
expect(tree.get(1)).toBe('a');
tree.add([1, 'b']);
expect(tree.getNode(1)?.value).toBe('b');
expect(tree.get(1)).toBe('b');
const treeMap = new BST<number>([4, 5, [1, '1'], 2, 3]);
expect(treeMap.get(1)).toBe('1');
expect(treeMap.getNode(1)?.value).toBe(undefined);
treeMap.add(1, 'a');
expect(treeMap.get(1)).toBe('a');
treeMap.add([1, 'b']);
expect(treeMap.getNode(1)?.value).toBe(undefined);
expect(treeMap.get(1)).toBe('b');
});
});
describe('BST operations test recursively', () => {
@ -708,7 +727,7 @@ describe('BST operations test recursively', () => {
expect(leftMost).toBe(1);
const node15 = objBST.getNode(15);
expect(node15?.value).toEqual({
expect(objBST.get(node15)).toEqual({
key: 15,
keyA: 15
});
@ -1135,7 +1154,7 @@ describe('BST iterative methods test', () => {
it('should clone work well', () => {
const cloned = bst.clone();
expect(cloned.root?.left).toBe(undefined);
expect(cloned.root?.right?.value).toBe('b');
expect(cloned.root?.right?.value).toBe(undefined);
});
it('should keys', () => {
@ -1210,13 +1229,13 @@ describe('BST iterative methods test', () => {
);
expect(balanced.leaves()).toEqual([1, 6, 4, 9]);
expect(balanced.leaves(node => node?.value)).toEqual(['a', 'f', 'd', 'i']);
expect(balanced.leaves(node => balanced.get(node))).toEqual(['a', 'f', 'd', 'i']);
});
});
describe('BST operations map mode test', () => {
describe('BST operations not map mode test', () => {
it('should perform various operations on a Binary Search Tree with numeric values', () => {
const bst = new BST<number, number>([], { isMapMode: true });
const bst = new BST<number, number>([], { isMapMode: false });
expect(bst).toBeInstanceOf(BST);
bst.add([11, 11]);
bst.add([3, 3]);
@ -1269,7 +1288,7 @@ describe('BST operations map mode test', () => {
});
it('should perform various operations on a Binary Search Tree with object values', () => {
const objBST = new BST<number, { name: string; age: number }>([], { isMapMode: true });
const objBST = new BST<number, { name: string; age: number }>([], { isMapMode: false });
expect(objBST).toBeInstanceOf(BST);
objBST.add([11, { name: '11', age: 11 }]);
objBST.add([3, { name: '3', age: 3 }]);
@ -1322,7 +1341,7 @@ describe('BST operations map mode test', () => {
});
it('should keyValueNodeEntryRawToNodeAndValue', () => {
const bst = new BST<number>([], { isMapMode: true });
const bst = new BST<number>([], { isMapMode: false });
const node0 = bst.keyValueNodeEntryRawToNodeAndValue(0);
expect(node0).toEqual([
{
@ -1343,11 +1362,11 @@ describe('BST operations map mode test', () => {
});
});
describe('BST operations map mode test recursively', () => {
describe('BST operations not map mode test recursively', () => {
it('should perform various operations on a Binary Search Tree with numeric values', () => {
const bst = new BST<number>([], {
iterationType: 'RECURSIVE',
isMapMode: true
isMapMode: false
});
expect(bst).toBeInstanceOf(BST);
bst.add([11, 11]);
@ -1375,7 +1394,7 @@ describe('BST operations map mode test recursively', () => {
});
it('should perform various operations on a Binary Search Tree with object values', () => {
const objBST = new BST<number, { key: number; keyA: number }>([], { isMapMode: true });
const objBST = new BST<number, { key: number; keyA: number }>([], { isMapMode: false });
expect(objBST).toBeInstanceOf(BST);
objBST.add([11, { key: 11, keyA: 11 }]);
objBST.add([3, { key: 3, keyA: 3 }]);
@ -1429,7 +1448,7 @@ describe('BST operations map mode test recursively', () => {
});
});
describe('BST iterative methods map mode test', () => {
describe('BST iterative methods not map mode test', () => {
let bst: BST<number, string>;
beforeEach(() => {
bst = new BST();

View file

@ -182,6 +182,25 @@ describe('RedBlackTree 1', () => {
expect(rbTree.size).toBe(4);
expect(cloned.size).toBe(3);
});
it('should replace value', () => {
const tree = new RedBlackTree<number, string>([4, 5, [1, '1'], 2, 3], { isMapMode: false });
expect(tree.get(1)).toBe('1');
expect(tree.getNode(1)?.value).toBe('1');
tree.add(1, 'a');
expect(tree.get(1)).toBe('a');
tree.add([1, 'b']);
expect(tree.getNode(1)?.value).toBe('b');
expect(tree.get(1)).toBe('b');
const treeMap = new RedBlackTree<number>([4, 5, [1, '1'], 2, 3]);
expect(treeMap.get(1)).toBe('1');
expect(treeMap.getNode(1)?.value).toBe(undefined);
treeMap.add(1, 'a');
expect(treeMap.get(1)).toBe('a');
treeMap.add([1, 'b']);
expect(treeMap.getNode(1)?.value).toBe(undefined);
expect(treeMap.get(1)).toBe('b');
});
});
describe('RedBlackTree 2', () => {

View file

@ -133,7 +133,7 @@ describe('TreeMultiMap operations test1', () => {
const nodeId10 = tmm.getNode(10);
expect(nodeId10?.key).toBe(10);
const nodeVal9 = tmm.getNode(node => node.value === 9);
const nodeVal9 = tmm.getNode(node => node.key === 9);
expect(nodeVal9?.key).toBe(9);
const nodesByCount1 = tmm.getNodes(node => node.count === 1);
@ -391,7 +391,7 @@ describe('TreeMultiMap operations test recursively1', () => {
const nodeId10 = tmm.getNode(10);
expect(nodeId10?.key).toBe(10);
const nodeVal9 = tmm.getNode(node => node.value === 9);
const nodeVal9 = tmm.getNode(node => node.key === 9);
expect(nodeVal9?.key).toBe(9);
const nodesByCount1 = tmm.getNodes(node => node.count === 1);
@ -837,10 +837,10 @@ describe('TreeMultiMap iterative methods test', () => {
});
});
describe('TreeMultiMap count map mode', () => {
describe('TreeMultiMap count not map mode', () => {
let tmm: TreeMultiMap<number>;
beforeEach(() => {
tmm = new TreeMultiMap<number>([], { isMapMode: true });
tmm = new TreeMultiMap<number>([], { isMapMode: false });
});
it('Should added node count ', () => {
@ -860,9 +860,9 @@ describe('TreeMultiMap count map mode', () => {
});
});
describe('TreeMultiMap operations test1 map mode', () => {
describe('TreeMultiMap operations test1 not map mode', () => {
it('should perform various operations on a Binary Search Tree with numeric values1', () => {
const tmm = new TreeMultiMap<number, number>([], { isMapMode: true });
const tmm = new TreeMultiMap<number, number>([], { isMapMode: false });
expect(tmm instanceof TreeMultiMap);
@ -907,11 +907,11 @@ describe('TreeMultiMap operations test1 map mode', () => {
});
});
describe('TreeMultiMap operations test recursively1 map mode', () => {
describe('TreeMultiMap operations test recursively1 not map mode', () => {
it('should perform various operations on a Binary Search Tree with numeric values1', () => {
const tmm = new TreeMultiMap<number>([], {
iterationType: 'RECURSIVE',
isMapMode: true
isMapMode: false
});
expect(tmm instanceof TreeMultiMap);
@ -956,10 +956,10 @@ describe('TreeMultiMap operations test recursively1 map mode', () => {
});
});
describe('TreeMultiMap iterative methods testm ap mode', () => {
describe('TreeMultiMap iterative methods test not map mode', () => {
let treeMM: TreeMultiMap<number, string>;
beforeEach(() => {
treeMM = new TreeMultiMap<number, string>([], { isMapMode: true });
treeMM = new TreeMultiMap<number, string>([], { isMapMode: false });
treeMM.add(1, 'a', 10);
treeMM.add([2, 'b'], undefined, 10);
treeMM.add([3, 'c'], undefined, 1);
@ -970,6 +970,6 @@ describe('TreeMultiMap iterative methods testm ap mode', () => {
expect(treeMM.getComputedCount()).toBe(21);
const cloned = treeMM.clone();
expect(cloned.root?.left?.key).toBe(1);
expect(cloned.get(cloned.root?.right)).toBe('c');
expect(cloned.get(cloned.root?.right)).toBe(undefined);
});
});