data-structure-typed 1.44.0 → 1.45.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/README.md +15 -15
  3. package/benchmark/report.html +30 -30
  4. package/benchmark/report.json +144 -198
  5. package/dist/cjs/data-structures/hash/hash-map.d.ts +230 -37
  6. package/dist/cjs/data-structures/hash/hash-map.js +430 -118
  7. package/dist/cjs/data-structures/hash/hash-map.js.map +1 -1
  8. package/dist/cjs/types/data-structures/graph/directed-graph.d.ts +0 -5
  9. package/dist/cjs/types/data-structures/graph/directed-graph.js +0 -7
  10. package/dist/cjs/types/data-structures/graph/directed-graph.js.map +1 -1
  11. package/dist/cjs/types/data-structures/hash/hash-map.d.ts +15 -1
  12. package/dist/cjs/types/data-structures/hash/index.d.ts +6 -0
  13. package/dist/cjs/types/data-structures/hash/index.js +20 -0
  14. package/dist/cjs/types/data-structures/hash/index.js.map +1 -1
  15. package/dist/cjs/utils/utils.d.ts +3 -0
  16. package/dist/cjs/utils/utils.js +15 -1
  17. package/dist/cjs/utils/utils.js.map +1 -1
  18. package/dist/mjs/data-structures/hash/hash-map.d.ts +230 -37
  19. package/dist/mjs/data-structures/hash/hash-map.js +435 -123
  20. package/dist/mjs/types/data-structures/graph/directed-graph.d.ts +0 -5
  21. package/dist/mjs/types/data-structures/graph/directed-graph.js +1 -6
  22. package/dist/mjs/types/data-structures/hash/hash-map.d.ts +15 -1
  23. package/dist/mjs/types/data-structures/hash/index.d.ts +6 -0
  24. package/dist/mjs/types/data-structures/hash/index.js +6 -1
  25. package/dist/mjs/utils/utils.d.ts +3 -0
  26. package/dist/mjs/utils/utils.js +11 -0
  27. package/dist/umd/data-structure-typed.js +532 -217
  28. package/dist/umd/data-structure-typed.min.js +1 -1
  29. package/dist/umd/data-structure-typed.min.js.map +1 -1
  30. package/package.json +9 -7
  31. package/src/data-structures/hash/hash-map.ts +432 -125
  32. package/src/types/data-structures/graph/directed-graph.ts +0 -6
  33. package/src/types/data-structures/hash/hash-map.ts +17 -1
  34. package/src/types/data-structures/hash/index.ts +7 -0
  35. package/src/utils/utils.ts +13 -0
  36. package/test/integration/all-in-one.ts +110 -0
  37. package/test/performance/reportor.ts +2 -2
  38. package/test/unit/data-structures/binary-tree/avl-tree.test.ts +2 -2
  39. package/test/unit/data-structures/binary-tree/bst.test.ts +6 -6
  40. package/test/unit/data-structures/binary-tree/overall.test.ts +1 -1
  41. package/test/unit/data-structures/binary-tree/rb-tree.test.ts +14 -14
  42. package/test/unit/data-structures/binary-tree/tree-multimap.test.ts +2 -2
  43. package/test/unit/data-structures/graph/abstract-graph.test.ts +2 -1
  44. package/test/unit/data-structures/graph/undirected-graph.test.ts +1 -1
  45. package/test/unit/data-structures/hash/hash-map.test.ts +151 -20
  46. package/test/unit/data-structures/heap/heap.test.ts +8 -8
  47. package/test/unit/data-structures/heap/max-heap.test.ts +4 -4
  48. package/test/unit/data-structures/heap/min-heap.test.ts +4 -4
  49. package/test/unit/data-structures/linked-list/doubly-linked-list.test.ts +1 -1
  50. package/test/unit/data-structures/linked-list/singly-linked-list.test.ts +2 -2
  51. package/test/unit/data-structures/linked-list/skip-list.test.ts +4 -4
  52. package/test/unit/data-structures/priority-queue/max-priority-queue.test.ts +2 -2
  53. package/test/unit/data-structures/priority-queue/priority-queue.test.ts +8 -2
  54. package/test/unit/data-structures/queue/deque.test.ts +25 -25
  55. package/test/unit/data-structures/trie/trie.test.ts +9 -9
  56. package/test/utils/array.ts +1 -1
  57. package/test/utils/number.ts +1 -1
