@gabrielrufino/cube 1.0.1
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/.github/workflows/cd.yml +26 -0
- package/.github/workflows/ci.yml +23 -0
- package/LICENSE +24 -0
- package/README.md +1695 -0
- package/build/Algorithms/index.d.ts +3 -0
- package/build/Algorithms/index.js +24 -0
- package/build/Array/IArray.d.ts +9 -0
- package/build/Array/IArray.js +2 -0
- package/build/Array/index.d.ts +12 -0
- package/build/Array/index.js +79 -0
- package/build/BinarySearchTree/BinarySearchTreeNode.d.ts +7 -0
- package/build/BinarySearchTree/BinarySearchTreeNode.js +22 -0
- package/build/BinarySearchTree/IBinarySearchNodeOptions.d.ts +5 -0
- package/build/BinarySearchTree/IBinarySearchNodeOptions.js +2 -0
- package/build/BinarySearchTree/IBinarySearchTree.d.ts +14 -0
- package/build/BinarySearchTree/IBinarySearchTree.js +2 -0
- package/build/BinarySearchTree/IBinarySearchTreeData.d.ts +7 -0
- package/build/BinarySearchTree/IBinarySearchTreeData.js +2 -0
- package/build/BinarySearchTree/index.d.ts +24 -0
- package/build/BinarySearchTree/index.js +199 -0
- package/build/DataStructure/index.d.ts +6 -0
- package/build/DataStructure/index.js +32 -0
- package/build/Deck/IDeck.d.ts +9 -0
- package/build/Deck/IDeck.js +2 -0
- package/build/Deck/index.d.ts +12 -0
- package/build/Deck/index.js +76 -0
- package/build/Dictionary/IDictionary.d.ts +16 -0
- package/build/Dictionary/IDictionary.js +2 -0
- package/build/Dictionary/IDictionaryData.d.ts +4 -0
- package/build/Dictionary/IDictionaryData.js +2 -0
- package/build/Dictionary/index.d.ts +21 -0
- package/build/Dictionary/index.js +110 -0
- package/build/DoublyLinkedList/IDoublyLinkedList.d.ts +16 -0
- package/build/DoublyLinkedList/IDoublyLinkedList.js +2 -0
- package/build/DoublyLinkedList/Node.d.ts +6 -0
- package/build/DoublyLinkedList/Node.js +11 -0
- package/build/DoublyLinkedList/index.d.ts +32 -0
- package/build/DoublyLinkedList/index.js +221 -0
- package/build/Graph/GraphNodeNotFoundError.d.ts +3 -0
- package/build/Graph/GraphNodeNotFoundError.js +27 -0
- package/build/Graph/GraphSearchNodeStates.d.ts +6 -0
- package/build/Graph/GraphSearchNodeStates.js +10 -0
- package/build/Graph/IGraph.d.ts +16 -0
- package/build/Graph/IGraph.js +2 -0
- package/build/Graph/IGraphOptions.d.ts +7 -0
- package/build/Graph/IGraphOptions.js +2 -0
- package/build/Graph/index.d.ts +20 -0
- package/build/Graph/index.js +187 -0
- package/build/HashTable/IHashTable.d.ts +9 -0
- package/build/HashTable/IHashTable.js +2 -0
- package/build/HashTable/IHashTableData.d.ts +4 -0
- package/build/HashTable/IHashTableData.js +2 -0
- package/build/HashTable/IHashTableInputs.d.ts +4 -0
- package/build/HashTable/IHashTableInputs.js +2 -0
- package/build/HashTable/IHashTableOptions.d.ts +4 -0
- package/build/HashTable/IHashTableOptions.js +2 -0
- package/build/HashTable/index.d.ts +16 -0
- package/build/HashTable/index.js +83 -0
- package/build/HashTableLinearProbing/HashTableLinearProbingElement.d.ts +6 -0
- package/build/HashTableLinearProbing/HashTableLinearProbingElement.js +19 -0
- package/build/HashTableLinearProbing/IHashTableLinearProbing.d.ts +9 -0
- package/build/HashTableLinearProbing/IHashTableLinearProbing.js +2 -0
- package/build/HashTableLinearProbing/IHashTableLinearProbingData.d.ts +5 -0
- package/build/HashTableLinearProbing/IHashTableLinearProbingData.js +2 -0
- package/build/HashTableLinearProbing/IHashTableLinearProbingInputs.d.ts +4 -0
- package/build/HashTableLinearProbing/IHashTableLinearProbingInputs.js +2 -0
- package/build/HashTableLinearProbing/IHashTableLinearProbingOptions.d.ts +4 -0
- package/build/HashTableLinearProbing/IHashTableLinearProbingOptions.js +2 -0
- package/build/HashTableLinearProbing/index.d.ts +20 -0
- package/build/HashTableLinearProbing/index.js +120 -0
- package/build/HashTableSeparateChaining/HashTableSeparateChainingElement.d.ts +6 -0
- package/build/HashTableSeparateChaining/HashTableSeparateChainingElement.js +21 -0
- package/build/HashTableSeparateChaining/IHashTableSeparateChaining.d.ts +10 -0
- package/build/HashTableSeparateChaining/IHashTableSeparateChaining.js +2 -0
- package/build/HashTableSeparateChaining/IHashTableSeparateChainingData.d.ts +5 -0
- package/build/HashTableSeparateChaining/IHashTableSeparateChainingData.js +2 -0
- package/build/HashTableSeparateChaining/IHashTableSeparateChainingInputs.d.ts +4 -0
- package/build/HashTableSeparateChaining/IHashTableSeparateChainingInputs.js +2 -0
- package/build/HashTableSeparateChaining/IHashTableSeparateChainingOptions.d.ts +4 -0
- package/build/HashTableSeparateChaining/IHashTableSeparateChainingOptions.js +2 -0
- package/build/HashTableSeparateChaining/index.d.ts +19 -0
- package/build/HashTableSeparateChaining/index.js +104 -0
- package/build/LinkedList/ILinkedList.d.ts +13 -0
- package/build/LinkedList/ILinkedList.js +2 -0
- package/build/LinkedList/ILinkedListItem.d.ts +5 -0
- package/build/LinkedList/ILinkedListItem.js +2 -0
- package/build/LinkedList/Node.d.ts +5 -0
- package/build/LinkedList/Node.js +10 -0
- package/build/LinkedList/index.d.ts +24 -0
- package/build/LinkedList/index.js +169 -0
- package/build/List/index.d.ts +1 -0
- package/build/List/index.js +8 -0
- package/build/MaxHeap/IMaxHeap.d.ts +9 -0
- package/build/MaxHeap/IMaxHeap.js +2 -0
- package/build/MaxHeap/IMaxHeapOptions.d.ts +5 -0
- package/build/MaxHeap/IMaxHeapOptions.js +2 -0
- package/build/MaxHeap/index.d.ts +19 -0
- package/build/MaxHeap/index.js +102 -0
- package/build/MinHeap/IMinHeap.d.ts +9 -0
- package/build/MinHeap/IMinHeap.js +2 -0
- package/build/MinHeap/IMinHeapOptions.d.ts +5 -0
- package/build/MinHeap/IMinHeapOptions.js +2 -0
- package/build/MinHeap/index.d.ts +19 -0
- package/build/MinHeap/index.js +102 -0
- package/build/Queue/IQueue.d.ts +8 -0
- package/build/Queue/IQueue.js +2 -0
- package/build/Queue/index.d.ts +11 -0
- package/build/Queue/index.js +74 -0
- package/build/Set/ISet.d.ts +15 -0
- package/build/Set/ISet.js +2 -0
- package/build/Set/index.d.ts +21 -0
- package/build/Set/index.js +132 -0
- package/build/Stack/IStack.d.ts +8 -0
- package/build/Stack/IStack.js +2 -0
- package/build/Stack/index.d.ts +11 -0
- package/build/Stack/index.js +64 -0
- package/build/index.d.ts +17 -0
- package/build/index.js +40 -0
- package/coverage/clover.xml +706 -0
- package/coverage/coverage-final.json +19 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +327 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +196 -0
- package/coverage/lcov-report/src/Algorithms/index.html +117 -0
- package/coverage/lcov-report/src/Algorithms/index.ts.html +149 -0
- package/coverage/lcov-report/src/Array/index.html +117 -0
- package/coverage/lcov-report/src/Array/index.ts.html +290 -0
- package/coverage/lcov-report/src/DataStructure/index.html +117 -0
- package/coverage/lcov-report/src/DataStructure/index.ts.html +131 -0
- package/coverage/lcov-report/src/Deck/index.html +117 -0
- package/coverage/lcov-report/src/Deck/index.ts.html +239 -0
- package/coverage/lcov-report/src/Dictionary/index.html +117 -0
- package/coverage/lcov-report/src/Dictionary/index.ts.html +350 -0
- package/coverage/lcov-report/src/DoublyLinkedList/Node.ts.html +113 -0
- package/coverage/lcov-report/src/DoublyLinkedList/index.html +132 -0
- package/coverage/lcov-report/src/DoublyLinkedList/index.ts.html +836 -0
- package/coverage/lcov-report/src/HashTable/index.html +117 -0
- package/coverage/lcov-report/src/HashTable/index.ts.html +320 -0
- package/coverage/lcov-report/src/HashTableLinearProbing/index.html +117 -0
- package/coverage/lcov-report/src/HashTableLinearProbing/index.ts.html +95 -0
- package/coverage/lcov-report/src/HashTableSeparateChaining/HashTableSeparateChainingElement.ts.html +149 -0
- package/coverage/lcov-report/src/HashTableSeparateChaining/index.html +132 -0
- package/coverage/lcov-report/src/HashTableSeparateChaining/index.ts.html +398 -0
- package/coverage/lcov-report/src/LinkedList/Node.ts.html +110 -0
- package/coverage/lcov-report/src/LinkedList/index.html +132 -0
- package/coverage/lcov-report/src/LinkedList/index.ts.html +641 -0
- package/coverage/lcov-report/src/List/index.html +117 -0
- package/coverage/lcov-report/src/List/index.ts.html +89 -0
- package/coverage/lcov-report/src/Queue/index.html +117 -0
- package/coverage/lcov-report/src/Queue/index.ts.html +218 -0
- package/coverage/lcov-report/src/Set/index.html +117 -0
- package/coverage/lcov-report/src/Set/index.ts.html +488 -0
- package/coverage/lcov-report/src/Stack/index.html +117 -0
- package/coverage/lcov-report/src/Stack/index.ts.html +215 -0
- package/coverage/lcov-report/src/index.html +117 -0
- package/coverage/lcov-report/src/index.ts.html +125 -0
- package/coverage/lcov.info +1346 -0
- package/package.json +42 -0
- package/src/Algorithms/index.spec.ts +15 -0
- package/src/Algorithms/index.ts +21 -0
- package/src/Array/IArray.ts +10 -0
- package/src/Array/index.spec.ts +151 -0
- package/src/Array/index.ts +68 -0
- package/src/BinarySearchTree/BinarySearchTreeNode.spec.ts +29 -0
- package/src/BinarySearchTree/BinarySearchTreeNode.ts +23 -0
- package/src/BinarySearchTree/IBinarySearchNodeOptions.ts +6 -0
- package/src/BinarySearchTree/IBinarySearchTree.ts +16 -0
- package/src/BinarySearchTree/IBinarySearchTreeData.ts +9 -0
- package/src/BinarySearchTree/index.spec.ts +486 -0
- package/src/BinarySearchTree/index.ts +198 -0
- package/src/DataStructure/index.spec.ts +25 -0
- package/src/DataStructure/index.ts +15 -0
- package/src/Deck/IDeck.ts +10 -0
- package/src/Deck/index.spec.ts +131 -0
- package/src/Deck/index.ts +51 -0
- package/src/Dictionary/IDictionary.ts +18 -0
- package/src/Dictionary/IDictionaryData.ts +5 -0
- package/src/Dictionary/index.spec.ts +310 -0
- package/src/Dictionary/index.ts +88 -0
- package/src/DoublyLinkedList/IDoublyLinkedList.ts +18 -0
- package/src/DoublyLinkedList/Node.ts +9 -0
- package/src/DoublyLinkedList/index.spec.ts +478 -0
- package/src/DoublyLinkedList/index.ts +250 -0
- package/src/Graph/GraphNodeNotFoundError.ts +7 -0
- package/src/Graph/GraphSearchNodeStates.ts +8 -0
- package/src/Graph/IGraph.ts +15 -0
- package/src/Graph/IGraphOptions.ts +6 -0
- package/src/Graph/index.spec.ts +318 -0
- package/src/Graph/index.ts +170 -0
- package/src/HashTable/IHashTable.ts +11 -0
- package/src/HashTable/IHashTableData.ts +5 -0
- package/src/HashTable/IHashTableInputs.ts +5 -0
- package/src/HashTable/IHashTableOptions.ts +5 -0
- package/src/HashTable/index.spec.ts +136 -0
- package/src/HashTable/index.ts +78 -0
- package/src/HashTableLinearProbing/HashTableLinearProbingElement.spec.ts +28 -0
- package/src/HashTableLinearProbing/HashTableLinearProbingElement.ts +18 -0
- package/src/HashTableLinearProbing/IHashTableLinearProbing.ts +11 -0
- package/src/HashTableLinearProbing/IHashTableLinearProbingData.ts +7 -0
- package/src/HashTableLinearProbing/IHashTableLinearProbingInputs.ts +5 -0
- package/src/HashTableLinearProbing/IHashTableLinearProbingOptions.ts +5 -0
- package/src/HashTableLinearProbing/index.spec.ts +266 -0
- package/src/HashTableLinearProbing/index.ts +128 -0
- package/src/HashTableSeparateChaining/HashTableSeparateChainingElement.ts +21 -0
- package/src/HashTableSeparateChaining/IHashTableSeparateChaining.ts +12 -0
- package/src/HashTableSeparateChaining/IHashTableSeparateChainingData.ts +7 -0
- package/src/HashTableSeparateChaining/IHashTableSeparateChainingInputs.ts +5 -0
- package/src/HashTableSeparateChaining/IHashTableSeparateChainingOptions.ts +5 -0
- package/src/HashTableSeparateChaining/index.spec.ts +173 -0
- package/src/HashTableSeparateChaining/index.ts +104 -0
- package/src/LinkedList/ILinkedList.ts +15 -0
- package/src/LinkedList/ILinkedListItem.ts +6 -0
- package/src/LinkedList/Node.ts +8 -0
- package/src/LinkedList/index.spec.ts +355 -0
- package/src/LinkedList/index.ts +185 -0
- package/src/List/index.ts +1 -0
- package/src/MaxHeap/IMaxHeap.ts +10 -0
- package/src/MaxHeap/IMaxHeapOptions.ts +6 -0
- package/src/MaxHeap/index.spec.ts +161 -0
- package/src/MaxHeap/index.ts +91 -0
- package/src/MinHeap/IMinHeap.ts +10 -0
- package/src/MinHeap/IMinHeapOptions.ts +6 -0
- package/src/MinHeap/index.spec.ts +161 -0
- package/src/MinHeap/index.ts +91 -0
- package/src/Queue/IQueue.ts +9 -0
- package/src/Queue/index.spec.ts +92 -0
- package/src/Queue/index.ts +44 -0
- package/src/Set/ISet.ts +17 -0
- package/src/Set/index.spec.ts +246 -0
- package/src/Set/index.ts +134 -0
- package/src/Stack/IStack.ts +9 -0
- package/src/Stack/index.spec.ts +108 -0
- package/src/Stack/index.ts +43 -0
- package/src/index.ts +17 -0
- package/tsconfig.json +104 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import IHashTable from './IHashTable';
|
|
2
|
+
import IHashTableData from './IHashTableData';
|
|
3
|
+
import IHashTableInputs from './IHashTableInputs';
|
|
4
|
+
import IHashTableOptions from './IHashTableOptions';
|
|
5
|
+
|
|
6
|
+
export default class HashTable<T = number> implements IHashTable<T> {
|
|
7
|
+
private _maxSize: number;
|
|
8
|
+
private _data: T[];
|
|
9
|
+
|
|
10
|
+
constructor(
|
|
11
|
+
inputs: IHashTableInputs<T> = {},
|
|
12
|
+
{maxSize = 100}: IHashTableOptions = {maxSize: 100},
|
|
13
|
+
) {
|
|
14
|
+
this._maxSize = maxSize;
|
|
15
|
+
this._data = new Array(this._maxSize);
|
|
16
|
+
|
|
17
|
+
for (const [key, value] of Object.entries(inputs)) {
|
|
18
|
+
this.put(key, value);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
get data(): IHashTableData<T> {
|
|
23
|
+
return this._data
|
|
24
|
+
.map((value, index) => ({index, value}))
|
|
25
|
+
.reduce((accumulator, current) => ({
|
|
26
|
+
...accumulator,
|
|
27
|
+
[current.index]: current.value,
|
|
28
|
+
}), {});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
get size(): number {
|
|
32
|
+
return Reflect.ownKeys(this.data).length;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
public put(key: string, value: T): T {
|
|
36
|
+
const position = this._hashCode(key);
|
|
37
|
+
this._data[position] = value;
|
|
38
|
+
return value;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
public get(key: string): T | null {
|
|
42
|
+
const position = this._hashCode(key);
|
|
43
|
+
return this.data[position] || null;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
public remove(key: string): T | null {
|
|
47
|
+
const value = this.get(key);
|
|
48
|
+
|
|
49
|
+
if (value) {
|
|
50
|
+
const position = this._hashCode(key);
|
|
51
|
+
Reflect.deleteProperty(this._data, position);
|
|
52
|
+
return value;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
private _hashCode(key: string): number {
|
|
59
|
+
const code = key
|
|
60
|
+
.split('')
|
|
61
|
+
.map(character => character.charCodeAt(0))
|
|
62
|
+
.reduce((previous, current) => previous + current, 0);
|
|
63
|
+
|
|
64
|
+
return code % this._maxSize;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
private [Symbol.toPrimitive](type: string): string | number | null {
|
|
68
|
+
if (type === 'string') {
|
|
69
|
+
return `[ ${Object.entries(this.data).map(([key, value]) => `${key} => ${value}`).join(', ')} ]`;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (type === 'number') {
|
|
73
|
+
return this.size;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import {describe, it, expect} from '@jest/globals';
|
|
2
|
+
|
|
3
|
+
import HashTableLinearProbingElement from './HashTableLinearProbingElement';
|
|
4
|
+
|
|
5
|
+
describe('HashTableLinearProbingElement', () => {
|
|
6
|
+
it('Should create a hash table linear probing element without problems', () => {
|
|
7
|
+
const hashTableLinearProbingElement = new HashTableLinearProbingElement('key', 10);
|
|
8
|
+
|
|
9
|
+
expect(hashTableLinearProbingElement.key).toBe('key');
|
|
10
|
+
expect(hashTableLinearProbingElement.value).toBe(10);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
describe('Conversion to primitive', () => {
|
|
14
|
+
it('Should return the key value pair separated by arrow in string conversion', () => {
|
|
15
|
+
const hashTableLinearProbingElement = new HashTableLinearProbingElement('key', 'value');
|
|
16
|
+
const string = String(hashTableLinearProbingElement);
|
|
17
|
+
|
|
18
|
+
expect(string).toBe('{ key => value }');
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('Should return the number 2 in number conversion', () => {
|
|
22
|
+
const hashTableLinearProbingElement = new HashTableLinearProbingElement('key', 'value');
|
|
23
|
+
const number = Number(hashTableLinearProbingElement);
|
|
24
|
+
|
|
25
|
+
expect(number).toBe(2);
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/* eslint-disable no-unused-vars */
|
|
2
|
+
/* eslint-disable no-useless-constructor */
|
|
3
|
+
|
|
4
|
+
export default class HashTableLinearProbingElement<T> {
|
|
5
|
+
constructor(
|
|
6
|
+
public key: string,
|
|
7
|
+
public value: T,
|
|
8
|
+
) {}
|
|
9
|
+
|
|
10
|
+
[Symbol.toPrimitive](type: 'string' | 'number'): string | number | null {
|
|
11
|
+
const options = {
|
|
12
|
+
string: `{ ${this.key} => ${this.value} }`,
|
|
13
|
+
number: 2,
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
return options[type] || null;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import IHashTableLinearProbingData from './IHashTableLinearProbingData';
|
|
2
|
+
|
|
3
|
+
interface IHashTableLinearProbing<T> {
|
|
4
|
+
get data(): IHashTableLinearProbingData<T>;
|
|
5
|
+
get size(): number;
|
|
6
|
+
put(_key: string, _value: T): T | null;
|
|
7
|
+
get(_key: string): T | null;
|
|
8
|
+
remove(_key: string): T | null;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export default IHashTableLinearProbing;
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import {describe, it, expect} from '@jest/globals';
|
|
2
|
+
|
|
3
|
+
import HashTableLinearProbing from './';
|
|
4
|
+
import HashTableLinearProbingElement from './HashTableLinearProbingElement';
|
|
5
|
+
|
|
6
|
+
describe('HashTableLinearProbing', () => {
|
|
7
|
+
it('Should create an empty hash table linear probing without problems', () => {
|
|
8
|
+
const hashTableLinearProbing = new HashTableLinearProbing();
|
|
9
|
+
|
|
10
|
+
expect(hashTableLinearProbing.data).toEqual({});
|
|
11
|
+
expect(hashTableLinearProbing.size).toBe(0);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it('Should create a filled hash table linear probing without problems', () => {
|
|
15
|
+
const hashTableLinearProbing = new HashTableLinearProbing({
|
|
16
|
+
first: 1,
|
|
17
|
+
second: 2,
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
expect(hashTableLinearProbing.data).toEqual({
|
|
21
|
+
36: new HashTableLinearProbingElement('second', 2),
|
|
22
|
+
52: new HashTableLinearProbingElement('first', 1),
|
|
23
|
+
});
|
|
24
|
+
expect(hashTableLinearProbing.size).toBe(2);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
describe('.put()', () => {
|
|
28
|
+
it('Should insert a new element', () => {
|
|
29
|
+
const hashTableLinearProbing = new HashTableLinearProbing({
|
|
30
|
+
first: 1,
|
|
31
|
+
});
|
|
32
|
+
hashTableLinearProbing.put('second', 2);
|
|
33
|
+
|
|
34
|
+
expect(hashTableLinearProbing.data).toEqual({
|
|
35
|
+
36: new HashTableLinearProbingElement('second', 2),
|
|
36
|
+
52: new HashTableLinearProbingElement('first', 1),
|
|
37
|
+
});
|
|
38
|
+
expect(hashTableLinearProbing.size).toBe(2);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('Should return the inserted element', () => {
|
|
42
|
+
const hashTableLinearProbing = new HashTableLinearProbing({
|
|
43
|
+
first: 1,
|
|
44
|
+
});
|
|
45
|
+
const returned = hashTableLinearProbing.put('second', 2);
|
|
46
|
+
|
|
47
|
+
expect(returned).toBe(2);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('Should change nothing when the hash table linear probing is full', () => {
|
|
51
|
+
const hashTableLinearProbing = new HashTableLinearProbing({
|
|
52
|
+
first: 1,
|
|
53
|
+
second: 2,
|
|
54
|
+
}, {
|
|
55
|
+
maxSize: 2,
|
|
56
|
+
});
|
|
57
|
+
hashTableLinearProbing.put('third', 3);
|
|
58
|
+
|
|
59
|
+
expect(hashTableLinearProbing.data).toEqual({
|
|
60
|
+
0: new HashTableLinearProbingElement('first', 1),
|
|
61
|
+
1: new HashTableLinearProbingElement('second', 2),
|
|
62
|
+
});
|
|
63
|
+
expect(hashTableLinearProbing.size).toBe(2);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('Should return null when the hash table linear probing is full', () => {
|
|
67
|
+
const hashTableLinearProbing = new HashTableLinearProbing({
|
|
68
|
+
first: 1,
|
|
69
|
+
second: 2,
|
|
70
|
+
}, {
|
|
71
|
+
maxSize: 2,
|
|
72
|
+
});
|
|
73
|
+
const returned = hashTableLinearProbing.put('third', 3);
|
|
74
|
+
|
|
75
|
+
expect(returned).toBeNull();
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('Should put the new element in the next available position in collision case', () => {
|
|
79
|
+
const hashTableLinearProbing = new HashTableLinearProbing({
|
|
80
|
+
first: 1,
|
|
81
|
+
});
|
|
82
|
+
hashTableLinearProbing.put('tsrif', -1);
|
|
83
|
+
|
|
84
|
+
expect(hashTableLinearProbing.data).toEqual({
|
|
85
|
+
52: new HashTableLinearProbingElement('first', 1),
|
|
86
|
+
53: new HashTableLinearProbingElement('tsrif', -1),
|
|
87
|
+
});
|
|
88
|
+
expect(hashTableLinearProbing.size).toBe(2);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
describe('.get()', () => {
|
|
93
|
+
it('Should return the value of the key', () => {
|
|
94
|
+
const hashTableLinearProbing = new HashTableLinearProbing({
|
|
95
|
+
first: 1,
|
|
96
|
+
second: 2,
|
|
97
|
+
});
|
|
98
|
+
const returned = hashTableLinearProbing.get('second');
|
|
99
|
+
|
|
100
|
+
expect(returned).toBe(2);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it('Should return the correct value in case of collisions', () => {
|
|
104
|
+
const hashTableLinearProbing = new HashTableLinearProbing({
|
|
105
|
+
first: 1,
|
|
106
|
+
tsrif: -1,
|
|
107
|
+
});
|
|
108
|
+
const returned = hashTableLinearProbing.get('tsrif');
|
|
109
|
+
|
|
110
|
+
expect(returned).toBe(-1);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it('Should return null when the key is not in the hash table linear probing', () => {
|
|
114
|
+
const hashTableLinearProbing = new HashTableLinearProbing({
|
|
115
|
+
first: 1,
|
|
116
|
+
second: 2,
|
|
117
|
+
});
|
|
118
|
+
const returned = hashTableLinearProbing.get('third');
|
|
119
|
+
|
|
120
|
+
expect(returned).toBeNull();
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
it('Should return null when the key is not in a full hash table linear probing', () => {
|
|
124
|
+
const hashTableLinearProbing = new HashTableLinearProbing({
|
|
125
|
+
first: 1,
|
|
126
|
+
second: 2,
|
|
127
|
+
}, {
|
|
128
|
+
maxSize: 2,
|
|
129
|
+
});
|
|
130
|
+
const returned = hashTableLinearProbing.get('third');
|
|
131
|
+
|
|
132
|
+
expect(returned).toBeNull();
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it('Should return null for any key in empty hash table linear probing', () => {
|
|
136
|
+
const hashTableLinearProbing = new HashTableLinearProbing();
|
|
137
|
+
const returned = hashTableLinearProbing.get('first');
|
|
138
|
+
|
|
139
|
+
expect(returned).toBeNull();
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
describe('.remove()', () => {
|
|
144
|
+
it('Should remove an element', () => {
|
|
145
|
+
const hashTableLinearProbing = new HashTableLinearProbing({
|
|
146
|
+
first: 1,
|
|
147
|
+
second: 2,
|
|
148
|
+
});
|
|
149
|
+
hashTableLinearProbing.remove('second');
|
|
150
|
+
|
|
151
|
+
expect(hashTableLinearProbing.data).toEqual({
|
|
152
|
+
52: new HashTableLinearProbingElement('first', 1),
|
|
153
|
+
});
|
|
154
|
+
expect(hashTableLinearProbing.size).toBe(1);
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
it('Should return the removed value', () => {
|
|
158
|
+
const hashTableLinearProbing = new HashTableLinearProbing({
|
|
159
|
+
first: 1,
|
|
160
|
+
second: 2,
|
|
161
|
+
});
|
|
162
|
+
const returned = hashTableLinearProbing.remove('second');
|
|
163
|
+
|
|
164
|
+
expect(returned).toBe(2);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it('Should change nothing if the key is not in the hash table linear probing', () => {
|
|
168
|
+
const hashTableLinearProbing = new HashTableLinearProbing({
|
|
169
|
+
first: 1,
|
|
170
|
+
second: 2,
|
|
171
|
+
});
|
|
172
|
+
hashTableLinearProbing.remove('third');
|
|
173
|
+
|
|
174
|
+
expect(hashTableLinearProbing.data).toEqual({
|
|
175
|
+
36: new HashTableLinearProbingElement('second', 2),
|
|
176
|
+
52: new HashTableLinearProbingElement('first', 1),
|
|
177
|
+
});
|
|
178
|
+
expect(hashTableLinearProbing.size).toBe(2);
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
it('Should return null if the key is not in the hash table linear probing', () => {
|
|
182
|
+
const hashTableLinearProbing = new HashTableLinearProbing({
|
|
183
|
+
first: 1,
|
|
184
|
+
second: 2,
|
|
185
|
+
});
|
|
186
|
+
const returned = hashTableLinearProbing.remove('third');
|
|
187
|
+
|
|
188
|
+
expect(returned).toBeNull();
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
it('Should move all the subsequent elements that have the same hash code to the left', () => {
|
|
192
|
+
const hashTableLinearProbing = new HashTableLinearProbing({
|
|
193
|
+
first: 1,
|
|
194
|
+
tsrif: -1,
|
|
195
|
+
irstf: -2,
|
|
196
|
+
srift: -3,
|
|
197
|
+
});
|
|
198
|
+
hashTableLinearProbing.remove('tsrif');
|
|
199
|
+
|
|
200
|
+
expect(hashTableLinearProbing.data).toEqual({
|
|
201
|
+
52: new HashTableLinearProbingElement('first', 1),
|
|
202
|
+
53: new HashTableLinearProbingElement('irstf', -2),
|
|
203
|
+
54: new HashTableLinearProbingElement('srift', -3),
|
|
204
|
+
});
|
|
205
|
+
expect(hashTableLinearProbing.size).toBe(3);
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
it('Should move all the subsequent elements that have the same hash code to the left when remove the first position', () => {
|
|
209
|
+
const hashTableLinearProbing = new HashTableLinearProbing({
|
|
210
|
+
first: 1,
|
|
211
|
+
tsrif: 0,
|
|
212
|
+
irstf: -1,
|
|
213
|
+
}, {
|
|
214
|
+
maxSize: 3,
|
|
215
|
+
});
|
|
216
|
+
hashTableLinearProbing.remove('first');
|
|
217
|
+
|
|
218
|
+
expect(hashTableLinearProbing.data).toEqual({
|
|
219
|
+
0: new HashTableLinearProbingElement('tsrif', 0),
|
|
220
|
+
1: new HashTableLinearProbingElement('irstf', -1),
|
|
221
|
+
});
|
|
222
|
+
expect(hashTableLinearProbing.size).toBe(2);
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
it('Should move all the subsequent elements that have the same hash code to the left when remove a middle position', () => {
|
|
226
|
+
const hashTableLinearProbing = new HashTableLinearProbing({
|
|
227
|
+
third: 3,
|
|
228
|
+
driht: -3,
|
|
229
|
+
rihtd: 0,
|
|
230
|
+
}, {
|
|
231
|
+
maxSize: 3,
|
|
232
|
+
});
|
|
233
|
+
hashTableLinearProbing.remove('third');
|
|
234
|
+
|
|
235
|
+
expect(hashTableLinearProbing.data).toEqual({
|
|
236
|
+
0: new HashTableLinearProbingElement('rihtd', 0),
|
|
237
|
+
2: new HashTableLinearProbingElement('driht', -3),
|
|
238
|
+
});
|
|
239
|
+
expect(hashTableLinearProbing.size).toBe(2);
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
describe('Conversion to primitive', () => {
|
|
244
|
+
it('Should return the elements separated by comma in string conversion', () => {
|
|
245
|
+
const hashTableLinearProbing = new HashTableLinearProbing({
|
|
246
|
+
first: 1,
|
|
247
|
+
second: 2,
|
|
248
|
+
third: 3,
|
|
249
|
+
});
|
|
250
|
+
const string = String(hashTableLinearProbing);
|
|
251
|
+
|
|
252
|
+
expect(string).toBe('[ { second => 2 }, { third => 3 }, { first => 1 } ]');
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
it('Should return the size in number conversion', () => {
|
|
256
|
+
const hashTableLinearProbing = new HashTableLinearProbing({
|
|
257
|
+
first: 1,
|
|
258
|
+
second: 2,
|
|
259
|
+
third: 3,
|
|
260
|
+
});
|
|
261
|
+
const number = Number(hashTableLinearProbing);
|
|
262
|
+
|
|
263
|
+
expect(number).toBe(3);
|
|
264
|
+
});
|
|
265
|
+
});
|
|
266
|
+
});
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import HashTableLinearProbingElement from './HashTableLinearProbingElement';
|
|
2
|
+
import IHashTableLinearProbing from './IHashTableLinearProbing';
|
|
3
|
+
import IHashTableLinearProbingInputs from './IHashTableLinearProbingInputs';
|
|
4
|
+
import IHashTableLinearProbingOptions from './IHashTableLinearProbingOptions';
|
|
5
|
+
|
|
6
|
+
export default class HashTableLinearProbing<T = number> implements IHashTableLinearProbing<T> {
|
|
7
|
+
private _maxSize: number = 0;
|
|
8
|
+
private _data: HashTableLinearProbingElement<T>[] = [];
|
|
9
|
+
|
|
10
|
+
constructor(
|
|
11
|
+
inputs: IHashTableLinearProbingInputs<T> = {},
|
|
12
|
+
{maxSize = 100}: IHashTableLinearProbingOptions = {maxSize: 100},
|
|
13
|
+
) {
|
|
14
|
+
this._maxSize = maxSize;
|
|
15
|
+
|
|
16
|
+
for (const [key, value] of Object.entries(inputs)) {
|
|
17
|
+
this.put(key, value);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
get data(): { [index: number]: HashTableLinearProbingElement<T>; } {
|
|
22
|
+
return this._data
|
|
23
|
+
.map((value, index) => ({index, value}))
|
|
24
|
+
.reduce((accumulator, current) => ({
|
|
25
|
+
...accumulator,
|
|
26
|
+
[current.index]: current.value,
|
|
27
|
+
}), {});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
get size(): number {
|
|
31
|
+
return Reflect.ownKeys(this.data).length;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
public put(key: string, value: T): T | null {
|
|
35
|
+
if (this.size === this._maxSize) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const element = new HashTableLinearProbingElement(key, value);
|
|
40
|
+
let position = this._hashCode(key);
|
|
41
|
+
|
|
42
|
+
if (this._data[position]) {
|
|
43
|
+
do {
|
|
44
|
+
position = this._nextPositionOf(position);
|
|
45
|
+
} while (this._data[position]);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
this._data[position] = element;
|
|
49
|
+
|
|
50
|
+
return value;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
public get(key: string): T | null {
|
|
54
|
+
const position = this._hashCode(key);
|
|
55
|
+
let i = position;
|
|
56
|
+
|
|
57
|
+
do {
|
|
58
|
+
if (this._data[i]?.key === key) {
|
|
59
|
+
return this._data[i].value;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
i = this._nextPositionOf(i);
|
|
63
|
+
} while (this._data[i] && i !== position);
|
|
64
|
+
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
public remove(key: string): T | null {
|
|
69
|
+
if (this.get(key)) {
|
|
70
|
+
let position = this._hashCode(key);
|
|
71
|
+
|
|
72
|
+
while (this._data[position].key !== key) {
|
|
73
|
+
position = this._nextPositionOf(position);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const {value} = this._data[position];
|
|
77
|
+
Reflect.deleteProperty(this._data, position);
|
|
78
|
+
|
|
79
|
+
let i: number;
|
|
80
|
+
for (
|
|
81
|
+
i = position;
|
|
82
|
+
this._data[this._nextPositionOf(i)]
|
|
83
|
+
&& this._hashCode(this._data[this._nextPositionOf(i)].key) === this._hashCode(key)
|
|
84
|
+
&& this._nextPositionOf(i) !== position;
|
|
85
|
+
i = this._nextPositionOf(i)
|
|
86
|
+
) {
|
|
87
|
+
this._data[i] = this._data[this._nextPositionOf(i)];
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (i !== position) {
|
|
91
|
+
Reflect.deleteProperty(this._data, i);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return value;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
private _hashCode(key: string): number {
|
|
101
|
+
const code = key
|
|
102
|
+
.split('')
|
|
103
|
+
.map(character => character.charCodeAt(0))
|
|
104
|
+
.reduce((previous, current) => previous + current, 0);
|
|
105
|
+
|
|
106
|
+
return code % this._maxSize;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
private _nextPositionOf(position: number) {
|
|
110
|
+
return (position + 1) % this._maxSize;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
private _previousPositionOf(position: number) {
|
|
114
|
+
return (position + this.size - 1) % this._maxSize;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
private [Symbol.toPrimitive](type: string): string | number | null {
|
|
118
|
+
if (type === 'string') {
|
|
119
|
+
return `[ ${Object.values(this.data).join(', ')} ]`;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (type === 'number') {
|
|
123
|
+
return this.size;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/* eslint-disable no-useless-constructor */
|
|
2
|
+
/* eslint-disable no-unused-vars */
|
|
3
|
+
|
|
4
|
+
export default class HashTableSeparateChainingElement<T> {
|
|
5
|
+
constructor(
|
|
6
|
+
public key: string,
|
|
7
|
+
public value: T,
|
|
8
|
+
) {}
|
|
9
|
+
|
|
10
|
+
private[Symbol.toPrimitive](type: string): string | number | null {
|
|
11
|
+
if (type === 'string') {
|
|
12
|
+
return `{ ${this.key} => ${this.value}}`;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (type === 'number') {
|
|
16
|
+
return 2;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import HashTableSeparateChainingElement from './HashTableSeparateChainingElement';
|
|
2
|
+
import IHashTableSeparateChainingData from './IHashTableSeparateChainingData';
|
|
3
|
+
|
|
4
|
+
interface IHashTableSeparateChaining<T> {
|
|
5
|
+
get data(): IHashTableSeparateChainingData<T>;
|
|
6
|
+
get size(): number;
|
|
7
|
+
put(_key: string, _value: T): T;
|
|
8
|
+
get(_key: string): HashTableSeparateChainingElement<T> | null;
|
|
9
|
+
remove(_key: string): HashTableSeparateChainingElement<T> | null;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export default IHashTableSeparateChaining;
|