data-structure-typed 1.48.8 → 1.49.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.
- package/CHANGELOG.md +1 -1
- package/README.md +58 -55
- package/README_zh-CN.md +58 -56
- package/benchmark/report.html +1 -46
- package/benchmark/report.json +23 -458
- package/dist/cjs/data-structures/binary-tree/avl-tree.d.ts +8 -1
- package/dist/cjs/data-structures/binary-tree/avl-tree.js +9 -0
- package/dist/cjs/data-structures/binary-tree/avl-tree.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/binary-tree.d.ts +15 -10
- package/dist/cjs/data-structures/binary-tree/binary-tree.js +55 -49
- package/dist/cjs/data-structures/binary-tree/binary-tree.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/bst.d.ts +8 -1
- package/dist/cjs/data-structures/binary-tree/bst.js +9 -0
- package/dist/cjs/data-structures/binary-tree/bst.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/rb-tree.d.ts +10 -16
- package/dist/cjs/data-structures/binary-tree/rb-tree.js +16 -29
- package/dist/cjs/data-structures/binary-tree/rb-tree.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/tree-multimap.d.ts +8 -1
- package/dist/cjs/data-structures/binary-tree/tree-multimap.js +9 -0
- package/dist/cjs/data-structures/binary-tree/tree-multimap.js.map +1 -1
- package/dist/cjs/data-structures/queue/deque.d.ts +0 -110
- package/dist/cjs/data-structures/queue/deque.js +1 -172
- package/dist/cjs/data-structures/queue/deque.js.map +1 -1
- package/dist/mjs/data-structures/binary-tree/avl-tree.d.ts +8 -1
- package/dist/mjs/data-structures/binary-tree/avl-tree.js +9 -0
- package/dist/mjs/data-structures/binary-tree/binary-tree.d.ts +15 -10
- package/dist/mjs/data-structures/binary-tree/binary-tree.js +55 -49
- package/dist/mjs/data-structures/binary-tree/bst.d.ts +8 -1
- package/dist/mjs/data-structures/binary-tree/bst.js +9 -0
- package/dist/mjs/data-structures/binary-tree/rb-tree.d.ts +10 -16
- package/dist/mjs/data-structures/binary-tree/rb-tree.js +16 -28
- package/dist/mjs/data-structures/binary-tree/tree-multimap.d.ts +8 -1
- package/dist/mjs/data-structures/binary-tree/tree-multimap.js +9 -0
- package/dist/mjs/data-structures/queue/deque.d.ts +0 -110
- package/dist/mjs/data-structures/queue/deque.js +0 -170
- package/dist/umd/data-structure-typed.js +94 -239
- 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/binary-tree/avl-tree.ts +11 -1
- package/src/data-structures/binary-tree/binary-tree.ts +65 -56
- package/src/data-structures/binary-tree/bst.ts +11 -1
- package/src/data-structures/binary-tree/rb-tree.ts +18 -32
- package/src/data-structures/binary-tree/tree-multimap.ts +17 -1
- package/src/data-structures/queue/deque.ts +1 -191
- package/test/unit/data-structures/binary-tree/binary-tree.test.ts +15 -8
- package/test/unit/data-structures/binary-tree/bst.test.ts +1 -1
- package/test/unit/data-structures/binary-tree/rb-tree.test.ts +5 -5
- package/test/unit/data-structures/queue/deque.test.ts +265 -367
- package/test/unit/data-structures/queue/queue.test.ts +158 -158
|
@@ -1,21 +1,7 @@
|
|
|
1
1
|
import { LinkedListQueue, Queue } from '../../../../src';
|
|
2
|
-
import { bigO } from '../../../utils';
|
|
3
2
|
import { isDebugTest } from '../../../config';
|
|
4
3
|
|
|
5
4
|
const isDebug = isDebugTest;
|
|
6
|
-
describe('Queue Operation Test', () => {
|
|
7
|
-
it('should validate a queue', () => {
|
|
8
|
-
const queue = new Queue<number>();
|
|
9
|
-
for (let i = 0; i < 1000; i++) {
|
|
10
|
-
queue.enqueue(i);
|
|
11
|
-
}
|
|
12
|
-
let last: number | undefined = 0;
|
|
13
|
-
for (let i = 0; i < 1000; i++) {
|
|
14
|
-
last = queue.dequeue();
|
|
15
|
-
}
|
|
16
|
-
expect(last).toBe(999);
|
|
17
|
-
});
|
|
18
|
-
});
|
|
19
5
|
|
|
20
6
|
describe('Queue', () => {
|
|
21
7
|
let queue: Queue<number>;
|
|
@@ -24,117 +10,209 @@ describe('Queue', () => {
|
|
|
24
10
|
queue = new Queue<number>();
|
|
25
11
|
});
|
|
26
12
|
|
|
27
|
-
|
|
13
|
+
test('new Queue() should create an empty queue', () => {
|
|
28
14
|
expect(queue.size).toBe(0);
|
|
15
|
+
expect(queue.isEmpty()).toBeTruthy();
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
test('push should add elements to the queue', () => {
|
|
19
|
+
queue.push(1);
|
|
20
|
+
queue.push(2);
|
|
21
|
+
expect(queue.size).toBe(2);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test('shift should remove the first element', () => {
|
|
25
|
+
queue.push(1);
|
|
26
|
+
queue.enqueue(2);
|
|
27
|
+
expect(queue.shift()).toBe(1);
|
|
28
|
+
expect(queue.size).toBe(1);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test('shift should return undefined if queue is empty', () => {
|
|
32
|
+
expect(queue.dequeue()).toBeUndefined();
|
|
29
33
|
});
|
|
30
34
|
|
|
31
|
-
|
|
35
|
+
test('peek should return the first element without removing it', () => {
|
|
32
36
|
queue.push(1);
|
|
33
37
|
queue.push(2);
|
|
34
38
|
expect(queue.peek()).toBe(1);
|
|
35
39
|
expect(queue.size).toBe(2);
|
|
36
40
|
});
|
|
41
|
+
|
|
42
|
+
test('peek should return undefined if queue is empty', () => {
|
|
43
|
+
expect(queue.peek()).toBeUndefined();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test('size should return the number of elements', () => {
|
|
47
|
+
queue.push(1);
|
|
48
|
+
queue.push(2);
|
|
49
|
+
expect(queue.size).toBe(2);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test('isEmpty should return true if the queue is empty', () => {
|
|
53
|
+
expect(queue.isEmpty()).toBeTruthy();
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test('isEmpty should return false if the queue is not empty', () => {
|
|
57
|
+
queue.push(1);
|
|
58
|
+
expect(queue.isEmpty()).toBeFalsy();
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test('toArray should return an array of queue elements', () => {
|
|
62
|
+
queue.push(1);
|
|
63
|
+
queue.push(2);
|
|
64
|
+
expect(queue.toArray()).toEqual([1, 2]);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test('clear should remove all elements from the queue', () => {
|
|
68
|
+
queue.push(1);
|
|
69
|
+
queue.push(2);
|
|
70
|
+
queue.clear();
|
|
71
|
+
expect(queue.size).toBe(0);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test('forEach should iterate over all elements', () => {
|
|
75
|
+
const arr: number[] = [];
|
|
76
|
+
queue.push(1);
|
|
77
|
+
queue.push(2);
|
|
78
|
+
queue.forEach(element => arr.push(element));
|
|
79
|
+
expect(arr).toEqual([1, 2]);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
// Boundary value testing
|
|
83
|
+
test('push and shift with many elements', () => {
|
|
84
|
+
for (let i = 0; i < 1000; i++) {
|
|
85
|
+
queue.push(i);
|
|
86
|
+
}
|
|
87
|
+
for (let i = 0; i < 1000; i++) {
|
|
88
|
+
expect(queue.shift()).toBe(i);
|
|
89
|
+
}
|
|
90
|
+
expect(queue.isEmpty()).toBeTruthy();
|
|
91
|
+
});
|
|
37
92
|
});
|
|
38
93
|
|
|
39
|
-
describe('Queue', () => {
|
|
94
|
+
describe('Queue - Advanced Methods', () => {
|
|
40
95
|
let queue: Queue<number>;
|
|
41
96
|
|
|
42
97
|
beforeEach(() => {
|
|
43
98
|
queue = new Queue<number>();
|
|
44
99
|
});
|
|
45
100
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
101
|
+
test('reduce should apply a function against an accumulator and each element', () => {
|
|
102
|
+
queue.push(1);
|
|
103
|
+
queue.push(2);
|
|
104
|
+
queue.push(3);
|
|
105
|
+
const sum = queue.reduce((acc, val) => acc + val, 0);
|
|
106
|
+
expect(sum).toBe(6);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
test('reduce should return initial value for empty queue', () => {
|
|
110
|
+
const initialValue = 0;
|
|
111
|
+
const sum = queue.reduce((acc, val) => acc + val, initialValue);
|
|
112
|
+
expect(sum).toBe(initialValue);
|
|
49
113
|
});
|
|
50
114
|
|
|
51
|
-
|
|
115
|
+
test('filter should return a new queue with all elements that pass the test implemented by provided function', () => {
|
|
52
116
|
queue.push(1);
|
|
53
117
|
queue.push(2);
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
expect(
|
|
118
|
+
queue.push(3);
|
|
119
|
+
const filteredQueue = queue.filter(val => val > 1);
|
|
120
|
+
expect(filteredQueue.toArray()).toEqual([2, 3]);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
test('filter should return an empty queue for empty queue', () => {
|
|
124
|
+
const filteredQueue = queue.filter(val => val > 1);
|
|
125
|
+
expect(filteredQueue.isEmpty()).toBeTruthy();
|
|
57
126
|
});
|
|
58
127
|
|
|
59
|
-
|
|
128
|
+
test('map should create a new queue with the results of calling a provided function on every element', () => {
|
|
60
129
|
queue.push(1);
|
|
61
130
|
queue.push(2);
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
expect(
|
|
65
|
-
expect(queue.peek()).toBe(2);
|
|
66
|
-
expect(queue.getLast()).toBe(2);
|
|
131
|
+
queue.push(3);
|
|
132
|
+
const mappedQueue = queue.map(val => val * 2);
|
|
133
|
+
expect(mappedQueue.toArray()).toEqual([2, 4, 6]);
|
|
67
134
|
});
|
|
68
135
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
136
|
+
test('map should return an empty queue for empty queue', () => {
|
|
137
|
+
const mappedQueue = queue.map(val => val * 2);
|
|
138
|
+
expect(mappedQueue.isEmpty()).toBeTruthy();
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
describe('Queue - Additional Methods', () => {
|
|
142
|
+
let queue: Queue<number>;
|
|
143
|
+
|
|
144
|
+
beforeEach(() => {
|
|
145
|
+
queue = new Queue<number>();
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
test('peekLast should return the last element without removing it', () => {
|
|
149
|
+
queue.push(1);
|
|
150
|
+
queue.push(2);
|
|
151
|
+
expect(queue.peekLast()).toBe(2);
|
|
78
152
|
expect(queue.size).toBe(2);
|
|
79
|
-
expect(queue.nodes.length).toBe(2);
|
|
80
|
-
expect(queue.peek()).toBe(4);
|
|
81
153
|
});
|
|
82
154
|
|
|
83
|
-
|
|
155
|
+
test('peekLast should return undefined if queue is empty', () => {
|
|
156
|
+
expect(queue.peekLast()).toBeUndefined();
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
test('getAt should return the element at the specified index', () => {
|
|
84
160
|
queue.push(1);
|
|
85
161
|
queue.push(2);
|
|
86
|
-
|
|
87
|
-
expect(queue.
|
|
162
|
+
queue.push(3);
|
|
163
|
+
expect(queue.getAt(1)).toBe(2);
|
|
88
164
|
});
|
|
89
165
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
expect(
|
|
93
|
-
expect(queue.
|
|
94
|
-
expect(queue.peek()).toBeUndefined();
|
|
166
|
+
test('getAt should return undefined for an invalid index', () => {
|
|
167
|
+
queue.push(1);
|
|
168
|
+
expect(queue.getAt(3)).toBeUndefined();
|
|
169
|
+
expect(queue.getAt(-1)).toBeUndefined();
|
|
95
170
|
});
|
|
96
171
|
|
|
97
|
-
|
|
98
|
-
expect(
|
|
99
|
-
|
|
172
|
+
test('print should not throw any errors', () => {
|
|
173
|
+
expect(() => {
|
|
174
|
+
queue.push(1);
|
|
175
|
+
queue.print();
|
|
176
|
+
}).not.toThrow();
|
|
100
177
|
});
|
|
178
|
+
});
|
|
101
179
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
queue.
|
|
107
|
-
expect(queue.size).toBe(
|
|
108
|
-
expect(queue.peek()).toBeUndefined();
|
|
109
|
-
expect(queue.getLast()).toBeUndefined();
|
|
180
|
+
describe('Queue - Static and Clone Methods', () => {
|
|
181
|
+
test('fromArray should create a new queue from an array', () => {
|
|
182
|
+
const array = [1, 2, 3];
|
|
183
|
+
const queue = Queue.fromArray(array);
|
|
184
|
+
expect(queue.toArray()).toEqual(array);
|
|
185
|
+
expect(queue.size).toBe(array.length);
|
|
110
186
|
});
|
|
111
187
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
}
|
|
116
|
-
const clonedQueue = queue.clone();
|
|
117
|
-
expect(clonedQueue.size).toBe(3);
|
|
118
|
-
expect(clonedQueue.peek()).toBe(1);
|
|
119
|
-
expect(clonedQueue.getLast()).toBe(3);
|
|
188
|
+
test('fromArray should create an empty queue from an empty array', () => {
|
|
189
|
+
const queue = Queue.fromArray([]);
|
|
190
|
+
expect(queue.isEmpty()).toBeTruthy();
|
|
120
191
|
});
|
|
121
192
|
|
|
122
|
-
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
193
|
+
test('clone should create a new queue with the same elements', () => {
|
|
194
|
+
const originalQueue = new Queue<number>();
|
|
195
|
+
originalQueue.push(1);
|
|
196
|
+
originalQueue.push(2);
|
|
197
|
+
|
|
198
|
+
const clonedQueue = originalQueue.clone();
|
|
199
|
+
expect(clonedQueue.toArray()).toEqual(originalQueue.toArray());
|
|
200
|
+
expect(clonedQueue.size).toBe(originalQueue.size);
|
|
128
201
|
});
|
|
129
202
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
203
|
+
test('clone should not affect the original queue when mutated', () => {
|
|
204
|
+
const originalQueue = new Queue<number>();
|
|
205
|
+
originalQueue.push(1);
|
|
206
|
+
originalQueue.push(2);
|
|
207
|
+
|
|
208
|
+
const clonedQueue = originalQueue.clone();
|
|
209
|
+
clonedQueue.push(3);
|
|
210
|
+
|
|
211
|
+
expect(clonedQueue.size).not.toBe(originalQueue.size);
|
|
212
|
+
expect(originalQueue.toArray()).not.toContain(3);
|
|
136
213
|
});
|
|
137
214
|
});
|
|
215
|
+
|
|
138
216
|
describe('LinkedListQueue', () => {
|
|
139
217
|
let queue: LinkedListQueue<string>;
|
|
140
218
|
|
|
@@ -163,82 +241,4 @@ describe('LinkedListQueue', () => {
|
|
|
163
241
|
queue.enqueue('B');
|
|
164
242
|
expect(queue.peek()).toBe('A');
|
|
165
243
|
});
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
describe('Queue Performance Test', () => {
|
|
169
|
-
const dataSize = 10000;
|
|
170
|
-
it('should numeric queue be efficient', function () {
|
|
171
|
-
const startTime = performance.now();
|
|
172
|
-
const queue = new Queue<number>();
|
|
173
|
-
for (let i = 0; i < dataSize; i++) {
|
|
174
|
-
queue.enqueue(i);
|
|
175
|
-
}
|
|
176
|
-
for (let i = 0; i < dataSize; i++) {
|
|
177
|
-
queue.dequeue();
|
|
178
|
-
}
|
|
179
|
-
isDebug && console.log(`Queue Performance Test: ${performance.now() - startTime} ms`);
|
|
180
|
-
expect(performance.now() - startTime).toBeLessThan(bigO.LINEAR * 100);
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
it('should numeric Array be more efficient than Queue when the data size is 10000', function () {
|
|
184
|
-
const startTime2 = performance.now();
|
|
185
|
-
const queue2: number[] = [];
|
|
186
|
-
for (let i = 0; i < dataSize; i++) {
|
|
187
|
-
queue2.push(i);
|
|
188
|
-
}
|
|
189
|
-
for (let i = 0; i < dataSize; i++) {
|
|
190
|
-
queue2.shift();
|
|
191
|
-
}
|
|
192
|
-
expect(performance.now() - startTime2).toBeLessThan(bigO.CUBED * 100);
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
it('should numeric LinkedListQueue be efficient', function () {
|
|
196
|
-
const startTime = performance.now();
|
|
197
|
-
const queue = new LinkedListQueue<number>();
|
|
198
|
-
for (let i = 0; i < dataSize; i++) {
|
|
199
|
-
queue.enqueue(i);
|
|
200
|
-
}
|
|
201
|
-
for (let i = 0; i < dataSize; i++) {
|
|
202
|
-
queue.dequeue();
|
|
203
|
-
}
|
|
204
|
-
// console.log(`LinkedListQueue Performance Test: ${performance.now() - startTime} ms`);
|
|
205
|
-
expect(performance.now() - startTime).toBeLessThan(bigO.LINEAR * 100);
|
|
206
|
-
});
|
|
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
244
|
});
|