@@ -1,8 +1,2 @@
1
1
  // 0 means unknown, 1 means visiting, 2 means visited;
2
2
  export type TopologicalStatus = 0 | 1 | 2;
3
-
4
- export enum TopologicalProperty {
5
- VAL = 'VAL',
6
- NODE = 'NODE',
7
- ID = 'ID'
8
- }
@@ -1 +1,17 @@
1
- export {};
1
+ export const enum IterateDirection {
2
+ DEFAULT = 0,
3
+ REVERSE = 1
4
+ }
5
+
6
+ export type HashMapOptions<T> = {
7
+ sizeFunction?: number | (() => number);
8
+ fixedLength?: number;
9
+ forEach: (callback: (el: T) => void) => void;
10
+ }
11
+
12
+ export type HashMapLinkedNode<K, V> = {
13
+ key: K
14
+ value: V
15
+ next: HashMapLinkedNode<K, V>
16
+ prev: HashMapLinkedNode<K, V>
17
+ }
@@ -1 +1,8 @@
1
+ export * from './coordinate-map';
2
+ export * from './coordinate-set';
3
+ export * from './hash-map';
4
+ export * from './hash-table';
5
+ export * from './tree-map';
6
+ export * from './tree-set';
7
+
1
8
  export type HashFunction<K> = (key: K) => number;
@@ -84,3 +84,16 @@ export const getMSB = (value: number): number => {
84
84
  }
85
85
  return 1 << (31 - Math.clz32(value));
86
86
  };
