@raikuxq/alg-ds 1.0.2 → 1.1.2
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.
- package/.idea/algorythmes.iml +15 -0
- package/.idea/codeStyles/codeStyleConfig.xml +5 -0
- package/.idea/deployment.xml +14 -0
- package/.idea/inspectionProfiles/Project_Default.xml +7 -0
- package/.idea/jsLinters/eslint.xml +6 -0
- package/.idea/misc.xml +6 -0
- package/.idea/modules.xml +8 -0
- package/.idea/vcs.xml +6 -0
- package/README.md +12 -0
- package/lib/algotirhms.ts +35 -0
- package/lib/constants.ts +3 -0
- package/lib/data-structures.ts +23 -0
- package/lib/helpers.ts +13 -0
- package/lib/sorts.ts +7 -0
- package/lib/types.ts +53 -0
- package/{src/exports → lib}/utils.ts +2 -2
- package/package.json +4 -3
- package/src/data-structures/HashTable/HashTable.ts +202 -0
- package/src/data-structures/HashTable/HashTableNode.ts +31 -0
- package/src/demo/demo.hashtable.ts +28 -0
- package/src/demo/performance/bst-compare.ts +1 -4
- package/src/demo/performance/hash-table.compare.ts +40 -0
- package/src/index.ts +44 -40
- package/src/types/IKeyValueStorage.ts +8 -0
- package/.eslintrc.js +0 -14
- package/jest.config.js +0 -4
- package/nodemon.json +0 -6
- package/src/exports/algotirhms.ts +0 -35
- package/src/exports/constants.ts +0 -3
- package/src/exports/helpers.ts +0 -13
- package/src/exports/main.ts +0 -21
- package/src/exports/sorts.ts +0 -7
- package/src/exports/types.ts +0 -53
- package/test/unit/algorithms/binary-search.test.ts +0 -25
- package/test/unit/algorithms/factorial.test.ts +0 -43
- package/test/unit/algorithms/fibonacci.test.ts +0 -41
- package/test/unit/algorithms/sorts.test.ts +0 -74
- package/test/unit/algorithms/transpose-matrix.test.ts +0 -39
- package/test/unit/data-structures/binary-tree/binary-search-tree.test.ts +0 -230
- package/test/unit/data-structures/graph/graph.create-from-matrix.test.ts +0 -106
- package/test/unit/data-structures/graph/graph.has-path.test.ts +0 -115
- package/test/unit/data-structures/graph/graph.presenter.lists.test.ts +0 -76
- package/test/unit/data-structures/graph/graph.presenter.matrix.test.ts +0 -73
- package/test/unit/data-structures/graph/graph.shortest-path.test.ts +0 -207
- package/test/unit/data-structures/graph/graph.test.ts +0 -394
- package/test/unit/data-structures/graph/graph.transpose.test.ts +0 -52
- package/test/unit/data-structures/linked-list/linked-list.test.ts +0 -477
- package/test/unit/data-structures/looped-array/looped-array.test.ts +0 -387
- package/test/unit/data-structures/queue/queue.test.ts +0 -147
- package/test/unit/data-structures/stack/stack.test.ts +0 -155
- package/tsconfig.json +0 -18
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<module type="WEB_MODULE" version="4">
|
|
3
|
+
<component name="NewModuleRootManager">
|
|
4
|
+
<content url="file://$MODULE_DIR$">
|
|
5
|
+
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
|
|
6
|
+
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
|
7
|
+
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
|
8
|
+
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
|
9
|
+
<excludeFolder url="file://$MODULE_DIR$/build/coverage" />
|
|
10
|
+
<excludeFolder url="file://$MODULE_DIR$/coverage" />
|
|
11
|
+
</content>
|
|
12
|
+
<orderEntry type="inheritedJdk" />
|
|
13
|
+
<orderEntry type="sourceFolder" forTests="false" />
|
|
14
|
+
</component>
|
|
15
|
+
</module>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<project version="4">
|
|
3
|
+
<component name="PublishConfigData">
|
|
4
|
+
<serverData>
|
|
5
|
+
<paths name="raikuhost">
|
|
6
|
+
<serverdata>
|
|
7
|
+
<mappings>
|
|
8
|
+
<mapping local="$PROJECT_DIR$" web="/" />
|
|
9
|
+
</mappings>
|
|
10
|
+
</serverdata>
|
|
11
|
+
</paths>
|
|
12
|
+
</serverData>
|
|
13
|
+
</component>
|
|
14
|
+
</project>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<component name="InspectionProjectProfileManager">
|
|
2
|
+
<profile version="1.0">
|
|
3
|
+
<option name="myName" value="Project Default" />
|
|
4
|
+
<inspection_tool class="DuplicatedCode" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
|
|
5
|
+
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
|
|
6
|
+
</profile>
|
|
7
|
+
</component>
|
package/.idea/misc.xml
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<project version="4">
|
|
3
|
+
<component name="ProjectModuleManager">
|
|
4
|
+
<modules>
|
|
5
|
+
<module fileurl="file://$PROJECT_DIR$/.idea/algorythmes.iml" filepath="$PROJECT_DIR$/.idea/algorythmes.iml" />
|
|
6
|
+
</modules>
|
|
7
|
+
</component>
|
|
8
|
+
</project>
|
package/.idea/vcs.xml
ADDED
package/README.md
CHANGED
|
@@ -30,6 +30,7 @@ Clone this repository and install dependencies by using `yarn` command.
|
|
|
30
30
|
+ [Stack](#stack)
|
|
31
31
|
+ [Queue](#queue)
|
|
32
32
|
+ [Non-linear data structures](#non-linear-data-structures)
|
|
33
|
+
+ [Hash table](#hash-table)
|
|
33
34
|
+ [Graph](#graph)
|
|
34
35
|
+ [Binary tree](#binary-trees)
|
|
35
36
|
|
|
@@ -135,6 +136,17 @@ Extends [IConvertableToArray](src/types/IConvertableToArray.ts) interface.
|
|
|
135
136
|
|
|
136
137
|
# Non linear data structures
|
|
137
138
|
|
|
139
|
+
## Hash Table
|
|
140
|
+
### Interfaces
|
|
141
|
+
[IKeyValueStorage](src/types/IKeyValueStorage.ts) — Contains basic key-value storages operations.
|
|
142
|
+
|
|
143
|
+
### Implementation
|
|
144
|
+
[HashTableNode](src/data-structures/HashTable/HashTableNode.ts) — Contains key, data and isDeleted properties.
|
|
145
|
+
|
|
146
|
+
[HashTable](src/data-structures/HashTable/HashTable.ts) [ [ tests ] ](test/unit/data-structures/hash-table/hash-table.test.ts) — Implementation of open addressing hash table using quadratic probing
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
|
|
138
150
|
## Graph
|
|
139
151
|
### Interfaces
|
|
140
152
|
[IGraph](src/types/IGraph.ts) — Contains basic graph operations.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { factorial, memoizedFactorial } from "../src/algorithms/factorial";
|
|
2
|
+
import { fibonacci, memoizedFibonacci } from "../src/algorithms/fibonacci";
|
|
3
|
+
import { binarySearch } from "../src/algorithms/binary-search";
|
|
4
|
+
import { transposeMatrix } from "../src/algorithms/transpose-matrix";
|
|
5
|
+
import { transposeDirectedGraph } from "../src/data-structures/Graph/transposing/transposeDirectedGraph";
|
|
6
|
+
import BFSIterationStrategy from "../src/data-structures/Graph/strategy/BFSIterationStrategy";
|
|
7
|
+
import DFSIterationStrategy from "../src/data-structures/Graph/strategy/DFSIterationStrategy";
|
|
8
|
+
import DijkstraIterationStrategy from "../src/data-structures/Graph/strategy/DijkstraIterationStrategy";
|
|
9
|
+
import GraphIteratorBFS from "../src/data-structures/Graph/iterator/GraphIteratorBFS";
|
|
10
|
+
import GraphIteratorDFS from "../src/data-structures/Graph/iterator/GraphIteratorDFS";
|
|
11
|
+
import GraphIteratorDijkstra from "../src/data-structures/Graph/iterator/GraphIteratorDijkstra";
|
|
12
|
+
import { hasPath } from "../src/data-structures/Graph/searching/hasPath";
|
|
13
|
+
import { shortestPath } from "../src/data-structures/Graph/searching/shortestPath";
|
|
14
|
+
import { presenterAdjacencyMatrix } from "../src/data-structures/Graph/presenter/presenterAdjacencyMatrix";
|
|
15
|
+
import { presenterAdjacencyLists } from "../src/data-structures/Graph/presenter/presenterAdjacencyLists";
|
|
16
|
+
|
|
17
|
+
export {
|
|
18
|
+
binarySearch,
|
|
19
|
+
factorial,
|
|
20
|
+
memoizedFactorial,
|
|
21
|
+
memoizedFibonacci,
|
|
22
|
+
fibonacci,
|
|
23
|
+
transposeMatrix,
|
|
24
|
+
GraphIteratorDFS,
|
|
25
|
+
presenterAdjacencyLists,
|
|
26
|
+
presenterAdjacencyMatrix,
|
|
27
|
+
hasPath,
|
|
28
|
+
shortestPath,
|
|
29
|
+
DijkstraIterationStrategy,
|
|
30
|
+
DFSIterationStrategy,
|
|
31
|
+
BFSIterationStrategy,
|
|
32
|
+
GraphIteratorBFS,
|
|
33
|
+
GraphIteratorDijkstra,
|
|
34
|
+
transposeDirectedGraph,
|
|
35
|
+
};
|
package/lib/constants.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import Queue from "../src/data-structures/Queue/Queue";
|
|
2
|
+
import Stack from "../src/data-structures/Stack/Stack";
|
|
3
|
+
import UndirectedGraph from "../src/data-structures/Graph/UndirectedGraph";
|
|
4
|
+
import DirectedGraph from "../src/data-structures/Graph/DirectedGraph";
|
|
5
|
+
import BinarySearchTree from "../src/data-structures/BinaryTree/BinarySearchTree/BinarySearchTree";
|
|
6
|
+
import RandBinarySearchTree from "../src/data-structures/BinaryTree/RandBinarySearchTree/RandBinarySearchTree";
|
|
7
|
+
import DoubleLinkedList from "../src/data-structures/LinkedList/DoubleLinkedList/DoubleLinkedList";
|
|
8
|
+
import SingleLinkedList from "../src/data-structures/LinkedList/SingleLinkedList/SingleLinkedList";
|
|
9
|
+
import LoopedArray from "../src/data-structures/LoopedArray/LoopedArray";
|
|
10
|
+
import HashTable from "../src/data-structures/HashTable/HashTable";
|
|
11
|
+
|
|
12
|
+
export {
|
|
13
|
+
Stack,
|
|
14
|
+
Queue,
|
|
15
|
+
SingleLinkedList,
|
|
16
|
+
DoubleLinkedList,
|
|
17
|
+
RandBinarySearchTree,
|
|
18
|
+
BinarySearchTree,
|
|
19
|
+
DirectedGraph,
|
|
20
|
+
UndirectedGraph,
|
|
21
|
+
LoopedArray,
|
|
22
|
+
HashTable,
|
|
23
|
+
};
|
package/lib/helpers.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { generateRandomGraph } from "../src/data-structures/Graph/demo/generateRandomGraph";
|
|
2
|
+
import { createLinkedList } from "../src/helpers/createLinkedList";
|
|
3
|
+
import { createBinaryTree } from "../src/helpers/createBinaryTree";
|
|
4
|
+
import { createGraph } from "../src/helpers/createGraph";
|
|
5
|
+
import { createGraphFromMatrix } from "../src/helpers/createGraphFromMatrix";
|
|
6
|
+
|
|
7
|
+
export {
|
|
8
|
+
createGraph,
|
|
9
|
+
createGraphFromMatrix,
|
|
10
|
+
createBinaryTree,
|
|
11
|
+
createLinkedList,
|
|
12
|
+
generateRandomGraph,
|
|
13
|
+
};
|
package/lib/sorts.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { bubbleSort } from "../src/algorithms/sorts/bubble-sort";
|
|
2
|
+
import { selectSort } from "../src/algorithms/sorts/select-sort";
|
|
3
|
+
import { mergeSort } from "../src/algorithms/sorts/merge-sort";
|
|
4
|
+
import { insertionSort } from "../src/algorithms/sorts/insertion-sort";
|
|
5
|
+
import { quickSort } from "../src/algorithms/sorts/quick-sort";
|
|
6
|
+
|
|
7
|
+
export { bubbleSort, insertionSort, mergeSort, selectSort, quickSort };
|
package/lib/types.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { ArrayMatrix } from "../src/types/ArrayMatrix";
|
|
2
|
+
import { EnumTreeTraversalType } from "../src/types/EnumTreeTraversalType";
|
|
3
|
+
import { EnumBinarySearchTreeType } from "../src/types/EnumBinarySearchTreeType";
|
|
4
|
+
import { EnumGraphTraversalType } from "../src/types/EnumGraphTraversalType";
|
|
5
|
+
import { EnumGraphType } from "../src/types/EnumGraphType";
|
|
6
|
+
import { EnumLinkedListType } from "../src/types/EnumLinkedListType";
|
|
7
|
+
import { EnumRandomGenerationFormat } from "../src/types/EnumRandomGenerationFormat";
|
|
8
|
+
import { EnumSortType } from "../src/types/EnumSortType";
|
|
9
|
+
import { FnSort } from "../src/types/FnSort";
|
|
10
|
+
import { FnCompareTwo } from "../src/types/FnCompareTwo";
|
|
11
|
+
import { FnToMemoize } from "../src/types/FnToMemoize";
|
|
12
|
+
import IArrayFacade from "../src/types/IArrayFacade";
|
|
13
|
+
import IBiDirectIterator from "../src/types/IBiDirectIterator";
|
|
14
|
+
import IBiDirectIterable from "../src/types/IBiDirectIterable";
|
|
15
|
+
import IIterable from "../src/types/IIterable";
|
|
16
|
+
import IIterator from "../src/types/IIterator";
|
|
17
|
+
import IBinaryTree from "../src/types/IBinaryTree";
|
|
18
|
+
import IConvertableToArray from "../src/types/IConvertableToArray";
|
|
19
|
+
import IGraph from "../src/types/IGraph";
|
|
20
|
+
import IGraphCreator from "../src/types/IGraphCreator";
|
|
21
|
+
import IGraphIterationStrategy from "../src/types/IGraphIterationStrategy";
|
|
22
|
+
import IGraphIterator from "../src/types/IGraphIterator";
|
|
23
|
+
import ILinearStorage from "../src/types/ILinearStorage";
|
|
24
|
+
import ILinearStorageRA from "../src/types/ILinearStorageRA";
|
|
25
|
+
import ILinkedList from "../src/types/ILinkedList";
|
|
26
|
+
|
|
27
|
+
export {
|
|
28
|
+
IGraph,
|
|
29
|
+
IGraphIterator,
|
|
30
|
+
IGraphIterationStrategy,
|
|
31
|
+
IIterator,
|
|
32
|
+
IIterable,
|
|
33
|
+
IGraphCreator,
|
|
34
|
+
IBiDirectIterable,
|
|
35
|
+
IBiDirectIterator,
|
|
36
|
+
EnumGraphType,
|
|
37
|
+
EnumSortType,
|
|
38
|
+
FnSort,
|
|
39
|
+
EnumGraphTraversalType,
|
|
40
|
+
EnumTreeTraversalType,
|
|
41
|
+
EnumBinarySearchTreeType,
|
|
42
|
+
IBinaryTree,
|
|
43
|
+
EnumLinkedListType,
|
|
44
|
+
ILinkedList,
|
|
45
|
+
ILinearStorage,
|
|
46
|
+
ILinearStorageRA,
|
|
47
|
+
IArrayFacade,
|
|
48
|
+
IConvertableToArray,
|
|
49
|
+
ArrayMatrix,
|
|
50
|
+
FnCompareTwo,
|
|
51
|
+
EnumRandomGenerationFormat,
|
|
52
|
+
FnToMemoize,
|
|
53
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { memoize } from "../algorithms/memoize";
|
|
1
|
+
import { memoize } from "../src/algorithms/memoize";
|
|
2
2
|
import {
|
|
3
3
|
getMinIndex,
|
|
4
4
|
getMinIndexFromIndex,
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
roundNumber,
|
|
8
8
|
swapArrayItems,
|
|
9
9
|
perfAsync,
|
|
10
|
-
} from "../utils";
|
|
10
|
+
} from "../src/utils";
|
|
11
11
|
|
|
12
12
|
export {
|
|
13
13
|
perf,
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"test": "jest",
|
|
5
5
|
"dev": "nodemon",
|
|
6
6
|
"build": "rimraf ./build && tsc",
|
|
7
|
-
"start": "npm run build && node build/
|
|
7
|
+
"start": "npm run build && node --experimental-specifier-resolution=node .build/index.js",
|
|
8
8
|
"lint": "yarn eslint . --ext .ts",
|
|
9
9
|
"lint:fix": "yarn eslint --fix . --ext .ts"
|
|
10
10
|
},
|
|
@@ -26,10 +26,11 @@
|
|
|
26
26
|
"prettier": "^2.1.2",
|
|
27
27
|
"rimraf": "^3.0.2",
|
|
28
28
|
"ts-jest": "^26.4.1",
|
|
29
|
-
"ts-node": "^
|
|
29
|
+
"ts-node": "^10.7.0",
|
|
30
|
+
"ts-node-esm": "^0.0.6",
|
|
30
31
|
"typescript": "^4.0.3"
|
|
31
32
|
},
|
|
32
33
|
"dependencies": {},
|
|
33
|
-
"version": "1.
|
|
34
|
+
"version": "1.1.2",
|
|
34
35
|
"type": "module"
|
|
35
36
|
}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import IKeyValueStorage from "../../types/IKeyValueStorage";
|
|
2
|
+
import HashTableNode from "./HashTableNode";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Implementation of open addressing hash table using quadratic probing
|
|
6
|
+
*/
|
|
7
|
+
export default class HashTable<T> implements IKeyValueStorage<T> {
|
|
8
|
+
/**
|
|
9
|
+
Constants
|
|
10
|
+
*/
|
|
11
|
+
private static DEFAULT_MAX_CAPACITY = 100;
|
|
12
|
+
private static MAX_LOAD_FACTOR = 0.5;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* State
|
|
16
|
+
*/
|
|
17
|
+
private storage: Array<HashTableNode<T>>;
|
|
18
|
+
private maxCapacity: number;
|
|
19
|
+
private storageCapacity = 0;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Given init capacity size will be used
|
|
23
|
+
* @throws when initial capacity value is not larger than 0
|
|
24
|
+
*/
|
|
25
|
+
public constructor(initialCapacity: number = HashTable.DEFAULT_MAX_CAPACITY) {
|
|
26
|
+
if (initialCapacity <= 0) {
|
|
27
|
+
throw new Error("Size must be larger than 0");
|
|
28
|
+
}
|
|
29
|
+
this.maxCapacity = initialCapacity;
|
|
30
|
+
this.storage = new Array(this.maxCapacity).fill(null);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Main-hash function
|
|
35
|
+
*/
|
|
36
|
+
private hashFn(key: string, number: number): number {
|
|
37
|
+
return (
|
|
38
|
+
(this.innerHashFn(key) + 127 * number + 365 * number * number) %
|
|
39
|
+
this.maxCapacity
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Helper-hash function
|
|
45
|
+
*/
|
|
46
|
+
private innerHashFn(key: string): number {
|
|
47
|
+
const length: number = key.length;
|
|
48
|
+
|
|
49
|
+
if (length === 0) {
|
|
50
|
+
return 0;
|
|
51
|
+
}
|
|
52
|
+
const substring = key.substring(0, length - 1);
|
|
53
|
+
const symbol = key.charCodeAt(length - 1);
|
|
54
|
+
|
|
55
|
+
return (127 * this.innerHashFn(substring) + symbol) % this.maxCapacity;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Max capacity will be increased and storage will be overwritten
|
|
60
|
+
*/
|
|
61
|
+
private resizeStorage(): Array<HashTableNode<T>> {
|
|
62
|
+
this.maxCapacity *= 2;
|
|
63
|
+
|
|
64
|
+
const newArray = new Array(this.maxCapacity).fill(null);
|
|
65
|
+
|
|
66
|
+
for (let i = 0; i < this.storage.length; i++) {
|
|
67
|
+
const element = this.storage[i];
|
|
68
|
+
|
|
69
|
+
if (element != null) {
|
|
70
|
+
for (let j = 0; j < this.maxCapacity; j++) {
|
|
71
|
+
const newIndex = this.hashFn(element.key, j);
|
|
72
|
+
|
|
73
|
+
if (newArray[newIndex] == null) {
|
|
74
|
+
newArray[newIndex] = element;
|
|
75
|
+
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return newArray;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Will find node instance by its key
|
|
87
|
+
* @throws when element does not exist
|
|
88
|
+
*/
|
|
89
|
+
private findNode(key: string): HashTableNode<T> {
|
|
90
|
+
for (let i = 0; i < this.maxCapacity; i++) {
|
|
91
|
+
const index = this.hashFn(key, i);
|
|
92
|
+
const node = this.storage[index];
|
|
93
|
+
|
|
94
|
+
if (node?.key === key) {
|
|
95
|
+
if (node?.isDeleted) {
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
return node;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
throw new Error("Element does not exist");
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Will create new node instance and set in to storage by index
|
|
107
|
+
*/
|
|
108
|
+
private addNode(key: string, data: T, index: number): void {
|
|
109
|
+
this.storage[index] = new HashTableNode<T>(key, data);
|
|
110
|
+
|
|
111
|
+
this.storageCapacity++;
|
|
112
|
+
const loadFactor = this.storageCapacity / this.maxCapacity;
|
|
113
|
+
|
|
114
|
+
if (loadFactor >= HashTable.MAX_LOAD_FACTOR) {
|
|
115
|
+
this.storage = this.resizeStorage();
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Will create new node instance and set in to storage by index
|
|
121
|
+
*/
|
|
122
|
+
private updateNode(data: T, index: number): void {
|
|
123
|
+
this.storage[index].data = data;
|
|
124
|
+
this.storage[index].isDeleted = false;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Will insert item to hash table
|
|
129
|
+
*/
|
|
130
|
+
public set(key: string, data: T): void {
|
|
131
|
+
for (let i = 0; i < this.maxCapacity; i++) {
|
|
132
|
+
const index = this.hashFn(key, i);
|
|
133
|
+
const node = this.storage[index];
|
|
134
|
+
|
|
135
|
+
const shouldAddNode = node === null;
|
|
136
|
+
if (shouldAddNode) {
|
|
137
|
+
this.addNode(key, data, index);
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const shouldUpdateNode = node.key === key;
|
|
142
|
+
if (shouldUpdateNode) {
|
|
143
|
+
this.updateNode(data, index);
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Will update item property isDeleted to false
|
|
151
|
+
* @throws when element does not exist
|
|
152
|
+
*/
|
|
153
|
+
public delete(key: string): void {
|
|
154
|
+
for (let i = 0; i < this.maxCapacity; i++) {
|
|
155
|
+
const index = this.hashFn(key, i);
|
|
156
|
+
|
|
157
|
+
if (this.storage[index] !== null) {
|
|
158
|
+
this.storage[index].isDeleted = true;
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
throw new Error("Element does not exist");
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Will find item in hash table
|
|
168
|
+
* @throws when element does not exist
|
|
169
|
+
*/
|
|
170
|
+
public get(key: string): T {
|
|
171
|
+
return this.findNode(key).data;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Check if node with given key exists
|
|
176
|
+
*/
|
|
177
|
+
public has(key: string): boolean {
|
|
178
|
+
try {
|
|
179
|
+
return Boolean(this.findNode(key));
|
|
180
|
+
} catch (e) {
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Added elements count
|
|
187
|
+
*/
|
|
188
|
+
public length(): number {
|
|
189
|
+
const actualItems = this.storage.filter((item) => {
|
|
190
|
+
return item !== null && !item.isDeleted;
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
return actualItems.length;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Will overwrite storage with array of null elements
|
|
198
|
+
*/
|
|
199
|
+
public clear(): void {
|
|
200
|
+
this.storage = new Array(HashTable.DEFAULT_MAX_CAPACITY).fill(null);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export default class HashTableNode<T> {
|
|
2
|
+
private readonly _key: string;
|
|
3
|
+
private _data: T;
|
|
4
|
+
private _isDeleted: boolean;
|
|
5
|
+
|
|
6
|
+
public constructor(key: string, data: T) {
|
|
7
|
+
this._key = key;
|
|
8
|
+
this._data = data;
|
|
9
|
+
this._isDeleted = false;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
get data(): T {
|
|
13
|
+
return this._data;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
set data(value: T) {
|
|
17
|
+
this._data = value;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
get key(): string {
|
|
21
|
+
return this._key;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
get isDeleted(): boolean {
|
|
25
|
+
return this._isDeleted;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
set isDeleted(value: boolean) {
|
|
29
|
+
this._isDeleted = value;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import HashTable from "../data-structures/HashTable/HashTable";
|
|
2
|
+
|
|
3
|
+
export const demoHashtable = (): void => {
|
|
4
|
+
const hashTable = new HashTable<number>(15);
|
|
5
|
+
|
|
6
|
+
// emulate 66% load
|
|
7
|
+
for (let i = 0; i < 10; i++) {
|
|
8
|
+
hashTable.set(`key${i * 2}`, i * 2);
|
|
9
|
+
}
|
|
10
|
+
console.log(hashTable);
|
|
11
|
+
|
|
12
|
+
for (let i = 10; i < 15; i++) {
|
|
13
|
+
hashTable.set(`key${i * 2}`, i * 2);
|
|
14
|
+
}
|
|
15
|
+
console.log(hashTable);
|
|
16
|
+
console.log("\n length:", hashTable.length());
|
|
17
|
+
|
|
18
|
+
hashTable.set("key4", 10000);
|
|
19
|
+
console.log("\n", hashTable.get("key4"));
|
|
20
|
+
hashTable.delete("key4");
|
|
21
|
+
console.log("\n has key4:", hashTable.has("key4"));
|
|
22
|
+
hashTable.set("key4", 20000);
|
|
23
|
+
console.log("\n has key4:", hashTable.has("key4"));
|
|
24
|
+
console.log("\n key4 value:", hashTable.get("key4"));
|
|
25
|
+
console.log("\n", hashTable);
|
|
26
|
+
hashTable.clear();
|
|
27
|
+
console.log("\n", hashTable);
|
|
28
|
+
};
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import RandBinarySearchTree from "../../data-structures/BinaryTree/RandBinarySearchTree/RandBinarySearchTree";
|
|
2
2
|
import BinarySearchTree from "../../data-structures/BinaryTree/BinarySearchTree/BinarySearchTree";
|
|
3
|
-
import { EnumTreeTraversalType } from "../../types/EnumTreeTraversalType";
|
|
4
3
|
import IBinaryTree from "../../types/IBinaryTree";
|
|
5
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
6
|
-
const util = require("util");
|
|
7
4
|
|
|
8
5
|
const logTree = <T>(tree: IBinaryTree<T>) => {
|
|
9
6
|
console.log("HEIGHT");
|
|
@@ -22,7 +19,7 @@ export const bstCompare = (): void => {
|
|
|
22
19
|
|
|
23
20
|
const arraySrc = Array.from(Array(1000).keys());
|
|
24
21
|
|
|
25
|
-
arraySrc.forEach((num
|
|
22
|
+
arraySrc.forEach((num) => {
|
|
26
23
|
bstLeaf.insert(num);
|
|
27
24
|
bstRand.insert(num);
|
|
28
25
|
});
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { perf, roundNumber } from "../../utils";
|
|
2
|
+
import IKeyValueStorage from "../../types/IKeyValueStorage";
|
|
3
|
+
import HashTable from "../../data-structures/HashTable/HashTable";
|
|
4
|
+
|
|
5
|
+
export const pushToStorage = (
|
|
6
|
+
linearDS: IKeyValueStorage<number>,
|
|
7
|
+
elementsCount: number
|
|
8
|
+
): void => {
|
|
9
|
+
for (let i = 0; i < elementsCount; i++) {
|
|
10
|
+
linearDS.set(`key${i}`, i);
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const perfHashTable = (): void => {
|
|
15
|
+
console.log(`HASHTABLE PERFORMANCE TEST:`);
|
|
16
|
+
const hashTable: IKeyValueStorage<number> = new HashTable<number>();
|
|
17
|
+
let elementsCount = 50;
|
|
18
|
+
|
|
19
|
+
while (elementsCount <= 5000000) {
|
|
20
|
+
pushToStorage(hashTable, elementsCount);
|
|
21
|
+
|
|
22
|
+
const perfSet = perf(() => {
|
|
23
|
+
hashTable.set(`key${elementsCount}`, elementsCount);
|
|
24
|
+
});
|
|
25
|
+
const perfGet = perf(() => {
|
|
26
|
+
hashTable.get(`key${elementsCount}`);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const perfHas = perf(() => {
|
|
30
|
+
hashTable.has(`key${elementsCount - 10}`);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
console.log(`N: ${elementsCount} set: ${roundNumber(perfSet)}ms`);
|
|
34
|
+
console.log(`N: ${elementsCount} get: ${roundNumber(perfGet)}ms`);
|
|
35
|
+
console.log(`N: ${elementsCount} has: ${roundNumber(perfHas)}ms`);
|
|
36
|
+
console.log("=========================");
|
|
37
|
+
|
|
38
|
+
elementsCount *= 10;
|
|
39
|
+
}
|
|
40
|
+
};
|