data-structure-typed 1.35.0 → 1.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (203) hide show
  1. package/.github/workflows/ci.yml +3 -0
  2. package/CHANGELOG.md +8 -1
  3. package/CONTRIBUTING.md +18 -0
  4. package/dist/data-structures/binary-tree/aa-tree.d.ts +2 -0
  5. package/dist/data-structures/binary-tree/abstract-binary-tree.d.ts +527 -0
  6. package/dist/data-structures/binary-tree/abstract-binary-tree.js +323 -0
  7. package/dist/data-structures/binary-tree/abstract-binary-tree.js.map +1 -1
  8. package/dist/data-structures/binary-tree/avl-tree.d.ts +94 -0
  9. package/dist/data-structures/binary-tree/avl-tree.js +90 -3
  10. package/dist/data-structures/binary-tree/avl-tree.js.map +1 -1
  11. package/dist/data-structures/binary-tree/b-tree.d.ts +2 -0
  12. package/dist/data-structures/binary-tree/binary-indexed-tree.d.ts +46 -0
  13. package/dist/data-structures/binary-tree/binary-indexed-tree.js +36 -0
  14. package/dist/data-structures/binary-tree/binary-indexed-tree.js.map +1 -1
  15. package/dist/data-structures/binary-tree/binary-tree.d.ts +31 -0
  16. package/dist/data-structures/binary-tree/binary-tree.js +21 -0
  17. package/dist/data-structures/binary-tree/binary-tree.js.map +1 -1
  18. package/dist/data-structures/binary-tree/bst.d.ts +133 -0
  19. package/dist/data-structures/binary-tree/bst.js +114 -0
  20. package/dist/data-structures/binary-tree/bst.js.map +1 -1
  21. package/dist/data-structures/binary-tree/index.d.ts +12 -0
  22. package/dist/data-structures/binary-tree/rb-tree.d.ts +13 -0
  23. package/dist/data-structures/binary-tree/segment-tree.d.ts +83 -0
  24. package/dist/data-structures/binary-tree/segment-tree.js +45 -0
  25. package/dist/data-structures/binary-tree/segment-tree.js.map +1 -1
  26. package/dist/data-structures/binary-tree/splay-tree.d.ts +2 -0
  27. package/dist/data-structures/binary-tree/tree-multiset.d.ts +209 -0
  28. package/dist/data-structures/binary-tree/tree-multiset.js +178 -0
  29. package/dist/data-structures/binary-tree/tree-multiset.js.map +1 -1
  30. package/dist/data-structures/binary-tree/two-three-tree.d.ts +2 -0
  31. package/dist/data-structures/graph/abstract-graph.d.ts +332 -0
  32. package/dist/data-structures/graph/abstract-graph.js +270 -7
  33. package/dist/data-structures/graph/abstract-graph.js.map +1 -1
  34. package/dist/data-structures/graph/directed-graph.d.ts +200 -0
  35. package/dist/data-structures/graph/directed-graph.js +167 -0
  36. package/dist/data-structures/graph/directed-graph.js.map +1 -1
  37. package/dist/data-structures/graph/index.d.ts +4 -0
  38. package/dist/data-structures/graph/map-graph.d.ts +79 -0
  39. package/dist/data-structures/graph/map-graph.js +54 -0
  40. package/dist/data-structures/graph/map-graph.js.map +1 -1
  41. package/dist/data-structures/graph/undirected-graph.d.ts +127 -0
  42. package/dist/data-structures/graph/undirected-graph.js +105 -0
  43. package/dist/data-structures/graph/undirected-graph.js.map +1 -1
  44. package/dist/data-structures/hash/coordinate-map.d.ts +45 -0
  45. package/dist/data-structures/hash/coordinate-map.js +35 -0
  46. package/dist/data-structures/hash/coordinate-map.js.map +1 -1
  47. package/dist/data-structures/hash/coordinate-set.d.ts +37 -0
  48. package/dist/data-structures/hash/coordinate-set.js +28 -0
  49. package/dist/data-structures/hash/coordinate-set.js.map +1 -1
  50. package/dist/data-structures/hash/hash-map.d.ts +56 -0
  51. package/dist/data-structures/hash/hash-map.js +29 -1
  52. package/dist/data-structures/hash/hash-map.js.map +1 -1
  53. package/dist/data-structures/hash/hash-table.d.ts +106 -0
  54. package/dist/data-structures/hash/hash-table.js +88 -6
  55. package/dist/data-structures/hash/hash-table.js.map +1 -1
  56. package/dist/data-structures/hash/index.d.ts +7 -0
  57. package/dist/data-structures/hash/pair.d.ts +2 -0
  58. package/dist/data-structures/hash/tree-map.d.ts +2 -0
  59. package/dist/data-structures/hash/tree-set.d.ts +2 -0
  60. package/dist/data-structures/heap/heap.d.ts +100 -0
  61. package/dist/data-structures/heap/heap.js +215 -76
  62. package/dist/data-structures/heap/heap.js.map +1 -1
  63. package/dist/data-structures/heap/index.d.ts +3 -0
  64. package/dist/data-structures/heap/max-heap.d.ts +12 -0
  65. package/dist/data-structures/heap/max-heap.js +16 -6
  66. package/dist/data-structures/heap/max-heap.js.map +1 -1
  67. package/dist/data-structures/heap/min-heap.d.ts +12 -0
  68. package/dist/data-structures/heap/min-heap.js +16 -6
  69. package/dist/data-structures/heap/min-heap.js.map +1 -1
  70. package/dist/data-structures/index.d.ts +11 -0
  71. package/dist/data-structures/linked-list/doubly-linked-list.d.ts +234 -0
  72. package/dist/data-structures/linked-list/doubly-linked-list.js +202 -0
  73. package/dist/data-structures/linked-list/doubly-linked-list.js.map +1 -1
  74. package/dist/data-structures/linked-list/index.d.ts +3 -0
  75. package/dist/data-structures/linked-list/singly-linked-list.d.ts +157 -0
  76. package/dist/data-structures/linked-list/singly-linked-list.js +135 -0
  77. package/dist/data-structures/linked-list/singly-linked-list.js.map +1 -1
  78. package/dist/data-structures/linked-list/skip-linked-list.d.ts +61 -0
  79. package/dist/data-structures/linked-list/skip-linked-list.js +36 -0
  80. package/dist/data-structures/linked-list/skip-linked-list.js.map +1 -1
  81. package/dist/data-structures/matrix/index.d.ts +4 -0
  82. package/dist/data-structures/matrix/matrix.d.ts +21 -0
  83. package/dist/data-structures/matrix/matrix.js +15 -0
  84. package/dist/data-structures/matrix/matrix.js.map +1 -1
  85. package/dist/data-structures/matrix/matrix2d.d.ts +108 -0
  86. package/dist/data-structures/matrix/matrix2d.js +91 -2
  87. package/dist/data-structures/matrix/matrix2d.js.map +1 -1
  88. package/dist/data-structures/matrix/navigator.d.ts +52 -0
  89. package/dist/data-structures/matrix/navigator.js +28 -0
  90. package/dist/data-structures/matrix/navigator.js.map +1 -1
  91. package/dist/data-structures/matrix/vector2d.d.ts +201 -0
  92. package/dist/data-structures/matrix/vector2d.js +188 -1
  93. package/dist/data-structures/matrix/vector2d.js.map +1 -1
  94. package/dist/data-structures/priority-queue/index.d.ts +3 -0
  95. package/dist/data-structures/priority-queue/max-priority-queue.d.ts +12 -0
  96. package/dist/data-structures/priority-queue/max-priority-queue.js +16 -17
  97. package/dist/data-structures/priority-queue/max-priority-queue.js.map +1 -1
  98. package/dist/data-structures/priority-queue/min-priority-queue.d.ts +12 -0
  99. package/dist/data-structures/priority-queue/min-priority-queue.js +16 -17
  100. package/dist/data-structures/priority-queue/min-priority-queue.js.map +1 -1
  101. package/dist/data-structures/priority-queue/priority-queue.d.ts +12 -0
  102. package/dist/data-structures/priority-queue/priority-queue.js +11 -174
  103. package/dist/data-structures/priority-queue/priority-queue.js.map +1 -1
  104. package/dist/data-structures/queue/deque.d.ts +165 -0
  105. package/dist/data-structures/queue/deque.js +124 -0
  106. package/dist/data-structures/queue/deque.js.map +1 -1
  107. package/dist/data-structures/queue/index.d.ts +2 -0
  108. package/dist/data-structures/queue/queue.d.ts +107 -0
  109. package/dist/data-structures/queue/queue.js +80 -0
  110. package/dist/data-structures/queue/queue.js.map +1 -1
  111. package/dist/data-structures/stack/index.d.ts +1 -0
  112. package/dist/data-structures/stack/stack.d.ts +63 -0
  113. package/dist/data-structures/stack/stack.js +50 -0
  114. package/dist/data-structures/stack/stack.js.map +1 -1
  115. package/dist/data-structures/tree/index.d.ts +1 -0
  116. package/dist/data-structures/tree/tree.d.ts +14 -0
  117. package/dist/data-structures/tree/tree.js +1 -0
  118. package/dist/data-structures/tree/tree.js.map +1 -1
  119. package/dist/data-structures/trie/index.d.ts +1 -0
  120. package/dist/data-structures/trie/trie.d.ts +61 -0
  121. package/dist/data-structures/trie/trie.js +36 -0
  122. package/dist/data-structures/trie/trie.js.map +1 -1
  123. package/dist/index.d.ts +4 -0
  124. package/dist/interfaces/abstract-binary-tree.d.ts +7 -0
  125. package/dist/interfaces/abstract-graph.d.ts +5 -0
  126. package/dist/interfaces/avl-tree.d.ts +7 -0
  127. package/dist/interfaces/binary-tree.d.ts +6 -0
  128. package/dist/interfaces/bst.d.ts +6 -0
  129. package/dist/interfaces/directed-graph.d.ts +3 -0
  130. package/dist/interfaces/doubly-linked-list.d.ts +1 -0
  131. package/dist/interfaces/heap.d.ts +1 -0
  132. package/dist/interfaces/index.d.ts +15 -0
  133. package/dist/interfaces/navigator.d.ts +1 -0
  134. package/dist/interfaces/priority-queue.d.ts +1 -0
  135. package/dist/interfaces/rb-tree.d.ts +6 -0
  136. package/dist/interfaces/segment-tree.d.ts +1 -0
  137. package/dist/interfaces/singly-linked-list.d.ts +1 -0
  138. package/dist/interfaces/tree-multiset.d.ts +6 -0
  139. package/dist/interfaces/undirected-graph.d.ts +3 -0
  140. package/dist/types/data-structures/abstract-binary-tree.d.ts +34 -0
  141. package/dist/types/data-structures/abstract-binary-tree.js +6 -0
  142. package/dist/types/data-structures/abstract-binary-tree.js.map +1 -1
  143. package/dist/types/data-structures/abstract-graph.d.ts +11 -0
  144. package/dist/types/data-structures/avl-tree.d.ts +4 -0
  145. package/dist/types/data-structures/binary-tree.d.ts +4 -0
  146. package/dist/types/data-structures/bst.d.ts +13 -0
  147. package/dist/types/data-structures/directed-graph.d.ts +6 -0
  148. package/dist/types/data-structures/doubly-linked-list.d.ts +1 -0
  149. package/dist/types/data-structures/hash.d.ts +1 -0
  150. package/dist/types/data-structures/heap.d.ts +1 -0
  151. package/dist/types/data-structures/index.d.ts +16 -0
  152. package/dist/types/data-structures/map-graph.d.ts +1 -0
  153. package/dist/types/data-structures/navigator.d.ts +14 -0
  154. package/dist/types/data-structures/priority-queue.d.ts +7 -0
  155. package/dist/types/data-structures/rb-tree.d.ts +8 -0
  156. package/dist/types/data-structures/segment-tree.d.ts +1 -0
  157. package/dist/types/data-structures/singly-linked-list.d.ts +1 -0
  158. package/dist/types/data-structures/tree-multiset.d.ts +4 -0
  159. package/dist/types/helpers.d.ts +1 -0
  160. package/dist/types/index.d.ts +3 -0
  161. package/dist/types/utils/index.d.ts +2 -0
  162. package/dist/types/utils/utils.d.ts +7 -0
  163. package/dist/types/utils/validate-type.d.ts +19 -0
  164. package/dist/utils/index.d.ts +1 -0
  165. package/dist/utils/utils.d.ts +19 -0
  166. package/lib/data-structures/graph/abstract-graph.js +3 -5
  167. package/lib/data-structures/heap/heap.d.ts +85 -68
  168. package/lib/data-structures/heap/heap.js +186 -108
  169. package/lib/data-structures/heap/max-heap.d.ts +6 -17
  170. package/lib/data-structures/heap/max-heap.js +11 -17
  171. package/lib/data-structures/heap/min-heap.d.ts +6 -18
  172. package/lib/data-structures/heap/min-heap.js +11 -18
  173. package/lib/data-structures/priority-queue/max-priority-queue.d.ts +5 -8
  174. package/lib/data-structures/priority-queue/max-priority-queue.js +11 -30
  175. package/lib/data-structures/priority-queue/min-priority-queue.d.ts +5 -8
  176. package/lib/data-structures/priority-queue/min-priority-queue.js +11 -31
  177. package/lib/data-structures/priority-queue/priority-queue.d.ts +6 -174
  178. package/lib/data-structures/priority-queue/priority-queue.js +11 -315
  179. package/lib/types/data-structures/heap.d.ts +1 -3
  180. package/package.json +11 -7
  181. package/src/data-structures/graph/abstract-graph.ts +3 -5
  182. package/src/data-structures/heap/heap.ts +182 -140
  183. package/src/data-structures/heap/max-heap.ts +15 -22
  184. package/src/data-structures/heap/min-heap.ts +15 -23
  185. package/src/data-structures/priority-queue/max-priority-queue.ts +14 -47
  186. package/src/data-structures/priority-queue/min-priority-queue.ts +14 -48
  187. package/src/data-structures/priority-queue/priority-queue.ts +7 -350
  188. package/src/types/data-structures/heap.ts +1 -5
  189. package/test/integration/avl-tree.test.ts +4 -4
  190. package/test/integration/bst.test.ts +8 -8
  191. package/test/unit/data-structures/graph/directed-graph.test.ts +5 -5
  192. package/test/unit/data-structures/graph/overall.test.ts +2 -2
  193. package/test/unit/data-structures/heap/heap.test.ts +26 -18
  194. package/test/unit/data-structures/heap/max-heap.test.ts +50 -42
  195. package/test/unit/data-structures/heap/min-heap.test.ts +38 -68
  196. package/test/unit/data-structures/linked-list/singly-linked-list.test.ts +1 -1
  197. package/test/unit/data-structures/priority-queue/max-priority-queue.test.ts +7 -9
  198. package/test/unit/data-structures/priority-queue/priority-queue.test.ts +14 -30
  199. package/umd/bundle.min.js +1 -1
  200. package/umd/bundle.min.js.LICENSE.txt +8 -0
  201. package/umd/bundle.min.js.map +1 -1
  202. package/test/unit/data-structures/graph/index.ts +0 -2
  203. package/test/unit/data-structures/linked-list/index.ts +0 -4