87
+
88
+ export const rangeCheck = (index: number, min: number, max: number, message = 'Index out of bounds.'): void => {
89
+ if (index < min || index > max) throw new RangeError(message);
90
+ }
91
+
92
+ export const throwRangeError = (message = 'The value is off-limits.'): void => {
93
+ throw new RangeError(message);
94
+ }
95
+
96
+ export const isObjOrFunc = (input: unknown): input is Record<string, unknown> | ((...args: any[]) => any) => {
97
+ const inputType = typeof input;
98
+ return (inputType === 'object' && input !== null) || inputType === 'function';
99
+ }
@@ -0,0 +1,110 @@
1
+ import {AVLTree, CP} from 'data-structure-typed';
2
+
3
+ describe('AVL Tree Test from data-structure-typed', () => {
4
+ it('should perform various operations on a AVL Tree from data-structure-typed', () => {
5
+ const keys = [11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5];
6
+ const tree = new AVLTree();
7
+
8
+ for (const i of keys) tree.add(i, i);
9
+
10
+ const node6 = tree.get(6);
11
+
12
+ expect(node6 && tree.getHeight(node6)).toBe(3);
13
+ expect(node6 && tree.getDepth(node6)).toBe(1);
14
+
15
+ const getValueById = tree.get(10);
16
+ expect(getValueById).toBe(10);
17
+
18
+ const getMinNodeByRoot = tree.getLeftMost();
19
+ expect(getMinNodeByRoot?.key).toBe(1);
20
+
21
+ const node15 = tree.getNode(15);
22
+ const getMinNodeBySpecificNode = node15 && tree.getLeftMost(node15);
23
+ expect(getMinNodeBySpecificNode?.key).toBe(12);
24
+
25
+ let subTreeSum = 0;
26
+ node15 && tree.subTreeTraverse(node => (subTreeSum += node.key), 15);
27
+ expect(subTreeSum).toBe(70);
28
+
29
+ let lesserSum = 0;
30
+ tree.lesserOrGreaterTraverse(node => (lesserSum += node.key), CP.lt, 10);
31
+ expect(lesserSum).toBe(45);
32
+
33
+ // 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.
34
+ expect(node15?.value).toBe(15);
35
+
36
+ const dfs = tree.dfs(node => node, 'in');
37
+ expect(dfs[0].key).toBe(1);
38
+ expect(dfs[dfs.length - 1].key).toBe(16);
39
+
40
+ tree.perfectlyBalance();
41
+ const bfs = tree.bfs(node => node);
42
+ expect(tree.isPerfectlyBalanced()).toBe(true);
43
+ expect(bfs[0].key).toBe(8);
44
+ expect(bfs[bfs.length - 1].key).toBe(16);
45
+
46
+ expect(tree.delete(11)[0].deleted?.key).toBe(11);
47
+ expect(tree.isAVLBalanced()).toBe(true);
48
+ expect(node15 && tree.getHeight(node15)).toBe(2);
49
+
50
+ expect(tree.delete(1)[0].deleted?.key).toBe(1);
51
+ expect(tree.isAVLBalanced()).toBe(true);
52
+ expect(tree.getHeight()).toBe(4);
53
+
54
+ expect(tree.delete(4)[0].deleted?.key).toBe(4);
55
+ expect(tree.isAVLBalanced()).toBe(true);
56
+ expect(tree.getHeight()).toBe(4);
57
+
58
+ expect(tree.delete(10)[0].deleted?.key).toBe(10);
59
+ expect(tree.isAVLBalanced()).toBe(true);
60
+ expect(tree.getHeight()).toBe(3);
61
+
62
+ expect(tree.delete(15)[0].deleted?.key).toBe(15);
63
+ expect(tree.isAVLBalanced()).toBe(true);
64
+
65
+ expect(tree.getHeight()).toBe(3);
66
+
67
+ expect(tree.delete(5)[0].deleted?.key).toBe(5);
68
+ expect(tree.isAVLBalanced()).toBe(true);
69
+ expect(tree.getHeight()).toBe(3);
70
+
71
+ expect(tree.delete(13)[0].deleted?.key).toBe(13);
72
+ expect(tree.isAVLBalanced()).toBe(true);
73
+ expect(tree.getHeight()).toBe(3);
74
+
75
+ expect(tree.delete(3)[0].deleted?.key).toBe(3);
76
+ expect(tree.isAVLBalanced()).toBe(true);
77
+ expect(tree.getHeight()).toBe(3);
78
+
79
+ expect(tree.delete(8)[0].deleted?.key).toBe(8);
80
+ expect(tree.isAVLBalanced()).toBe(true);
81
+ expect(tree.getHeight()).toBe(3);
82
+
83
+ expect(tree.delete(6)[0].deleted?.key).toBe(6);
84
+ expect(tree.delete(6).length).toBe(0);
85
+ expect(tree.isAVLBalanced()).toBe(true);
86
+ expect(tree.getHeight()).toBe(2);
87
+
88
+ expect(tree.delete(7)[0].deleted?.key).toBe(7);
89
+ expect(tree.isAVLBalanced()).toBe(true);
90
+ expect(tree.getHeight()).toBe(2);
91
+
92
+ expect(tree.delete(9)[0].deleted?.key).toBe(9);
93
+ expect(tree.isAVLBalanced()).toBe(true);
94
+ expect(tree.getHeight()).toBe(2);
95
+ expect(tree.delete(14)[0].deleted?.key).toBe(14);
96
+ expect(tree.isAVLBalanced()).toBe(true);
97
+ expect(tree.getHeight()).toBe(1);
98
+
99
+ expect(tree.isAVLBalanced()).toBe(true);
100
+ const lastBFSIds = tree.bfs();
101
+ expect(lastBFSIds[0]).toBe(12);
102
+ expect(lastBFSIds[1]).toBe(2);
103
+ expect(lastBFSIds[2]).toBe(16);
104
+
105
+ const lastBFSNodes = tree.bfs(node => node);
106
+ expect(lastBFSNodes[0].key).toBe(12);
107
+ expect(lastBFSNodes[1].key).toBe(2);
108
+ expect(lastBFSNodes[2].key).toBe(16);
109
+ });
110
+ });
@@ -107,7 +107,7 @@ const composeReport = () => {
107
107
  htmlTables // New content to be inserted
108
108
  );
109
109
  fs.writeFileSync(htmlFilePath, html);
110
- console.log(`Performance ${BOLD}${GREEN}report${END} file generated`);
110
+ console.log(`Performance ${BOLD}${GREEN}report${END} file generated in ${BOLD}${GREEN}${reportDistPath}${END}`);
111
111
  };
112
112
 
113
113
  function replaceMarkdownContent(startMarker: string, endMarker: string, newText: string) {
@@ -135,7 +135,7 @@ function replaceMarkdownContent(startMarker: string, endMarker: string, newText:
135
135
  if (err) {
136
136
  console.error(`Unable to write to ${filePath}:`, err);
137
137
  } else {
138
- console.log(`The content has been successfully replaced in ${filePath}!`);
138
+ console.log(`The content has been successfully replaced in ${BOLD}${GREEN}${filePath}!${END}`);
139
139
  }
140
140
  });
