data-structure-typed 1.47.3 → 1.47.5
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/CHANGELOG.md +1 -1
- package/benchmark/report.html +2 -2
- package/benchmark/report.json +12 -18
- package/dist/cjs/data-structures/hash/hash-map.d.ts +3 -3
- package/dist/cjs/data-structures/hash/hash-map.js +10 -4
- package/dist/cjs/data-structures/hash/hash-map.js.map +1 -1
- package/dist/cjs/data-structures/hash/hash-table.d.ts +9 -4
- package/dist/cjs/data-structures/hash/hash-table.js +50 -5
- package/dist/cjs/data-structures/hash/hash-table.js.map +1 -1
- package/dist/cjs/data-structures/heap/heap.d.ts +6 -1
- package/dist/cjs/data-structures/heap/heap.js +51 -9
- package/dist/cjs/data-structures/heap/heap.js.map +1 -1
- package/dist/cjs/data-structures/linked-list/doubly-linked-list.d.ts +56 -56
- package/dist/cjs/data-structures/linked-list/doubly-linked-list.js +117 -119
- package/dist/cjs/data-structures/linked-list/doubly-linked-list.js.map +1 -1
- package/dist/cjs/data-structures/linked-list/singly-linked-list.d.ts +36 -36
- package/dist/cjs/data-structures/linked-list/singly-linked-list.js +58 -60
- package/dist/cjs/data-structures/linked-list/singly-linked-list.js.map +1 -1
- package/dist/cjs/data-structures/queue/deque.d.ts +49 -49
- package/dist/cjs/data-structures/queue/deque.js +79 -72
- package/dist/cjs/data-structures/queue/deque.js.map +1 -1
- package/dist/cjs/data-structures/queue/queue.d.ts +45 -0
- package/dist/cjs/data-structures/queue/queue.js +77 -0
- package/dist/cjs/data-structures/queue/queue.js.map +1 -1
- package/dist/cjs/data-structures/stack/stack.d.ts +18 -5
- package/dist/cjs/data-structures/stack/stack.js +56 -7
- package/dist/cjs/data-structures/stack/stack.js.map +1 -1
- package/dist/cjs/data-structures/trie/trie.d.ts +5 -0
- package/dist/cjs/data-structures/trie/trie.js +47 -0
- package/dist/cjs/data-structures/trie/trie.js.map +1 -1
- package/dist/mjs/data-structures/hash/hash-map.d.ts +3 -3
- package/dist/mjs/data-structures/hash/hash-map.js +10 -4
- package/dist/mjs/data-structures/hash/hash-table.d.ts +9 -4
- package/dist/mjs/data-structures/hash/hash-table.js +50 -5
- package/dist/mjs/data-structures/heap/heap.d.ts +6 -1
- package/dist/mjs/data-structures/heap/heap.js +51 -9
- package/dist/mjs/data-structures/linked-list/doubly-linked-list.d.ts +56 -56
- package/dist/mjs/data-structures/linked-list/doubly-linked-list.js +117 -119
- package/dist/mjs/data-structures/linked-list/singly-linked-list.d.ts +36 -36
- package/dist/mjs/data-structures/linked-list/singly-linked-list.js +58 -60
- package/dist/mjs/data-structures/queue/deque.d.ts +49 -49
- package/dist/mjs/data-structures/queue/deque.js +79 -72
- package/dist/mjs/data-structures/queue/queue.d.ts +45 -0
- package/dist/mjs/data-structures/queue/queue.js +77 -0
- package/dist/mjs/data-structures/stack/stack.d.ts +18 -5
- package/dist/mjs/data-structures/stack/stack.js +56 -7
- package/dist/mjs/data-structures/trie/trie.d.ts +5 -0
- package/dist/mjs/data-structures/trie/trie.js +47 -0
- package/dist/umd/data-structure-typed.js +545 -276
- package/dist/umd/data-structure-typed.min.js +2 -2
- package/dist/umd/data-structure-typed.min.js.map +1 -1
- package/package.json +1 -1
- package/src/data-structures/hash/hash-map.ts +13 -7
- package/src/data-structures/hash/hash-table.ts +59 -9
- package/src/data-structures/heap/heap.ts +60 -9
- package/src/data-structures/linked-list/doubly-linked-list.ts +129 -129
- package/src/data-structures/linked-list/singly-linked-list.ts +65 -65
- package/src/data-structures/queue/deque.ts +84 -77
- package/src/data-structures/queue/queue.ts +84 -0
- package/src/data-structures/stack/stack.ts +64 -8
- package/src/data-structures/trie/trie.ts +53 -0
- package/test/integration/conversion.test.ts +0 -0
- package/test/performance/data-structures/heap/heap.test.ts +13 -4
- package/test/unit/data-structures/hash/hash-table.test.ts +58 -2
- package/test/unit/data-structures/heap/min-heap.test.ts +48 -0
- package/test/unit/data-structures/linked-list/doubly-linked-list.test.ts +2 -2
- package/test/unit/data-structures/queue/queue.test.ts +37 -0
- package/test/unit/data-structures/stack/stack.test.ts +55 -5
- package/test/unit/data-structures/trie/trie.test.ts +33 -0
|
File without changes
|
|
@@ -3,20 +3,29 @@ import * as Benchmark from 'benchmark';
|
|
|
3
3
|
import { magnitude } from '../../../utils';
|
|
4
4
|
|
|
5
5
|
const suite = new Benchmark.Suite();
|
|
6
|
-
const { TEN_THOUSAND } = magnitude;
|
|
6
|
+
const { HUNDRED_THOUSAND, TEN_THOUSAND } = magnitude;
|
|
7
7
|
|
|
8
8
|
suite
|
|
9
|
-
.add(`${
|
|
9
|
+
.add(`${HUNDRED_THOUSAND.toLocaleString()} add & pop`, () => {
|
|
10
10
|
const heap = new Heap<number>({ comparator: (a, b) => b - a });
|
|
11
11
|
|
|
12
|
-
for (let i = 0; i <
|
|
12
|
+
for (let i = 0; i < HUNDRED_THOUSAND; i++) {
|
|
13
13
|
heap.add(i);
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
for (let i = 0; i <
|
|
16
|
+
for (let i = 0; i < HUNDRED_THOUSAND; i++) {
|
|
17
17
|
heap.pop();
|
|
18
18
|
}
|
|
19
19
|
})
|
|
20
|
+
.add(`${HUNDRED_THOUSAND.toLocaleString()} add & dfs`, () => {
|
|
21
|
+
const heap = new Heap<number>({ comparator: (a, b) => b - a });
|
|
22
|
+
|
|
23
|
+
for (let i = 0; i < HUNDRED_THOUSAND; i++) {
|
|
24
|
+
heap.add(i);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
heap.dfs();
|
|
28
|
+
})
|
|
20
29
|
.add(`${TEN_THOUSAND.toLocaleString()} fib add & pop`, () => {
|
|
21
30
|
const fbHeap = new FibonacciHeap<number>();
|
|
22
31
|
for (let i = 1; i <= TEN_THOUSAND; i++) {
|
|
@@ -8,7 +8,7 @@ describe('HashNode', () => {
|
|
|
8
8
|
|
|
9
9
|
expect(hashNode.key).toBe(key);
|
|
10
10
|
expect(hashNode.value).toBe(value);
|
|
11
|
-
expect(hashNode.next).toBe(
|
|
11
|
+
expect(hashNode.next).toBe(undefined);
|
|
12
12
|
});
|
|
13
13
|
});
|
|
14
14
|
|
|
@@ -16,7 +16,7 @@ describe('HashTable', () => {
|
|
|
16
16
|
it('should initialize with default capacity', () => {
|
|
17
17
|
const hashTable = new HashTable<string, string>();
|
|
18
18
|
expect(hashTable.capacity).toBe(16);
|
|
19
|
-
expect(hashTable.buckets).toEqual(new Array(16).fill(
|
|
19
|
+
expect(hashTable.buckets).toEqual(new Array(16).fill(undefined));
|
|
20
20
|
expect(hashTable.hashFn('a')).toBe(6);
|
|
21
21
|
expect(hashTable.capacity).toBe(16);
|
|
22
22
|
expect(hashTable.size).toBe(0);
|
|
@@ -184,3 +184,59 @@ describe('HashTable performance', function () {
|
|
|
184
184
|
}
|
|
185
185
|
});
|
|
186
186
|
});
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
describe('HashTable methods', () => {
|
|
190
|
+
let hashTable: HashTable<string, string>;
|
|
191
|
+
|
|
192
|
+
beforeEach(() => {
|
|
193
|
+
hashTable = new HashTable();
|
|
194
|
+
for (let i = 0; i < 10; i++) {
|
|
195
|
+
hashTable.set(`key${i}`, `value${i}`);
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
test('should retrieve correct values with get method', () => {
|
|
200
|
+
for (let i = 0; i < 10; i++) {
|
|
201
|
+
expect(hashTable.get(`key${i}`)).toBe(`value${i}`);
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
// test('forEach should apply a function to each key-value pair', () => {
|
|
206
|
+
// const mockCallback = jest.fn();
|
|
207
|
+
// hashTable.forEach(mockCallback);
|
|
208
|
+
//
|
|
209
|
+
// expect(mockCallback.mock.calls.length).toBe(10);
|
|
210
|
+
// for (let i = 0; i < 10; i++) {
|
|
211
|
+
// // Check whether each key-value pair has been called before, regardless of the order
|
|
212
|
+
// const call = mockCallback.mock.calls.find(call => call[1] === `value${i}`);
|
|
213
|
+
// expect(call).toBeTruthy();
|
|
214
|
+
// expect(call[0]).toBe(`key${i}`);
|
|
215
|
+
// }
|
|
216
|
+
// });
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
test('filter should return a new HashTable with elements that satisfy the condition', () => {
|
|
220
|
+
const filtered = hashTable.filter(([key]) => key.endsWith('1') || key.endsWith('3'));
|
|
221
|
+
|
|
222
|
+
expect(filtered.size).toBe(2);
|
|
223
|
+
expect(filtered.get('key1')).toBe('value1');
|
|
224
|
+
expect(filtered.get('key3')).toBe('value3');
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
test('map should return a new HashTable with mapped values', () => {
|
|
228
|
+
const mapped = hashTable.map(([, value]) => value.toUpperCase());
|
|
229
|
+
|
|
230
|
+
for (let i = 0; i < 10; i++) {
|
|
231
|
+
expect(mapped.get(`key${i}`)).toBe(`value${i}`.toUpperCase());
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
test('reduce should accumulate values based on the reducer function', () => {
|
|
236
|
+
const result = hashTable.reduce((acc, [, value]) => `${acc}-${value}`, '');
|
|
237
|
+
|
|
238
|
+
expect(result).toBe('-value5-value7-value3-value4-value6-value0-value2-value8-value1-value9');
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
});
|
|
242
|
+
|
|
@@ -49,4 +49,52 @@ describe('MinHeap', () => {
|
|
|
49
49
|
minHeap.poll();
|
|
50
50
|
expect(minHeap.isEmpty()).toBe(true);
|
|
51
51
|
});
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
const n = 100000;
|
|
55
|
+
|
|
56
|
+
it('should push & dfs', () => {
|
|
57
|
+
for (let i = 0; i < n; i++) {
|
|
58
|
+
minHeap.push(i);
|
|
59
|
+
}
|
|
60
|
+
expect(minHeap.dfs()[0]).toBe(0)
|
|
61
|
+
expect(minHeap.dfs()[999]).toBe(4126)
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
describe('Heap iterative methods', () => {
|
|
67
|
+
let heap: MinHeap<number>;
|
|
68
|
+
|
|
69
|
+
beforeEach(() => {
|
|
70
|
+
heap = new MinHeap<number>();
|
|
71
|
+
for (let i = 1; i <= 10; i++) {
|
|
72
|
+
heap.add(i * 10); // Add 10, 20, ..., 100
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
test('Heap is iterable', () => {
|
|
77
|
+
expect([...heap]).toEqual([10, 20, 30, 40, 50, 60, 70, 80, 90, 100]);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
test('forEach method calls a function for each element', () => {
|
|
81
|
+
const mockCallback = jest.fn();
|
|
82
|
+
heap.forEach(mockCallback);
|
|
83
|
+
expect(mockCallback.mock.calls.length).toBe(10);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
test('filter method returns filtered elements', () => {
|
|
87
|
+
const result = heap.filter(x => x > 50);
|
|
88
|
+
expect([...result]).toEqual([60, 70, 80, 90, 100]);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
test('map method correctly maps elements', () => {
|
|
92
|
+
const result = heap.map(x => x / 10, (a: number, b: number) => a - b);
|
|
93
|
+
expect([...result]).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test('reduce method correctly reduces elements', () => {
|
|
97
|
+
const result = heap.reduce((acc, curr) => acc + curr, 0);
|
|
98
|
+
expect(result).toBe(550); // 10+20+...+100 = 550
|
|
99
|
+
});
|
|
52
100
|
});
|
|
@@ -166,7 +166,7 @@ describe('DoublyLinkedList Operation Test', () => {
|
|
|
166
166
|
list.reverse();
|
|
167
167
|
|
|
168
168
|
expect(list.toArray()).toEqual([3, 2, 1]);
|
|
169
|
-
expect(list.
|
|
169
|
+
expect(list.toReversedArray()).toEqual([1, 2, 3]);
|
|
170
170
|
});
|
|
171
171
|
|
|
172
172
|
it('should map elements using a callback function', () => {
|
|
@@ -268,7 +268,7 @@ describe('DoublyLinkedList Operation Test', () => {
|
|
|
268
268
|
list.push(2);
|
|
269
269
|
list.push(3);
|
|
270
270
|
|
|
271
|
-
const reversedArray = list.
|
|
271
|
+
const reversedArray = list.toReversedArray();
|
|
272
272
|
|
|
273
273
|
expect(reversedArray).toEqual([3, 2, 1]);
|
|
274
274
|
});
|
|
@@ -205,3 +205,40 @@ describe('Queue Performance Test', () => {
|
|
|
205
205
|
expect(performance.now() - startTime).toBeLessThan(bigO.LINEAR * 100);
|
|
206
206
|
});
|
|
207
207
|
});
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
describe('Queue iterative methods', () => {
|
|
211
|
+
let queue: Queue<number>;
|
|
212
|
+
|
|
213
|
+
beforeEach(() => {
|
|
214
|
+
queue = new Queue();
|
|
215
|
+
for (let i = 0; i < 10; i++) {
|
|
216
|
+
queue.enqueue(i);
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
test('iterator should provide access to all elements', () => {
|
|
221
|
+
const elements = [];
|
|
222
|
+
for (const item of queue) {
|
|
223
|
+
elements.push(item);
|
|
224
|
+
}
|
|
225
|
+
expect(elements).toEqual([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
test('forEach should apply the callback to each element', () => {
|
|
229
|
+
const elements: number[] = [];
|
|
230
|
+
queue.forEach((element) => elements.push(element * 2));
|
|
231
|
+
expect(elements).toEqual([0, 2, 4, 6, 8, 10, 12, 14, 16, 18]);
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
test('filter should return a new queue with only the elements that satisfy the predicate', () => {
|
|
235
|
+
const filteredQueue = queue.filter(element => element % 2 === 0);
|
|
236
|
+
expect([...filteredQueue]).toEqual([0, 2, 4, 6, 8]);
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
test('map should return a new queue with the transformed elements', () => {
|
|
240
|
+
const mappedQueue = queue.map(element => element * 2);
|
|
241
|
+
expect([...mappedQueue]).toEqual([0, 2, 4, 6, 8, 10, 12, 14, 16, 18]);
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
});
|
|
@@ -15,7 +15,7 @@ describe('Stack', () => {
|
|
|
15
15
|
stack.push(1);
|
|
16
16
|
stack.push(2);
|
|
17
17
|
stack.push(3);
|
|
18
|
-
expect(stack.size
|
|
18
|
+
expect(stack.size).toBe(3);
|
|
19
19
|
});
|
|
20
20
|
|
|
21
21
|
it('should peek at the top element without removing it', () => {
|
|
@@ -23,7 +23,7 @@ describe('Stack', () => {
|
|
|
23
23
|
stack.push(2);
|
|
24
24
|
stack.push(3);
|
|
25
25
|
expect(stack.peek()).toBe(3);
|
|
26
|
-
expect(stack.size
|
|
26
|
+
expect(stack.size).toBe(3);
|
|
27
27
|
});
|
|
28
28
|
|
|
29
29
|
it('should pop elements from the stack', () => {
|
|
@@ -32,7 +32,7 @@ describe('Stack', () => {
|
|
|
32
32
|
stack.push(3);
|
|
33
33
|
const poppedElement = stack.pop();
|
|
34
34
|
expect(poppedElement).toBe(3);
|
|
35
|
-
expect(stack.size
|
|
35
|
+
expect(stack.size).toBe(2);
|
|
36
36
|
});
|
|
37
37
|
|
|
38
38
|
it('should return null when popping from an empty stack', () => {
|
|
@@ -53,7 +53,7 @@ describe('Stack', () => {
|
|
|
53
53
|
stack.push(2);
|
|
54
54
|
stack.push(3);
|
|
55
55
|
stack.clear();
|
|
56
|
-
expect(stack.size
|
|
56
|
+
expect(stack.size).toBe(0);
|
|
57
57
|
expect(stack.isEmpty()).toBe(true);
|
|
58
58
|
});
|
|
59
59
|
|
|
@@ -61,7 +61,57 @@ describe('Stack', () => {
|
|
|
61
61
|
stack.push(1);
|
|
62
62
|
stack.push(2);
|
|
63
63
|
const clonedStack = stack.clone();
|
|
64
|
-
expect(clonedStack.size
|
|
64
|
+
expect(clonedStack.size).toBe(2);
|
|
65
65
|
expect(clonedStack.pop()).toBe(2);
|
|
66
66
|
});
|
|
67
67
|
});
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
describe('Stack iterative methods', () => {
|
|
71
|
+
let stack: Stack<number>; // Declare a Stack instance
|
|
72
|
+
|
|
73
|
+
beforeEach(() => {
|
|
74
|
+
stack = new Stack<number>(); // Create a new Stack instance before each test
|
|
75
|
+
stack.push(1);
|
|
76
|
+
stack.push(2);
|
|
77
|
+
stack.push(3);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
test('should iterate through the stack', () => {
|
|
81
|
+
const result: number[] = [];
|
|
82
|
+
for (const element of stack) {
|
|
83
|
+
result.push(element);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
expect(result).toEqual([3, 2, 1]); // iteration should start from the top of the stack
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
test('should apply forEach to the stack', () => {
|
|
90
|
+
const result: number[] = [];
|
|
91
|
+
stack.forEach((element) => {
|
|
92
|
+
result.push(element);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
expect(result).toEqual([3, 2, 1]);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
test('should filter elements in the stack', () => {
|
|
99
|
+
const filteredStack = stack.filter((element) => element > 1);
|
|
100
|
+
|
|
101
|
+
expect(filteredStack.size).toBe(2);
|
|
102
|
+
expect([...filteredStack]).toEqual([2, 3]);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
test('should map elements in the stack', () => {
|
|
106
|
+
const mappedStack = stack.map((element) => element * 2);
|
|
107
|
+
|
|
108
|
+
expect(mappedStack.size).toBe(3);
|
|
109
|
+
expect([...mappedStack]).toEqual([2, 4, 6]);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
test('should reduce elements in the stack', () => {
|
|
113
|
+
const sum = stack.reduce((accumulator, element) => accumulator + element, 0);
|
|
114
|
+
|
|
115
|
+
expect(sum).toBe(6);
|
|
116
|
+
});
|
|
117
|
+
});
|
|
@@ -823,3 +823,36 @@ describe('Trie operations', () => {
|
|
|
823
823
|
expect(trie.getHeight()).toBe(6); // Assuming 'apple' and 'banana' are the longest words.
|
|
824
824
|
});
|
|
825
825
|
});
|
|
826
|
+
|
|
827
|
+
describe('Trie class', () => {
|
|
828
|
+
let trie: Trie;
|
|
829
|
+
beforeEach(() => {
|
|
830
|
+
trie = new Trie(['apple', 'app', 'banana', 'band', 'bandana']);
|
|
831
|
+
});
|
|
832
|
+
|
|
833
|
+
test('[Symbol.iterator] should iterate over all words', () => {
|
|
834
|
+
const words = [...trie];
|
|
835
|
+
expect(words).toEqual(['app', 'apple', 'banana', 'band', 'bandana']);
|
|
836
|
+
});
|
|
837
|
+
|
|
838
|
+
test('forEach should execute a callback for each word', () => {
|
|
839
|
+
const mockCallback = jest.fn();
|
|
840
|
+
trie.forEach(mockCallback);
|
|
841
|
+
expect(mockCallback).toHaveBeenCalledTimes(5);
|
|
842
|
+
});
|
|
843
|
+
|
|
844
|
+
test('filter should return words that satisfy the predicate', () => {
|
|
845
|
+
const filteredWords = trie.filter(word => word.startsWith('ba'));
|
|
846
|
+
expect(filteredWords).toEqual(['banana', 'band', 'bandana']);
|
|
847
|
+
});
|
|
848
|
+
|
|
849
|
+
test('map should apply a function to each word', () => {
|
|
850
|
+
const mappedWords = trie.map(word => word.length.toString());
|
|
851
|
+
expect([...mappedWords]).toEqual(['3', '5', '6', '4', '7']);
|
|
852
|
+
});
|
|
853
|
+
|
|
854
|
+
test('reduce should reduce the words to a single value', () => {
|
|
855
|
+
const concatenatedWords = trie.reduce((acc, word) => acc + word, '');
|
|
856
|
+
expect(concatenatedWords).toEqual('appapplebananabandbandana');
|
|
857
|
+
});
|
|
858
|
+
});
|