mirror of
https://github.com/zrwusa/data-structure-typed.git
synced 2024-11-23 12:54:04 +00:00
feat: Remove support for the 'variant' option parameter in Red-Black Tree, meaning no support for reverse Red-Black Tree.
fix: Fix bug in the return value of the Red-Black Tree delete method. test: Test the clone methods of all the binary tree data structures.
This commit is contained in:
parent
50a5c06798
commit
eb590d6c27
|
@ -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.49.6](https://github.com/zrwusa/data-structure-typed/compare/v1.35.0...main) (upcoming)
|
||||
## [v1.49.7](https://github.com/zrwusa/data-structure-typed/compare/v1.35.0...main) (upcoming)
|
||||
|
||||
### Changes
|
||||
|
||||
|
|
|
@ -1509,8 +1509,8 @@ export class BinaryTree<
|
|||
if (current && this.isNodeOrNull(current.left)) queue.push(current.left);
|
||||
if (current && this.isNodeOrNull(current.right)) queue.push(current.right);
|
||||
} else {
|
||||
if (current.left) queue.push(current.left);
|
||||
if (current.right) queue.push(current.right);
|
||||
if (this.isRealNode(current.left)) queue.push(current.left);
|
||||
if (this.isRealNode(current.right)) queue.push(current.right);
|
||||
}
|
||||
|
||||
traverse(level + 1);
|
||||
|
@ -1530,8 +1530,8 @@ export class BinaryTree<
|
|||
if (current && this.isNodeOrNull(current.left)) queue.push(current.left);
|
||||
if (current && this.isNodeOrNull(current.right)) queue.push(current.right);
|
||||
} else {
|
||||
if (current.left) queue.push(current.left);
|
||||
if (current.right) queue.push(current.right);
|
||||
if (this.isRealNode(current.left)) queue.push(current.left);
|
||||
if (this.isRealNode(current.right)) queue.push(current.right);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -106,7 +106,6 @@ export class RedBlackTree<
|
|||
override createTree(options?: RBTreeOptions<K>): TREE {
|
||||
return new RedBlackTree<K, V, N, TREE>([], {
|
||||
iterationType: this.iterationType,
|
||||
variant: this.variant,
|
||||
...options
|
||||
}) as TREE;
|
||||
}
|
||||
|
@ -316,9 +315,9 @@ export class RedBlackTree<
|
|||
this._fixDelete(x!);
|
||||
}
|
||||
this._size--;
|
||||
ans.push({ deleted: z, needBalanced: undefined });
|
||||
};
|
||||
helper(this.root);
|
||||
// TODO
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,4 +7,4 @@ export type RedBlackTreeNodeNested<K, V> = RedBlackTreeNode<K, V, RedBlackTreeNo
|
|||
|
||||
export type RedBlackTreeNested<K, V, N extends RedBlackTreeNode<K, V, N>> = RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
export type RBTreeOptions<K> = BSTOptions<K> & {};
|
||||
export type RBTreeOptions<K> = Omit<BSTOptions<K>, 'variant'> & {};
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
<meta charset='UTF-8'>
|
||||
<title>CDN Test</title>
|
||||
<!-- <script src="../../dist/umd/data-structure-typed.min.js"></script>-->
|
||||
<!-- <script src="../../dist/umd/data-structure-typed.js"></script>-->
|
||||
<script src='https://cdn.jsdelivr.net/npm/data-structure-typed/dist/umd/data-structure-typed.min.js'></script>
|
||||
<script src="../../dist/umd/data-structure-typed.js"></script>
|
||||
<!-- <script src='https://cdn.jsdelivr.net/npm/data-structure-typed/dist/umd/data-structure-typed.min.js'></script>-->
|
||||
<!-- <script src='https://cdn.jsdelivr.net/npm/data-structure-typed@1.42.2/dist/umd/data-structure-typed.min.js'></script>-->
|
||||
<!-- <script src='https://cdn.jsdelivr.net/npm/data-structure-typed@1.43.3/dist/umd/data-structure-typed.min.js'></script>-->
|
||||
<!-- <script src='https://cdn.jsdelivr.net/npm/data-structure-typed@1.44.0/dist/umd/data-structure-typed.min.js'></script>-->
|
||||
|
@ -114,7 +114,7 @@
|
|||
try {
|
||||
const { PriorityQueue: CPriorityQueue } = sdsl;
|
||||
const { PriorityQueue } = dataStructureTyped;
|
||||
const pq = new PriorityQueue({ comparator: (a, b) => b - a });
|
||||
const pq = new PriorityQueue([], { comparator: (a, b) => b - a });
|
||||
|
||||
const tS = performance.now();
|
||||
const n = 1000000;
|
||||
|
@ -123,7 +123,7 @@
|
|||
}
|
||||
|
||||
for (let i = 0; i < n; i++) {
|
||||
pq.pop();
|
||||
pq.poll();
|
||||
}
|
||||
console.log((performance.now() - tS).toFixed(2), `PriorityQueue ${n.toLocaleString()} add`);
|
||||
console.log(pq.size, `pq.size`);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { AVLTree, BST } from '../../../../src';
|
||||
import { AVLTree, BST, BSTVariant, IterationType, RedBlackTree, TreeMultimap } from '../../../../src';
|
||||
|
||||
describe('Overall BinaryTree Test', () => {
|
||||
it('should perform various operations on BinaryTree', () => {
|
||||
|
@ -60,4 +60,183 @@ describe('Overall BinaryTree Test', () => {
|
|||
avlTree.isAVLBalanced(); // true
|
||||
expect(avlTree.isAVLBalanced()).toBe(true); // true
|
||||
});
|
||||
|
||||
it('Should clone a BST works fine', () => {
|
||||
const bst = new BST<number>([3, 6, 7, 1, 9], {
|
||||
iterationType: IterationType.RECURSIVE,
|
||||
variant: BSTVariant.INVERSE,
|
||||
extractor: key => key
|
||||
});
|
||||
expect(bst.size).toBe(5);
|
||||
expect(bst.root?.key).toBe(6);
|
||||
expect(bst.root?.left?.key).toBe(7);
|
||||
expect(bst.root?.left?.left?.key).toBe(9);
|
||||
expect(bst.root?.right?.key).toBe(1);
|
||||
expect(bst.root?.right?.left?.key).toBe(3);
|
||||
expect(bst.getNodeByKey(7)?.left?.key).toBe(9);
|
||||
expect(bst.getHeight()).toBe(2);
|
||||
expect(bst.has(9)).toBe(true);
|
||||
expect(bst.has(7)).toBe(true);
|
||||
expect(bst.delete(7)[0].deleted?.key).toBe(7);
|
||||
expect(bst.has(7)).toBe(false);
|
||||
expect(bst.size).toBe(4);
|
||||
expect(bst.root?.key).toBe(6);
|
||||
expect(bst.root?.left?.key).toBe(9);
|
||||
expect(bst.root?.right?.key).toBe(1);
|
||||
expect(bst.root?.right?.left?.key).toBe(3);
|
||||
expect(bst.getNodeByKey(6)?.left?.key).toBe(9);
|
||||
expect(bst.getHeight()).toBe(2);
|
||||
expect(bst.has(9)).toBe(true);
|
||||
expect(bst.has(7)).toBe(false);
|
||||
expect(bst.bfs()).toEqual([6, 9, 1, 3]);
|
||||
const clonedBST = bst.clone();
|
||||
expect(clonedBST.size).toBe(4);
|
||||
expect(clonedBST.root?.key).toBe(6);
|
||||
expect(clonedBST.root?.left?.key).toBe(9);
|
||||
expect(clonedBST.root?.right?.key).toBe(1);
|
||||
expect(clonedBST.root?.right?.left?.key).toBe(3);
|
||||
expect(clonedBST.getNodeByKey(6)?.left?.key).toBe(9);
|
||||
expect(clonedBST.getHeight()).toBe(2);
|
||||
expect(clonedBST.has(9)).toBe(true);
|
||||
expect(clonedBST.has(7)).toBe(false);
|
||||
expect(clonedBST.bfs()).toEqual([6, 9, 1, 3]);
|
||||
});
|
||||
|
||||
it('Should clone a AVLTree works fine', () => {
|
||||
const avl = new AVLTree<number>([3, 6, 7, 1, 9], {
|
||||
iterationType: IterationType.RECURSIVE,
|
||||
variant: BSTVariant.INVERSE,
|
||||
extractor: key => key
|
||||
});
|
||||
expect(avl.size).toBe(5);
|
||||
avl.add(2);
|
||||
avl.add(5);
|
||||
avl.add(4);
|
||||
expect(avl.root?.key).toBe(3);
|
||||
expect(avl.root?.left?.key).toBe(7);
|
||||
expect(avl.root?.left?.left?.key).toBe(9);
|
||||
expect(avl.root?.right?.key).toBe(1);
|
||||
expect(avl.root?.right?.left?.key).toBe(2);
|
||||
expect(avl.getNodeByKey(7)?.left?.key).toBe(9);
|
||||
expect(avl.getHeight()).toBe(3);
|
||||
expect(avl.has(9)).toBe(true);
|
||||
expect(avl.has(7)).toBe(true);
|
||||
expect(avl.delete(7)[0].deleted?.key).toBe(7);
|
||||
expect(avl.has(7)).toBe(false);
|
||||
expect(avl.size).toBe(7);
|
||||
expect(avl.root?.key).toBe(3);
|
||||
expect(avl.root?.left?.key).toBe(5);
|
||||
expect(avl.root?.right?.key).toBe(1);
|
||||
expect(avl.root?.right?.left?.key).toBe(2);
|
||||
expect(avl.getNodeByKey(6)?.left?.key).toBe(undefined);
|
||||
expect(avl.getHeight()).toBe(3);
|
||||
expect(avl.has(9)).toBe(true);
|
||||
expect(avl.has(7)).toBe(false);
|
||||
expect(avl.bfs()).toEqual([3, 5, 1, 9, 4, 2, 6]);
|
||||
const clonedAVL = avl.clone();
|
||||
expect(clonedAVL.size).toBe(7);
|
||||
expect(clonedAVL.root?.key).toBe(3);
|
||||
expect(clonedAVL.root?.left?.key).toBe(5);
|
||||
expect(clonedAVL.root?.right?.key).toBe(1);
|
||||
expect(clonedAVL.root?.right?.left?.key).toBe(2);
|
||||
expect(clonedAVL.getNodeByKey(6)?.left?.key).toBe(undefined);
|
||||
expect(clonedAVL.getHeight()).toBe(3);
|
||||
expect(clonedAVL.has(9)).toBe(true);
|
||||
expect(clonedAVL.has(7)).toBe(false);
|
||||
expect(clonedAVL.bfs()).toEqual([3, 5, 1, 9, 4, 2, 6]);
|
||||
});
|
||||
|
||||
it('Should clone a TreeMultimap works fine', () => {
|
||||
const tmm = new TreeMultimap<number>([3, 6, 7, 1, 9], {
|
||||
iterationType: IterationType.RECURSIVE,
|
||||
variant: BSTVariant.INVERSE,
|
||||
extractor: key => key
|
||||
});
|
||||
expect(tmm.size).toBe(5);
|
||||
tmm.add(2);
|
||||
tmm.add(2);
|
||||
tmm.add(2);
|
||||
tmm.add(5);
|
||||
tmm.add(4);
|
||||
expect(tmm.count).toBe(10);
|
||||
expect(tmm.root?.key).toBe(3);
|
||||
expect(tmm.root?.left?.key).toBe(7);
|
||||
expect(tmm.root?.left?.left?.key).toBe(9);
|
||||
expect(tmm.root?.right?.key).toBe(1);
|
||||
expect(tmm.root?.right?.left?.key).toBe(2);
|
||||
expect(tmm.getNodeByKey(7)?.left?.key).toBe(9);
|
||||
expect(tmm.getHeight()).toBe(3);
|
||||
expect(tmm.has(9)).toBe(true);
|
||||
expect(tmm.has(7)).toBe(true);
|
||||
expect(tmm.delete(7)[0].deleted?.key).toBe(7);
|
||||
expect(tmm.has(7)).toBe(false);
|
||||
expect(tmm.size).toBe(7);
|
||||
expect(tmm.count).toBe(9);
|
||||
expect(tmm.root?.key).toBe(3);
|
||||
expect(tmm.root?.left?.key).toBe(5);
|
||||
expect(tmm.root?.right?.key).toBe(1);
|
||||
expect(tmm.root?.right?.left?.key).toBe(2);
|
||||
expect(tmm.getNodeByKey(6)?.left?.key).toBe(undefined);
|
||||
expect(tmm.getHeight()).toBe(3);
|
||||
expect(tmm.has(9)).toBe(true);
|
||||
expect(tmm.has(7)).toBe(false);
|
||||
expect(tmm.bfs()).toEqual([3, 5, 1, 9, 4, 2, 6]);
|
||||
const clonedTMM = tmm.clone();
|
||||
expect(clonedTMM.size).toBe(7);
|
||||
expect(clonedTMM.count).toBe(9);
|
||||
expect(clonedTMM.root?.key).toBe(3);
|
||||
expect(clonedTMM.root?.left?.key).toBe(5);
|
||||
expect(clonedTMM.root?.right?.key).toBe(1);
|
||||
expect(clonedTMM.root?.right?.left?.key).toBe(2);
|
||||
expect(clonedTMM.getNodeByKey(6)?.left?.key).toBe(undefined);
|
||||
expect(clonedTMM.getHeight()).toBe(3);
|
||||
expect(clonedTMM.has(9)).toBe(true);
|
||||
expect(clonedTMM.has(7)).toBe(false);
|
||||
expect(clonedTMM.bfs()).toEqual([3, 5, 1, 9, 4, 2, 6]);
|
||||
});
|
||||
|
||||
it('Should clone a RedBlackTree works fine', () => {
|
||||
const rbTree = new RedBlackTree<number>([3, 6, 7, 1, 9], {
|
||||
iterationType: IterationType.RECURSIVE,
|
||||
extractor: key => key
|
||||
});
|
||||
expect(rbTree.size).toBe(5);
|
||||
rbTree.add(2);
|
||||
rbTree.add(2);
|
||||
rbTree.add(2);
|
||||
rbTree.add(5);
|
||||
rbTree.add(4);
|
||||
expect(rbTree.root?.key).toBe(3);
|
||||
expect(rbTree.root?.left?.key).toBe(1);
|
||||
expect(rbTree.root?.left?.left?.key).toBe(NaN);
|
||||
expect(rbTree.root?.right?.key).toBe(7);
|
||||
expect(rbTree.root?.right?.left?.key).toBe(5);
|
||||
expect(rbTree.getNodeByKey(7)?.left?.key).toBe(5);
|
||||
expect(rbTree.getHeight()).toBe(4);
|
||||
expect(rbTree.has(9)).toBe(true);
|
||||
expect(rbTree.has(7)).toBe(true);
|
||||
expect(rbTree.delete(7)?.[0]?.deleted?.key).toBe(7);
|
||||
expect(rbTree.has(7)).toBe(false);
|
||||
expect(rbTree.size).toBe(7);
|
||||
expect(rbTree.root?.key).toBe(3);
|
||||
expect(rbTree.root?.left?.key).toBe(1);
|
||||
expect(rbTree.root?.right?.key).toBe(5);
|
||||
expect(rbTree.root?.right?.left?.key).toBe(4);
|
||||
expect(rbTree.getNodeByKey(6)?.left?.key).toBe(NaN);
|
||||
expect(rbTree.getHeight()).toBe(4);
|
||||
expect(rbTree.has(9)).toBe(true);
|
||||
expect(rbTree.has(7)).toBe(false);
|
||||
expect(rbTree.bfs()).toEqual([3, 1, 5, 2, 4, 9, 6]);
|
||||
const clonedRbTree = rbTree.clone();
|
||||
expect(clonedRbTree.size).toBe(7);
|
||||
expect(clonedRbTree.root?.key).toBe(3);
|
||||
expect(clonedRbTree.root?.left?.key).toBe(1);
|
||||
expect(clonedRbTree.root?.right?.key).toBe(5);
|
||||
expect(clonedRbTree.root?.right?.left?.key).toBe(4);
|
||||
expect(clonedRbTree.getNodeByKey(6)?.left?.key).toBe(NaN);
|
||||
expect(clonedRbTree.getHeight()).toBe(4);
|
||||
expect(clonedRbTree.has(9)).toBe(true);
|
||||
expect(clonedRbTree.has(7)).toBe(false);
|
||||
expect(clonedRbTree.bfs()).toEqual([3, 1, 5, 2, 4, 9, 6]);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -108,12 +108,25 @@ describe('HashMap Test2', () => {
|
|||
expect(hashMap.get(keyObj)).toBe('objectValue');
|
||||
});
|
||||
|
||||
// it('should handle number keys correctly', () => {
|
||||
// hashMap.set(999, { a: '999Value' });
|
||||
// hashMap.set('999', {a: '999StrValue'})
|
||||
// expect(hashMap.get(999)).toEqual({ a: '999Value' });
|
||||
// expect(hashMap.get('999')).toEqual({ a: '999StrValue' });
|
||||
// });
|
||||
test('Inheritability test', () => {
|
||||
class ExtendedHashMap<K, V> extends HashMap<K, V> {
|
||||
constructor(
|
||||
elements: Iterable<[K, V]> = [],
|
||||
options?: {
|
||||
hashFn?: (key: K) => string;
|
||||
someOtherParam: string;
|
||||
}
|
||||
) {
|
||||
const { someOtherParam, ...restOptions } = options || {};
|
||||
// do something with someOtherParam
|
||||
super(elements, restOptions);
|
||||
}
|
||||
}
|
||||
|
||||
const eHM = new ExtendedHashMap<string, number>([], { someOtherParam: 'someOtherParam' });
|
||||
eHM.set('one', 1);
|
||||
expect(eHM.get('one')).toBe(1);
|
||||
});
|
||||
|
||||
it('should update the value for an existing key', () => {
|
||||
hashMap.set('key1', 'value1');
|
||||
|
|
Loading…
Reference in a new issue