141
141
  });
@@ -219,7 +219,7 @@ describe('AVL Tree Test recursively', () => {
219
219
  });
220
220
 
221
221
  describe('AVLTree APIs test', () => {
222
- const avl = new AVLTree<{id: number; text: string}>();
222
+ const avl = new AVLTree<{ id: number; text: string }>();
223
223
  beforeEach(() => {
224
224
  avl.clear();
225
225
  });
@@ -268,7 +268,7 @@ describe('AVLTree', () => {
268
268
  });
269
269
 
270
270
  describe('BinaryTree APIs test', () => {
271
- const avl = new AVLTree<{id: number; text: string}>();
271
+ const avl = new AVLTree<{ id: number; text: string }>();
272
272
  beforeEach(() => {
273
273
  avl.clear();
274
274
  });
@@ -189,7 +189,7 @@ describe('BST operations test', () => {
189
189
  });
190
190
 
191
191
  it('should perform various operations on a Binary Search Tree with object values', () => {
192
- const objBST = new BST<{key: number; keyA: number}>();
192
+ const objBST = new BST<{ key: number; keyA: number }>();
193
193
  expect(objBST).toBeInstanceOf(BST);
194
194
  objBST.add(11, {key: 11, keyA: 11});
195
195
  objBST.add(3, {key: 3, keyA: 3});
@@ -260,7 +260,7 @@ describe('BST operations test', () => {
260
260
  objBST.perfectlyBalance();
261
261
  expect(objBST.isPerfectlyBalanced()).toBe(true);
262
262
 
263
- const bfsNodesAfterBalanced: BSTNode<{key: number; keyA: number}>[] = [];
263
+ const bfsNodesAfterBalanced: BSTNode<{ key: number; keyA: number }>[] = [];
264
264
  objBST.bfs(node => bfsNodesAfterBalanced.push(node));
265
265
  expect(bfsNodesAfterBalanced[0].key).toBe(8);
266
266
  expect(bfsNodesAfterBalanced[bfsNodesAfterBalanced.length - 1].key).toBe(16);
@@ -385,7 +385,7 @@ describe('BST operations test', () => {
385
385
  expect(bfsIDs[1]).toBe(12);
386
386
  expect(bfsIDs[2]).toBe(16);
387
387
 
388
- const bfsNodes: BSTNode<{key: number; keyA: number}>[] = [];
388
+ const bfsNodes: BSTNode<{ key: number; keyA: number }>[] = [];
389
389
  objBST.bfs(node => bfsNodes.push(node));
390
390
  expect(bfsNodes[0].key).toBe(2);
391
391
  expect(bfsNodes[1].key).toBe(12);
@@ -580,7 +580,7 @@ describe('BST operations test recursively', () => {
580
580
  });
581
581
 
582
582
  it('should perform various operations on a Binary Search Tree with object values', () => {
583
- const objBST = new BST<{key: number; keyA: number}>();
583
+ const objBST = new BST<{ key: number; keyA: number }>();
584
584
  expect(objBST).toBeInstanceOf(BST);
585
585
  objBST.add(11, {key: 11, keyA: 11});
586
586
  objBST.add(3, {key: 3, keyA: 3});
@@ -652,7 +652,7 @@ describe('BST operations test recursively', () => {
652
652
  objBST.perfectlyBalance();
653
653
  expect(objBST.isPerfectlyBalanced()).toBe(true);
654
654
 
655
- const bfsNodesAfterBalanced: BSTNode<{key: number; keyA: number}>[] = [];
655
+ const bfsNodesAfterBalanced: BSTNode<{ key: number; keyA: number }>[] = [];
656
656
  objBST.bfs(node => bfsNodesAfterBalanced.push(node));
657
657
  expect(bfsNodesAfterBalanced[0].key).toBe(8);
658
658
  expect(bfsNodesAfterBalanced[bfsNodesAfterBalanced.length - 1].key).toBe(16);
@@ -777,7 +777,7 @@ describe('BST operations test recursively', () => {
777
777
  expect(bfsIDs[1]).toBe(12);
778
778
  expect(bfsIDs[2]).toBe(16);
779
779
 
780
- const bfsNodes: BSTNode<{key: number; keyA: number}>[] = [];
780
+ const bfsNodes: BSTNode<{ key: number; keyA: number }>[] = [];
781
781
  objBST.bfs(node => bfsNodes.push(node));
782
782
  expect(bfsNodes[0].key).toBe(2);
783
783
  expect(bfsNodes[1].key).toBe(12);
@@ -29,7 +29,7 @@ describe('Overall BinaryTree Test', () => {
29
29
  bfsIDs[0] === 11; // true
30
30
  expect(bfsIDs[0]).toBe(11);
31
31
 
32
- const objBST = new BST<{key: number; keyA: number}>();
32
+ const objBST = new BST<{ key: number; keyA: number }>();
33
33
  objBST.add(11, {key: 11, keyA: 11});
34
34
  objBST.add(3, {key: 3, keyA: 3});
35
35
 
@@ -13,7 +13,7 @@ describe('RedBlackTree', () => {
13
13
  });
14
14
 
15
15
  describe('add and getNode', () => {
16
- test('should add and find a node in the tree', () => {
16
+ it('should add and find a node in the tree', () => {
17
17
  tree.add(10);
18
18
  tree.add(20);
19
19
  tree.add(5);
@@ -24,7 +24,7 @@ describe('RedBlackTree', () => {
24
24
  expect(tree.getNode(15)).toBe(undefined);
25
25
  });
26
26
 
27
- test('should add and find nodes with negative keys', () => {
27
+ it('should add and find nodes with negative keys', () => {
28
28
  tree.add(-10);
29
29
  tree.add(-20);
30
30
 
@@ -34,7 +34,7 @@ describe('RedBlackTree', () => {
34
34
  });
35
35
 
36
36
  describe('deleteNode', () => {
37
- test('should delete a node from the tree', () => {
37
+ it('should delete a node from the tree', () => {
38
38
  tree.add(10);
39
39
  tree.add(20);
40
40
  tree.add(5);
@@ -43,7 +43,7 @@ describe('RedBlackTree', () => {
43
43
  expect(tree.getNode(20)).toBe(undefined);
44
44
  });
45
45
 
46
- test('should handle deleting a non-existent node', () => {
46
+ it('should handle deleting a non-existent node', () => {
47
47
  tree.add(10);
48
48
  tree.add(20);
49
49
  tree.add(5);
@@ -54,7 +54,7 @@ describe('RedBlackTree', () => {
54
54
  });
55
55
 
56
56
  describe('minimum', () => {
57
- test('should find the minimum node in the tree', () => {
57
+ it('should find the minimum node in the tree', () => {
58
58
  tree.add(10);
59
59
  tree.add(20);
60
60
  tree.add(5);
@@ -65,14 +65,14 @@ describe('RedBlackTree', () => {
65
65
  expect(minNode?.key).toBe(3);
66
66
  });
67
67
 
68
- test('should handle an empty tree', () => {
68
+ it('should handle an empty tree', () => {
69
69
  const minNode = tree.getLeftMost(tree.root);
70
70
  expect(minNode).toBe(tree.NIL);
71
71
  });
72
72
  });
73
73
 
74
74
  describe('getRightMost', () => {
75
- test('should find the getRightMost node in the tree', () => {
75
+ it('should find the getRightMost node in the tree', () => {
76
76
  tree.add(10);
77
77
  tree.add(20);
78
78
  tree.add(5);
@@ -83,14 +83,14 @@ describe('RedBlackTree', () => {
83
83
  expect(maxNode?.key).toBe(25);
84
84
  });
85
85
 
86
- test('should handle an empty tree', () => {
86
+ it('should handle an empty tree', () => {
87
87
  const maxNode = tree.getRightMost(tree.root);
88
88
  expect(maxNode).toBe(tree.NIL);
89
89
  });
90
90
  });
91
91
 
92
92
  describe('getSuccessor', () => {
93
- test('should find the getSuccessor of a node', () => {
93
+ it('should find the getSuccessor of a node', () => {
94
94
  tree.add(10);
95
95
  tree.add(20);
96
96
  tree.add(5);
@@ -103,7 +103,7 @@ describe('RedBlackTree', () => {
103
103
  expect(successorNode?.key).toBe(20);
104
104
  });
105
105
 
106
- test('should handle a node with no getSuccessor', () => {
106
+ it('should handle a node with no getSuccessor', () => {
107
107
  tree.add(10);
108
108
  tree.add(5);
109
109
 
@@ -115,7 +115,7 @@ describe('RedBlackTree', () => {
115
115
  });
116
116
 
117
117
  describe('getPredecessor', () => {
118
- test('should find the getPredecessor of a node', () => {
118
+ it('should find the getPredecessor of a node', () => {
119
119
  tree.add(10);
120
120
  tree.add(20);
121
121
  tree.add(5);
@@ -128,7 +128,7 @@ describe('RedBlackTree', () => {
128
128
  expect(predecessorNode?.key).toBe(15);
129
129
  });
130
130
 
131
- test('should handle a node with no getPredecessor', () => {
131
+ it('should handle a node with no getPredecessor', () => {
132
132
  tree.add(10);
133
133
  tree.add(20);
134
134
 
@@ -478,13 +478,13 @@ describe('RedBlackTree', () => {
478
478
  for (let i = 0; i < arr.length; i++) {
479
479
  tree.add(arr[i]);
480
480
  }
481
- console.log(performance.now() - tS);
481
+ isDebug && console.log(performance.now() - tS);
482
482
 
483
483
  const cS = performance.now();
484
484
 
485
485
  for (let i = 0; i < arr.length; i++) {
486
486
  competitor.setElement(arr[i], arr[i]);
487
487
  }
488
- console.log(performance.now() - cS);
488
+ isDebug && console.log(performance.now() - cS);
489
489
  });
490
490
  });
@@ -207,7 +207,7 @@ describe('TreeMultimap operations test', () => {
207
207
  });
208
208
 
209
209
  it('should perform various operations on a Binary Search Tree with object values', () => {
210
- const objTreeMultimap = new TreeMultimap<{key: number; keyA: number}>();
210
+ const objTreeMultimap = new TreeMultimap<{ key: number; keyA: number }>();
211
211
  expect(objTreeMultimap).toBeInstanceOf(TreeMultimap);
212
212
  objTreeMultimap.add(11, {key: 11, keyA: 11});
213
213
  objTreeMultimap.add(3, {key: 3, keyA: 3});
@@ -447,7 +447,7 @@ describe('TreeMultimap operations test recursively', () => {
447
447
  });
448
448
 
449
449
  it('should perform various operations on a Binary Search Tree with object values', () => {
450
- const objTreeMultimap = new TreeMultimap<{key: number; keyA: number}>();
450
+ const objTreeMultimap = new TreeMultimap<{ key: number; keyA: number }>();
451
451
  expect(objTreeMultimap).toBeInstanceOf(TreeMultimap);
452
452
  objTreeMultimap.add(11, {key: 11, keyA: 11});
453
453
  objTreeMultimap.add(3, {key: 3, keyA: 3});
@@ -74,7 +74,8 @@ class MyGraph<V = any, E = any, VO extends MyVertex<V> = MyVertex<V>, EO extends
74
74
  describe('AbstractGraph Operation Test', () => {
75
75
  const myGraph: MyGraph<number, string> = new MyGraph<number, string>();
76
76
 
77
- beforeEach(() => {});
77
+ beforeEach(() => {
78
+ });
78
79
  it('should edge cases', function () {
79
80
  myGraph.addVertex('A', 1);
80
81
  myGraph.addVertex('B', 2);
@@ -150,7 +150,7 @@ describe('UndirectedGraph', () => {
150
150
  });
151
151
 
152
152
  it('should getAllPathsBetween work well in 66 vertexes 97 edges graph', () => {
153
- const graph = new UndirectedGraph<{name: string}, number>();
153
+ const graph = new UndirectedGraph<{ name: string }, number>();
154
154
  for (const v of saltyVertexes) {
155
155
  graph.addVertex(v.name, v);
156
156
  }
@@ -1,4 +1,6 @@
1
1
  import {HashMap} from '../../../../src';
2
+ import {getRandomInt, getRandomIntArray} from "../../../utils";
3
+
2
4
 
3
5
  describe('HashMap', () => {
4
6
  let hashMap: HashMap<string, number>;
@@ -9,10 +11,10 @@ describe('HashMap', () => {
9
11
 
10
12
  it('should initialize correctly', () => {
11
13
  expect(hashMap.size).toBe(0);
12
- expect(hashMap.table.length).toBe(16);
13
- expect(hashMap.loadFactor).toBe(0.75);
14
- expect(hashMap.capacityMultiplier).toBe(2);
15
- expect(hashMap.initialCapacity).toBe(16);
14
+ // expect(hashMap.table.length).toBe(16);
15
+ // expect(hashMap.loadFactor).toBe(0.75);
16
+ // expect(hashMap.capacityMultiplier).toBe(2);
17
+ // expect(hashMap.initialCapacity).toBe(16);
16
18
  expect(hashMap.isEmpty()).toBe(true);
17
19
  });
18
20
 
@@ -58,26 +60,23 @@ describe('HashMap', () => {
58
60
  hashMap.set('two', 2);
59
61
  hashMap.set('three', 3);
60
62
 
61
- const entries = Array.from(hashMap.entries());
62
- expect(entries).toEqual(
63
- expect.arrayContaining([
64
- ['one', 1],
65
- ['two', 2],
66
- ['three', 3]
67
- ])
68
- );
63
+ // const entries = Array.from(hashMap.entries());
64
+ // expect(entries).toContainEqual(['one', 1]);
65
+ // expect(entries).toContainEqual(['two', 2]);
66
+ // expect(entries).toContainEqual(['three', 3]);
69
67
  });
70
68
 
69
+
71
70
  it('should resize the table when load factor is exceeded', () => {
72
71
  // Set a small initial capacity for testing resizing
73
- hashMap = new HashMap<string, number>(4, 0.5);
72
+ hashMap = new HashMap<string, number>();
74
73
 
75
74
  hashMap.set('one', 1);
76
75
  hashMap.set('two', 2);
77
76
  hashMap.set('three', 3);
78
77
  hashMap.set('four', 4); // This should trigger a resize
79
78
 
80
- expect(hashMap.table.length).toBe(8);
79
+ // expect(hashMap.table.length).toBe(8);
81
80
  expect(hashMap.get('one')).toBe(1);
82
81
  expect(hashMap.get('two')).toBe(2);
83
82
  expect(hashMap.get('three')).toBe(3);
@@ -85,11 +84,8 @@ describe('HashMap', () => {
85
84
  });
86
85
 
87
86
  it('should allow using a custom hash function', () => {
88
- const customHashFn = () => {
89
- // A simple custom hash function that always returns 0
90
- return 0;
91
- };
92
- hashMap = new HashMap<string, number>(16, 0.75, customHashFn);
87
+
88
+ hashMap = new HashMap<string, number>();
93
89
 
94
90
  hashMap.set('one', 1);
95
91
  hashMap.set('two', 2);
@@ -98,6 +94,141 @@ describe('HashMap', () => {
98
94
  expect(hashMap.get('two')).toBe(2);
99
95
  // Since the custom hash function always returns 0, these keys will collide.
100
96
  // Make sure they are stored separately.
101
- expect(hashMap.table[0].length).toBe(2);
97
+ // expect(hashMap.table[0].length).toBe(2);
102
98
  });
103
99
  });
100
+
101
+ describe('HashMap', () => {
102
+ let hashMap: HashMap;
103
+
104
+ beforeEach(() => {
105
+ hashMap = new HashMap();
106
+ });
107
+
108
+ it('should create an empty map', () => {
109
+ expect(hashMap.size).toBe(0);
110
+ });
111
+
112
+ it('should add a key-value pair', () => {
113
+ hashMap.set('key1', 'value1');
114
+ expect(hashMap.get('key1')).toBe('value1');
115
+ });
116
+
117
+ it('should handle object keys correctly', () => {
118
+ const keyObj = {id: 1};
119
+ hashMap.set(keyObj, 'objectValue');
120
+ expect(hashMap.get(keyObj)).toBe('objectValue');
121
+ });
122
+
123
+ it('should handle number keys correctly', () => {
124
+ hashMap.set(999, {a: '999Value'});
125
+ expect(hashMap.get(999)).toEqual({a: '999Value'});
126
+ });
127
+
128
+ it('should update the value for an existing key', () => {
129
+ hashMap.set('key1', 'value1');
130
+ hashMap.set('key1', 'newValue');
131
+ expect(hashMap.get('key1')).toBe('newValue');
132
+ });
133
+
134
+ it('should return undefined for a non-existent key', () => {
135
+ expect(hashMap.get('nonExistentKey')).toBeUndefined();
136
+ });
137
+
138
+ it('should remove a key-value pair', () => {
139
+ hashMap.set('key1', 'value1');
140
+ hashMap.delete('key1');
141
+ expect(hashMap.get('key1')).toBeUndefined();
142
+ });
143
+
144
+ it('should clear the map', () => {
145
+ hashMap.set('key1', 'value1');
146
+ expect(hashMap.size).toBe(1);
147
+
148
+ hashMap.clear();
149
+ expect(hashMap.size).toBe(0);
150
+ });
151
+
152
+ it('should iterate over values', () => {
153
+ hashMap.set('key1', 'value1');
154
+ hashMap.set('key2', 'value2');
155
+ const values = [];
156
+ for (const value of hashMap) {
157
+ values.push(value);
158
+ }
159
+ expect(values).toEqual([['key1', 'value1'], ['key2', 'value2']]);
160
+ });
161
+
162
+ // test('should delete element at specific index', () => {
163
+ // hashMap.set('key1', 'value1');
164
+ // hashMap.set('key2', 'value2');
165
+ // hashMap.deleteAt(0);
166
+ // expect(hashMap.get('key1')).toBeUndefined();
167
+ // expect(hashMap.size).toBe(1);
168
+ // });
169
+ function compareHashMaps(hashMap: HashMap<unknown, unknown>, stdMap: Map<unknown, unknown>) {
170
+ expect(hashMap.size).toEqual(stdMap.size);
171
+ let index = 0;
172
+ stdMap.forEach((value, key) => {
173
+ if (index === 0) {
174
+ expect(hashMap.front).toEqual([key, value]);
175
+ expect(hashMap.begin.current[0]).toEqual(key);
176
+ } else if (index === hashMap.size - 1) {
177
+ expect(hashMap.back).toEqual([key, value]);
178
+ expect(hashMap.reverseBegin.current[0]).toEqual(key);
179
+ } else if (index <= 1000) {
180
+ expect(hashMap.getAt(index)).toEqual([key, value]);
181
+ }
182
+ expect(hashMap.get(key)).toEqual(value);
183
+ expect(hashMap.getIterator(key).current[1]).toEqual(value);
184
+ index++;
185
+ });
186
+ }
187
+
188
+ const stdMap: Map<unknown, unknown> = new Map();
189
+ const arr: number[] = getRandomIntArray(1000, 1, 10000);
190
+
191
+ it('delete test', () => {
192
+ for (const item of arr) {
193
+ stdMap.set(item, item);
194
+ hashMap.set(item, item);
195
+ }
196
+ for (const item of arr) {
197
+ if (Math.random() > 0.6) {
198
+ expect(hashMap.delete(item)).toEqual(stdMap.delete(item));
199
+ }
200
+ }
201
+ compareHashMaps(hashMap, stdMap);
202
+
203
+ for (let i = 0; i < 1000; ++i) {
204
+ const random = getRandomInt(0, 100);
205
+ expect(hashMap.delete(random)).toEqual(stdMap.delete(random));
206
+ }
207
+ compareHashMaps(hashMap, stdMap);
208
+ });
209
+
210
+ test('should iterate correctly with reverse iterators', () => {
211
+ hashMap.set('key1', 'value1');
212
+ hashMap.set('key2', 'value2');
213
+ const iterator = hashMap.reverseBegin;
214
+ expect(iterator.next().current).toEqual(['key1', 'value1']);
215
+
216
+ });
217
+
218
+ test('should return the last element', () => {
219
+ hashMap.set('key1', 'value1');
220
+ hashMap.set('key2', 'value2');
221
+ expect(hashMap.back).toEqual(['key2', 'value2']);
222
+ });
223
+
224
+ test('should return undefined for empty map', () => {
225
+ expect(hashMap.back).toBeUndefined();
226
+ });
227
+
228
+ test('should get element at specific index', () => {
229
+ hashMap.set('key1', 'value1');
230
+ hashMap.set('key2', 'value2');
231
+ expect(hashMap.getAt(1)).toEqual(['key2', 'value2']);
232
+ });
233
+ })
234
+