@@ -1,359 +1,16 @@
1
1
  /**
2
2
  * data-structure-typed
3
3
  *
4
- * @author Tyler Zeng
5
- * @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
4
+ * @author Kirk Qi
5
+ * @copyright Copyright (c) 2022 Kirk Qi <qilinaus@gmail.com>
6
6
  * @license MIT License
7
7
  */
8
- import type {PriorityQueueComparator, PriorityQueueDFSOrderPattern, PriorityQueueOptions} from '../../types';
9
8
 
10
- export class PriorityQueue<E = any> {
11
- /**
12
- * The constructor initializes a priority queue with the given options, including an array of nodes and a comparator
13
- * function.
14
- * @param options - The `options` parameter is an object that contains the following properties:
15
- */
16
- constructor(options: PriorityQueueOptions<E>) {
17
- const {nodes, comparator, isFix = true} = options;
18
- this._comparator = comparator;
9
+ import {Heap} from '../heap';
10
+ import {CompareFunction} from '../../types';
19
11
 
20
- if (nodes && Array.isArray(nodes) && nodes.length > 0) {
21
- // TODO support distinct
22
- this._nodes = [...nodes];
23
- isFix && this._fix();
24
- }
12
+ export class PriorityQueue<T> extends Heap<T> {
13
+ constructor(comparator: CompareFunction<T>) {
14
+ super(comparator);
25
15
  }
26
-
27
- protected _nodes: E[] = [];
28
-
29
- get nodes(): E[] {
30
- return this._nodes;
31
- }
32
-
33
- get size(): number {
34
- return this.nodes.length;
35
- }
36
-
37
- /**
38
- * The `heapify` function creates a new PriorityQueue instance and fixes the heap property.
39
- * @param options - The "options" parameter is an object that contains the configuration options for the PriorityQueue.
40
- * It can include properties such as "comparator" which specifies the comparison function used to order the elements in
41
- * the priority queue, and "initialValues" which is an array of initial values to be added to the priority
42
- * @returns a new instance of the PriorityQueue class after performing the heapify operation on it.
43
- */
44
- static heapify<E>(options: PriorityQueueOptions<E>) {
45
- const heap = new PriorityQueue(options);
46
- heap._fix();
47
- return heap;
48
- }
49
-
50
- /**
51
- * The function checks if a priority queue is valid by creating a new priority queue with a fix option and then calling
52
- * the isValid method.
53
- * @param options - An object containing options for creating a priority queue. The options object should have the
54
- * following properties:
55
- * @returns the result of calling the `isValid()` method on a new instance of the `PriorityQueue` class.
56
- */
57
- static isPriorityQueueified<E>(options: Omit<PriorityQueueOptions<E>, 'isFix'>) {
58
- return new PriorityQueue({...options, isFix: false}).isValid();
59
- }
60
-
61
- /**
62
- * Starting from TypeScript version 5.0 and onwards, the use of distinct access modifiers for Getters and Setters is not permitted. As an alternative, to ensure compatibility, it is necessary to adopt a Java-style approach for Setters (using the same name as the property) while utilizing separate method names for Getters.
63
- */
64
- getNodes(): E[] {
65
- return this._nodes;
66
- }
67
-
68
- /**
69
- * The "add" function adds a node to the heap and ensures that the heap property is maintained.
70
- * @param {E} node - The parameter "node" is of type E, which means it can be any data type. It represents the node
71
- * that needs to be added to the heap.
72
- */
73
- add(node: E) {
74
- this.nodes.push(node);
75
- this._heapifyUp(this.size - 1);
76
- }
77
-
78
- /**
79
- * The "has" function checks if a given node is present in the list of nodes.
80
- * @param {E} node - The parameter `node` is of type `E`, which means it can be any type. It represents the node that
81
- * we want to check if it exists in the `nodes` array.
82
- * @returns a boolean value indicating whether the given node is included in the array of nodes.
83
- */
84
- has(node: E): boolean {
85
- return this.nodes.includes(node);
86
- }
87
-
88
- /**
89
- * The `peek` function returns the first element of the `nodes` array if it exists, otherwise it returns `null`.
90
- * @returns The `peek()` function is returning the first element (`E`) of the `nodes` array if the `size` is not zero.
91
- * Otherwise, it returns `null`.
92
- */
93
- peek(): E | null {
94
- return this.size ? this.nodes[0] : null;
95
- }
96
-
97
- /**
98
- * The `poll` function removes and returns the top element from a heap data structure.
99
- * @returns The `poll()` method returns a value of type `E` or `null`.
100
- */
101
- poll(): E | null {
102
- let res: E | null = null;
103
- if (this.size > 1) {
104
- this._swap(0, this.nodes.length - 1);
105
- res = this.nodes.pop() ?? null;
106
- this._heapifyDown(0);
107
- } else if (this.size === 1) {
108
- res = this.nodes.pop() ?? null;
109
- }
110
- return res;
111
- }
112
-
113
- /**
114
- * The `leaf` function returns the last element in the `nodes` array or `null` if the array is empty.
115
- * @returns The method `leaf()` is returning the last element (`E`) in the `nodes` array if it exists. If the array is
116
- * empty or the last element is `null`, then it returns `null`.
117
- */
118
- leaf(): E | null {
119
- return this.nodes[this.size - 1] ?? null;
120
- }
121
-
122
- /**
123
- * The function checks if the size of an object is equal to zero and returns a boolean value indicating whether the
124
- * object is empty or not.
125
- * @returns The method `isEmpty()` is returning a boolean value indicating whether the size of the object is equal to
126
- * 0.
127
- */
128
- isEmpty() {
129
- return this.size === 0;
130
- }
131
-
132
- /**
133
- * The clear function clears the nodes array.
134
- */
135
- clear() {
136
- this._setNodes([]);
137
- }
138
-
139
- /**
140
- * The toArray function returns an array containing all the elements in the nodes property.
141
- * @returns An array of type E, which is the elements of the nodes property.
142
- */
143
- toArray(): E[] {
144
- return [...this.nodes];
145
- }
146
-
147
- /**
148
- * The `clone` function returns a new instance of the `PriorityQueue` class with the same nodes and comparator as the
149
- * original instance.
150
- * @returns The `clone()` method is returning a new instance of the `PriorityQueue` class with the same `nodes` and
151
- * `comparator` properties as the original instance.
152
- */
153
- clone(): PriorityQueue<E> {
154
- return new PriorityQueue<E>({
155
- nodes: this.nodes,
156
- comparator: this._comparator
157
- });
158
- }
159
-
160
- // --- start additional methods ---
161
- /**
162
- * The `isValid` function recursively checks if a binary tree satisfies a certain condition.
163
- * @returns The function `isValid()` returns a boolean value.
164
- */
165
- isValid(): boolean {
166
- for (let i = 0; i < this.nodes.length; i++) {
167
- const leftChildIndex = this._getLeft(i);
168
- const rightChildIndex = this._getRight(i);
169
- if (this._isValidIndex(leftChildIndex) && !this._compare(leftChildIndex, i)) {
170
- return false;
171
- }
172
- if (this._isValidIndex(rightChildIndex) && !this._compare(rightChildIndex, i)) {
173
- return false;
174
- }
175
- }
176
- return true;
177
- }
178
-
179
- /**
180
- * O(n log n), In scenarios with smaller data sizes, heap sort is generally expected to be slower than QuickSort or MergeSort.
181
- */
182
-
183
- /**
184
- * The function sorts the elements in a data structure and returns them in an array.
185
- * Plan to support sorting of duplicate elements.
186
- * @returns The `sort()` method is returning an array of type `E[]`.
187
- */
188
- sort(): E[] {
189
- const visitedNode: E[] = [];
190
- while (this.size !== 0) {
191
- const top = this.poll();
192
- if (top) visitedNode.push(top);
193
- }
194
- return visitedNode;
195
- }
196
-
197
- /**
198
- * The dfs function performs a depth-first search traversal on a binary tree and returns an array of visited nodes
199
- * based on the specified traversal order.
200
- * @param {PriorityQueueDFSOrderPattern} dfsMode - The dfsMode parameter is a string that specifies the order in which
201
- * the nodes should be visited during the Depth-First Search (dfs) traversal. It can have one of the following values:
202
- * @returns an array of type `(E | null)[]`.
203
- */
204
- dfs(dfsMode: PriorityQueueDFSOrderPattern): (E | null)[] {
205
- const visitedNode: (E | null)[] = [];
206
-
207
- const traverse = (cur: number) => {
208
- const leftChildIndex = this._getLeft(cur);
209
- const rightChildIndex = this._getRight(cur);
210
- switch (dfsMode) {
211
- case 'in':
212
- this._isValidIndex(leftChildIndex) && traverse(leftChildIndex);
213
- visitedNode.push(this.nodes[cur] ?? null);
214
- this._isValidIndex(rightChildIndex) && traverse(rightChildIndex);
215
- break;
216
- case 'pre':
217
- visitedNode.push(this.nodes[cur] ?? null);
218
- this._isValidIndex(leftChildIndex) && traverse(leftChildIndex);
219
- this._isValidIndex(rightChildIndex) && traverse(rightChildIndex);
220
- break;
221
- case 'post':
222
- this._isValidIndex(leftChildIndex) && traverse(leftChildIndex);
223
- this._isValidIndex(rightChildIndex) && traverse(rightChildIndex);
224
- visitedNode.push(this.nodes[cur] ?? null);
225
- break;
226
- }
227
- };
228
-
229
- this._isValidIndex(0) && traverse(0);
230
- return visitedNode;
231
- }
232
-
233
- protected _setNodes(value: E[]) {
234
- this._nodes = value;
235
- }
236
-
237
- protected readonly _comparator: PriorityQueueComparator<E> = (a: E, b: E) => {
238
- const aKey = a as unknown as number,
239
- bKey = b as unknown as number;
240
- return aKey - bKey;
241
- };
242
-
243
- /**
244
- * The function compares two numbers using a custom comparator function.
245
- * @param {number} a - The parameter "a" is a number that represents the index of a node in an array.
246
- * @param {number} b - The parameter "b" is a number.
247
- * @returns the result of the comparison between the elements at indices `a` and `b` in the `nodes` array. The
248
- * comparison is done using the `_comparator` function, and if the result is greater than 0, `true` is returned,
249
- * indicating that the element at index `a` is greater than the element at index `b`.
250
- */
251
- protected _compare(a: number, b: number) {
252
- return this._comparator(this.nodes[a], this.nodes[b]) > 0;
253
- }
254
-
255
- /**
256
- * The function swaps two elements in an array.
257
- * @param {number} a - The parameter "a" is a number that represents the index of an element in an array.
258
- * @param {number} b - The parameter "b" is a number.
259
- */
260
- protected _swap(a: number, b: number) {
261
- const temp = this.nodes[a];
262
- this.nodes[a] = this.nodes[b];
263
- this.nodes[b] = temp;
264
- }
265
-
266
- /**
267
- * The function checks if a given index is valid within an array.
268
- * @param {number} index - The parameter "index" is of type number and represents the index value that needs to be
269
- * checked for validity.
270
- * @returns A boolean value indicating whether the given index is valid or not.
271
- */
272
- protected _isValidIndex(index: number): boolean {
273
- return index > -1 && index < this.nodes.length;
274
- }
275
-
276
- /**
277
- * The function returns the index of the parent node given the index of a child node in a binary tree.
278
- * @param {number} child - The "child" parameter is a number representing the index of a child node in a binary tree.
279
- * @returns the parent of the given child node.
280
- */
281
- protected _getParent(child: number): number {
282
- return Math.floor((child - 1) / 2);
283
- }
284
-
285
- /**
286
- * The function returns the index of the left child node in a binary tree given the index of its parent node.
287
- * @param {number} parent - The parameter "parent" is a number that represents the index of a node in a binary tree.
288
- * @returns the left child of a given parent node in a binary tree.
289
- */
290
- protected _getLeft(parent: number): number {
291
- return 2 * parent + 1;
292
- }
293
-
294
- /**
295
- * The function returns the index of the right child node in a binary tree given the index of its parent node.
296
- * @param {number} parent - The parameter "parent" is a number that represents the index of a node in a binary tree.
297
- * @returns the right child of a given parent node in a binary tree.
298
- */
299
- protected _getRight(parent: number): number {
300
- return 2 * parent + 2;
301
- }
302
-
303
- /**
304
- * The function returns the index of the smallest child node of a given parent node.
305
- * @param {number} parent - The parent parameter is a number that represents the index of the parent node in a binary
306
- * tree.
307
- * @returns the minimum value between the parent node and its left and right child nodes.
308
- */
309
- protected _getComparedChild(parent: number) {
310
- let min = parent;
311
- const left = this._getLeft(parent),
312
- right = this._getRight(parent);
313
-
314
- if (left < this.size && this._compare(min, left)) {
315
- min = left;
316
- }
317
- if (right < this.size && this._compare(min, right)) {
318
- min = right;
319
- }
320
- return min;
321
- }
322
-
323
- /**
324
- * The function `_heapifyUp` is used to maintain the heap property by moving an element up the heap until it is in the
325
- * correct position.
326
- * @param {number} start - The start parameter is the index of the element that needs to be moved up in the heap.
327
- */
328
- protected _heapifyUp(start: number) {
329
- while (start > 0 && this._compare(this._getParent(start), start)) {
330
- const parent = this._getParent(start);
331
- this._swap(start, parent);
332
- start = parent;
333
- }
334
- }
335
-
336
- /**
337
- * The function performs a heapify operation by comparing and swapping elements in a binary heap.
338
- * @param {number} start - The start parameter is the index of the element in the heap from where the heapifyDown
339
- * operation should start.
340
- */
341
- protected _heapifyDown(start: number) {
342
- let min = this._getComparedChild(start);
343
- while (this._compare(start, min)) {
344
- this._swap(min, start);
345
- start = min;
346
- min = this._getComparedChild(start);
347
- }
348
- }
349
-
350
- /**
351
- * The _fix function performs a heapify operation on the elements of the heap starting from the middle and moving
352
- * towards the root.
353
- */
354
- protected _fix() {
355
- for (let i = Math.floor(this.size / 2); i > -1; i--) this._heapifyDown(i);
356
- }
357
-
358
- // --- end additional methods ---
359
16
  }
@@ -1,5 +1 @@
1
- export type HeapOptions<T> = {
2
- priorityExtractor?: (element: T) => number;
3
- // TODO there is an idea that support chaining which is for conveniently using the data structure
4
- // isChaining? : boolean
5
- };
1
+ export type CompareFunction<T> = (a: T, b: T) => number;
@@ -31,12 +31,12 @@ describe('AVL Tree Test', () => {
31
31
  // node15 has type problem. After the uniform design, the generics of containers (DirectedGraph, BST) are based on the type of value. However, this design has a drawback: when I attempt to inherit from the Vertex or BSTNode classes, the types of the results obtained by all methods are those of the parent class.
32
32
  expect(node15?.val).toBe(15);
33
33
 
34
- const dfs = tree.DFS('in', 'node');
34
+ const dfs = tree.dfs('in', 'node');
35
35
  expect(dfs[0].key).toBe(1);
36
36
  expect(dfs[dfs.length - 1].key).toBe(16);
37
37
 
38
38
  tree.perfectlyBalance();
39
- const bfs = tree.BFS('node');
39
+ const bfs = tree.bfs('node');
40
40
  expect(tree.isPerfectlyBalanced()).toBe(true);
41
41
  expect(bfs[0].key).toBe(8);
42
42
  expect(bfs[bfs.length - 1].key).toBe(16);
@@ -95,12 +95,12 @@ describe('AVL Tree Test', () => {
95
95
  expect(tree.getHeight()).toBe(1);
96
96
 
97
97
  expect(tree.isAVLBalanced()).toBe(true);
98
- const lastBFSIds = tree.BFS();
98
+ const lastBFSIds = tree.bfs();
99
99
  expect(lastBFSIds[0]).toBe(12);
100
100
  expect(lastBFSIds[1]).toBe(2);
101
101
  expect(lastBFSIds[2]).toBe(16);
102
102
 
103
- const lastBFSNodes = tree.BFS('node');
103
+ const lastBFSNodes = tree.bfs('node');
104
104
  expect(lastBFSNodes[0].key).toBe(12);
105
105
  expect(lastBFSNodes[1].key).toBe(2);
106
106
  expect(lastBFSNodes[2].key).toBe(16);
@@ -44,14 +44,14 @@ describe('Individual package BST operations test', () => {
44
44
  const node11 = bst.get(11);
45
45
  expect(node11).toBeInstanceOf(BSTNode);
46
46
 
47
- const dfsInorderNodes = bst.DFS('in', 'node');
47
+ const dfsInorderNodes = bst.dfs('in', 'node');
48
48
  expect(dfsInorderNodes[0].key).toBe(1);
49
49
  expect(dfsInorderNodes[dfsInorderNodes.length - 1].key).toBe(16);
50
50
 
51
51
  bst.perfectlyBalance();
52
52
  expect(bst.isPerfectlyBalanced()).toBe(true);
53
53
 
54
- const bfsNodesAfterBalanced = bst.BFS('node');
54
+ const bfsNodesAfterBalanced = bst.bfs('node');
55
55
  expect(bfsNodesAfterBalanced[0].key).toBe(8);
56
56
  expect(bfsNodesAfterBalanced[bfsNodesAfterBalanced.length - 1].key).toBe(16);
57
57
 
@@ -169,12 +169,12 @@ describe('Individual package BST operations test', () => {
169
169
 
170
170
  expect(bst.isAVLBalanced()).toBe(false);
171
171
 
172
- const bfsIDs = bst.BFS();
172
+ const bfsIDs = bst.bfs();
173
173
  expect(bfsIDs[0]).toBe(2);
174
174
  expect(bfsIDs[1]).toBe(12);
175
175
  expect(bfsIDs[2]).toBe(16);
176
176
 
177
- const bfsNodes = bst.BFS('node');
177
+ const bfsNodes = bst.bfs('node');
178
178
  expect(bfsNodes[0].key).toBe(2);
179
179
  expect(bfsNodes[1].key).toBe(12);
180
180
  expect(bfsNodes[2].key).toBe(16);
@@ -242,14 +242,14 @@ describe('Individual package BST operations test', () => {
242
242
  const node11 = objBST.get(11);
243
243
  expect(node11).toBeInstanceOf(BSTNode);
244
244
 
245
- const dfsInorderNodes = objBST.DFS('in', 'node');
245
+ const dfsInorderNodes = objBST.dfs('in', 'node');
246
246
  expect(dfsInorderNodes[0].key).toBe(1);
247
247
  expect(dfsInorderNodes[dfsInorderNodes.length - 1].key).toBe(16);
248
248
 
249
249
  objBST.perfectlyBalance();
250
250
  expect(objBST.isPerfectlyBalanced()).toBe(true);
251
251
 
252
- const bfsNodesAfterBalanced = objBST.BFS('node');
252
+ const bfsNodesAfterBalanced = objBST.bfs('node');
253
253
  expect(bfsNodesAfterBalanced[0].key).toBe(8);
254
254
  expect(bfsNodesAfterBalanced[bfsNodesAfterBalanced.length - 1].key).toBe(16);
255
255
 
@@ -367,12 +367,12 @@ describe('Individual package BST operations test', () => {
367
367
 
368
368
  expect(objBST.isAVLBalanced()).toBe(false);
369
369
 
370
- const bfsIDs = objBST.BFS();
370
+ const bfsIDs = objBST.bfs();
371
371
  expect(bfsIDs[0]).toBe(2);
372
372
  expect(bfsIDs[1]).toBe(12);
373
373
  expect(bfsIDs[2]).toBe(16);
374
374
 
375
- const bfsNodes = objBST.BFS('node');
375
+ const bfsNodes = objBST.bfs('node');
376
376
  expect(bfsNodes[0].key).toBe(2);
377
377
  expect(bfsNodes[1].key).toBe(12);
378
378
  expect(bfsNodes[2].key).toBe(16);
@@ -1,4 +1,4 @@
1
- import {DirectedEdge, DirectedGraph, DirectedVertex, VertexId} from '../../../../src';
1
+ import {DirectedEdge, DirectedGraph, DirectedVertex, VertexKey} from '../../../../src';
2
2
 
3
3
  describe('DirectedGraph Operation Test', () => {
4
4
  let graph: DirectedGraph;
@@ -63,7 +63,7 @@ describe('DirectedGraph Operation Test', () => {
63
63
  });
64
64
 
65
65
  class MyVertex<V extends string> extends DirectedVertex<V> {
66
- constructor(key: VertexId, val?: V) {
66
+ constructor(key: VertexKey, val?: V) {
67
67
  super(key, val);
68
68
  this._data = val;
69
69
  }
@@ -80,7 +80,7 @@ class MyVertex<V extends string> extends DirectedVertex<V> {
80
80
  }
81
81
 
82
82
  class MyEdge<E extends string> extends DirectedEdge<E> {
83
- constructor(v1: VertexId, v2: VertexId, weight?: number, val?: E) {
83
+ constructor(v1: VertexKey, v2: VertexKey, weight?: number, val?: E) {
84
84
  super(v1, v2, weight, val);
85
85
  this._data = val;
86
86
  }
@@ -97,11 +97,11 @@ class MyEdge<E extends string> extends DirectedEdge<E> {
97
97
  }
98
98
 
99
99
  class MyDirectedGraph<V extends MyVertex<string>, E extends MyEdge<string>> extends DirectedGraph<V, E> {
100
- createVertex(key: VertexId, val: V['val']): V {
100
+ createVertex(key: VertexKey, val: V['val']): V {
101
101
  return new MyVertex(key, val) as V;
102
102
  }
103
103
 
104
- createEdge(src: VertexId, dest: VertexId, weight?: number, val?: E['val']): E {
104
+ createEdge(src: VertexKey, dest: VertexKey, weight?: number, val?: E['val']): E {
105
105
  return new MyEdge(src, dest, weight ?? 1, val) as E;
106
106
  }
107
107
  }
@@ -29,8 +29,8 @@ describe('Overall Graph Operation Test', () => {
29
29
  graph.addEdge('A', 'B');
30
30
  graph.addEdge('B', 'C');
31
31
 
32
- const topologicalOrderIds = graph.topologicalSort();
33
- expect(topologicalOrderIds).toEqual(['A', 'B', 'C']);
32
+ const topologicalOrderKeys = graph.topologicalSort();
33
+ expect(topologicalOrderKeys).toEqual(['A', 'B', 'C']);
34
34
  });
35
35
  it('Overall UndirectedGraph Operation Test', () => {
36
36
  const graph = new UndirectedGraph();
@@ -21,34 +21,42 @@ describe('Heap Operation Test', () => {
21
21
  });
22
22
 
23
23
  it('should object heap work well', function () {
24
- const minHeap = new MinHeap<{a: string}>();
25
- minHeap.add(1, {a: 'a1'});
26
- minHeap.add(6, {a: 'a6'});
27
- minHeap.add(2, {a: 'a2'});
28
- minHeap.add(0, {a: 'a0'});
24
+ const minHeap = new MinHeap<{a: string; key: number}>((a, b) => a.key - b.key);
25
+ minHeap.add({key: 1, a: 'a1'});
26
+ minHeap.add({key: 6, a: 'a6'});
27
+ minHeap.add({key: 2, a: 'a2'});
28
+ minHeap.add({key: 0, a: 'a0'});
29
29
 
30
- expect(minHeap.peek()).toEqual({a: 'a0'});
31
- expect(minHeap.toArray()).toEqual([{a: 'a0'}, {a: 'a1'}, {a: 'a2'}, {a: 'a6'}]);
30
+ expect(minHeap.peek()).toEqual({a: 'a0', key: 0});
31
+ console.log('---', minHeap.toArray());
32
+ expect(minHeap.toArray().map(item => ({a: item.a}))).toEqual([{a: 'a0'}, {a: 'a1'}, {a: 'a2'}, {a: 'a6'}]);
32
33
  let i = 0;
33
34
  const expectPolled = [{a: 'a0'}, {a: 'a1'}, {a: 'a2'}, {a: 'a6'}];
34
35
  while (minHeap.size > 0) {
35
- expect(minHeap.poll()).toEqual(expectPolled[i]);
36
+ expect({a: minHeap.poll()?.a}).toEqual(expectPolled[i]);
36
37
  i++;
37
38
  }
38
39
 
39
- const maxHeap = new MaxHeap<{a: string}>();
40
- maxHeap.add(1, {a: 'a1'});
41
- maxHeap.add(6, {a: 'a6'});
42
- maxHeap.add(5, {a: 'a5'});
43
- maxHeap.add(2, {a: 'a2'});
44
- maxHeap.add(0, {a: 'a0'});
45
- maxHeap.add(9, {a: 'a9'});
46
- expect(maxHeap.peek()).toEqual({a: 'a9'});
47
- expect(maxHeap.toArray()).toEqual([{a: 'a9'}, {a: 'a2'}, {a: 'a6'}, {a: 'a1'}, {a: 'a0'}, {a: 'a5'}]);
40
+ const maxHeap = new MaxHeap<{key: number; a: string}>((a, b) => b.key - a.key);
41
+ maxHeap.add({key: 1, a: 'a1'});
42
+ maxHeap.add({key: 6, a: 'a6'});
43
+ maxHeap.add({key: 5, a: 'a5'});
44
+ maxHeap.add({key: 2, a: 'a2'});
45
+ maxHeap.add({key: 0, a: 'a0'});
46
+ maxHeap.add({key: 9, a: 'a9'});
47
+ expect(maxHeap.peek()).toEqual({a: 'a9', key: 9});
48
+ expect(maxHeap.toArray().map(item => ({a: item.a}))).toEqual([
49
+ {a: 'a9'},
50
+ {a: 'a2'},
51
+ {a: 'a6'},
52
+ {a: 'a1'},
53
+ {a: 'a0'},
54
+ {a: 'a5'}
55
+ ]);
48
56
  const maxExpectPolled = [{a: 'a9'}, {a: 'a6'}, {a: 'a5'}, {a: 'a2'}, {a: 'a1'}, {a: 'a0'}];
49
57
  let maxI = 0;
50
58
  while (maxHeap.size > 0) {
51
- expect(maxHeap.poll()).toEqual(maxExpectPolled[maxI]);
59
+ expect({a: maxHeap.poll()?.a}).toEqual(maxExpectPolled[maxI]);
52
60
  maxI++;
53
61
  }
54
62
  });
@@ -1,44 +1,52 @@
1
- import {HeapItem, MaxHeap} from '../../../../src';
2
-
3
- describe('MaxHeap Operation Test', () => {
4
- it('should object Max Heap operations be proper', function () {
5
- const maxHeap = new MaxHeap<{keyA: string}>();
6
- const myObj1 = {keyA: 'a1'},
7
- myObj6 = {keyA: 'a6'},
8
- myObj5 = {keyA: 'a5'},
9
- myObj2 = {keyA: 'a2'},
10
- myObj0 = {keyA: 'a0'},
11
- myObj9 = {keyA: 'a9'};
12
- maxHeap.add(1, myObj1);
13
- expect(maxHeap.has(myObj1)).toBe(true);
14
- expect(maxHeap.has(myObj9)).toBe(false);
15
- maxHeap.add(6, myObj6);
16
- expect(maxHeap.has(myObj6)).toBe(true);
17
- maxHeap.add(5, myObj5);
18
- expect(maxHeap.has(myObj5)).toBe(true);
19
- maxHeap.add(2, myObj2);
20
- expect(maxHeap.has(myObj2)).toBe(true);
21
- expect(maxHeap.has(myObj6)).toBe(true);
22
- maxHeap.add(0, myObj0);
23
- expect(maxHeap.has(myObj0)).toBe(true);
24
- expect(maxHeap.has(myObj9)).toBe(false);
25
- maxHeap.add(9, myObj9);
26
- expect(maxHeap.has(myObj9)).toBe(true);
27
-
28
- const peek9 = maxHeap.peek(true);
29
- peek9 && peek9.val && expect(peek9.val.keyA).toBe('a9');
30
-
31
- const heapToArr = maxHeap.toArray(true);
32
- expect(heapToArr.map(item => item?.val?.keyA)).toEqual(['a9', 'a2', 'a6', 'a1', 'a0', 'a5']);
33
-
34
- const values = ['a9', 'a6', 'a5', 'a2', 'a1', 'a0'];
35
- let i = 0;
36
- while (maxHeap.size > 0) {
37
- const polled = maxHeap.poll(true);
38
- expect(polled).toBeInstanceOf(HeapItem);
39
- polled && expect(polled.val).toHaveProperty('keyA');
40
- polled && polled.val && expect(polled.val.keyA).toBe(values[i]);
41
- i++;
42
- }
1
+ import {CompareFunction, MaxHeap} from '../../../../src';
2
+
3
+ describe('MaxHeap', () => {
4
+ const numberComparator: CompareFunction<number> = (a, b) => b - a;
5
+ let maxHeap: MaxHeap<number>;
6
+
7
+ beforeEach(() => {
8
+ maxHeap = new MaxHeap(numberComparator);
9
+ });
10
+
11
+ test('add and poll elements in descending order', () => {
12
+ maxHeap.add(3);
13
+ maxHeap.add(1);
14
+ maxHeap.add(4);
15
+ maxHeap.add(2);
16
+
17
+ expect(maxHeap.poll()).toBe(4);
18
+ expect(maxHeap.poll()).toBe(3);
19
+ expect(maxHeap.poll()).toBe(2);
20
+ expect(maxHeap.poll()).toBe(1);
21
+ });
22
+
23
+ test('peek at the top element without removing it', () => {
24
+ maxHeap.add(3);
25
+ maxHeap.add(1);
26
+ maxHeap.add(4);
27
+ maxHeap.add(2);
28
+
29
+ expect(maxHeap.peek()).toBe(4);
30
+ expect(maxHeap.size).toBe(4);
31
+ });
32
+
33
+ test('sort elements in descending order', () => {
34
+ maxHeap.add(3);
35
+ maxHeap.add(1);
36
+ maxHeap.add(4);
37
+ maxHeap.add(2);
38
+
39
+ const sortedArray = maxHeap.sort();
40
+ expect(sortedArray).toEqual([4, 3, 2, 1]);
41
+ });
42
+
43
+ test('check if the heap is empty', () => {
44
+ expect(maxHeap.isEmpty()).toBe(true);
45
+
46
+ maxHeap.add(5);
47
+ expect(maxHeap.isEmpty()).toBe(false);
48
+
49
+ maxHeap.poll();
50
+ expect(maxHeap.isEmpty()).toBe(true);
43
51
  });
44
52
  });