data-structure-typed 0.9.16 → 1.3.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.
Files changed (264) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +665 -172
  3. package/dist/bundle.js +2 -0
  4. package/dist/bundle.js.LICENSE.txt +13 -0
  5. package/dist/data-structures/binary-tree/aa-tree.js +2 -5
  6. package/dist/data-structures/binary-tree/abstract-binary-tree.d.ts +364 -0
  7. package/dist/data-structures/binary-tree/abstract-binary-tree.js +1308 -0
  8. package/dist/data-structures/binary-tree/avl-tree.d.ts +85 -14
  9. package/dist/data-structures/binary-tree/avl-tree.js +142 -116
  10. package/dist/data-structures/binary-tree/b-tree.js +2 -5
  11. package/dist/data-structures/binary-tree/binary-indexed-tree.d.ts +39 -1
  12. package/dist/data-structures/binary-tree/binary-indexed-tree.js +54 -13
  13. package/dist/data-structures/binary-tree/binary-tree.d.ts +29 -126
  14. package/dist/data-structures/binary-tree/binary-tree.js +31 -1093
  15. package/dist/data-structures/binary-tree/bst.d.ts +117 -23
  16. package/dist/data-structures/binary-tree/bst.js +233 -240
  17. package/dist/data-structures/binary-tree/index.d.ts +1 -0
  18. package/dist/data-structures/binary-tree/index.js +1 -0
  19. package/dist/data-structures/binary-tree/rb-tree.d.ts +18 -1
  20. package/dist/data-structures/binary-tree/rb-tree.js +40 -5
  21. package/dist/data-structures/binary-tree/segment-tree.d.ts +61 -11
  22. package/dist/data-structures/binary-tree/segment-tree.js +126 -93
  23. package/dist/data-structures/binary-tree/splay-tree.js +2 -5
  24. package/dist/data-structures/binary-tree/tree-multiset.d.ts +213 -6
  25. package/dist/data-structures/binary-tree/tree-multiset.js +687 -34
  26. package/dist/data-structures/binary-tree/two-three-tree.js +2 -5
  27. package/dist/data-structures/graph/abstract-graph.d.ts +270 -36
  28. package/dist/data-structures/graph/abstract-graph.js +610 -572
  29. package/dist/data-structures/graph/directed-graph.d.ts +173 -16
  30. package/dist/data-structures/graph/directed-graph.js +345 -313
  31. package/dist/data-structures/graph/index.d.ts +1 -0
  32. package/dist/data-structures/graph/index.js +1 -0
  33. package/dist/data-structures/graph/map-graph.d.ts +79 -0
  34. package/dist/data-structures/graph/map-graph.js +111 -0
  35. package/dist/data-structures/graph/undirected-graph.d.ts +111 -9
  36. package/dist/data-structures/graph/undirected-graph.js +203 -178
  37. package/dist/data-structures/hash/coordinate-map.d.ts +38 -1
  38. package/dist/data-structures/hash/coordinate-map.js +59 -36
  39. package/dist/data-structures/hash/coordinate-set.d.ts +32 -2
  40. package/dist/data-structures/hash/coordinate-set.js +49 -33
  41. package/dist/data-structures/hash/hash-table.d.ts +2 -1
  42. package/dist/data-structures/hash/hash-table.js +4 -0
  43. package/dist/data-structures/hash/pair.d.ts +2 -1
  44. package/dist/data-structures/hash/pair.js +4 -0
  45. package/dist/data-structures/hash/tree-map.d.ts +2 -1
  46. package/dist/data-structures/hash/tree-map.js +4 -0
  47. package/dist/data-structures/hash/tree-set.d.ts +2 -1
  48. package/dist/data-structures/hash/tree-set.js +4 -0
  49. package/dist/data-structures/heap/heap.d.ts +62 -45
  50. package/dist/data-structures/heap/heap.js +124 -86
  51. package/dist/data-structures/heap/max-heap.d.ts +13 -5
  52. package/dist/data-structures/heap/max-heap.js +18 -28
  53. package/dist/data-structures/heap/min-heap.d.ts +14 -5
  54. package/dist/data-structures/heap/min-heap.js +19 -28
  55. package/dist/data-structures/index.d.ts +1 -1
  56. package/dist/data-structures/index.js +1 -1
  57. package/dist/data-structures/linked-list/doubly-linked-list.d.ts +193 -56
  58. package/dist/data-structures/linked-list/doubly-linked-list.js +484 -220
  59. package/dist/data-structures/linked-list/index.d.ts +1 -0
  60. package/dist/data-structures/linked-list/index.js +1 -0
  61. package/dist/data-structures/linked-list/singly-linked-list.d.ts +117 -315
  62. package/dist/data-structures/linked-list/singly-linked-list.js +374 -727
  63. package/dist/data-structures/linked-list/skip-linked-list.d.ts +2 -1
  64. package/dist/data-structures/linked-list/skip-linked-list.js +4 -0
  65. package/dist/data-structures/matrix/matrix.d.ts +12 -0
  66. package/dist/data-structures/matrix/matrix.js +21 -8
  67. package/dist/data-structures/matrix/matrix2d.d.ts +85 -2
  68. package/dist/data-structures/matrix/matrix2d.js +146 -80
  69. package/dist/data-structures/matrix/navigator.d.ts +36 -1
  70. package/dist/data-structures/matrix/navigator.js +46 -37
  71. package/dist/data-structures/matrix/vector2d.d.ts +142 -15
  72. package/dist/data-structures/matrix/vector2d.js +215 -109
  73. package/dist/data-structures/priority-queue/max-priority-queue.d.ts +12 -2
  74. package/dist/data-structures/priority-queue/max-priority-queue.js +33 -26
  75. package/dist/data-structures/priority-queue/min-priority-queue.d.ts +12 -2
  76. package/dist/data-structures/priority-queue/min-priority-queue.js +34 -26
  77. package/dist/data-structures/priority-queue/priority-queue.d.ts +153 -3
  78. package/dist/data-structures/priority-queue/priority-queue.js +244 -143
  79. package/dist/data-structures/queue/deque.d.ts +141 -13
  80. package/dist/data-structures/queue/deque.js +200 -82
  81. package/dist/data-structures/queue/queue.d.ts +65 -38
  82. package/dist/data-structures/queue/queue.js +110 -66
  83. package/dist/data-structures/stack/stack.d.ts +27 -32
  84. package/dist/data-structures/stack/stack.js +47 -53
  85. package/dist/data-structures/tree/index.d.ts +1 -0
  86. package/dist/data-structures/tree/index.js +17 -0
  87. package/dist/data-structures/tree/tree.d.ts +14 -0
  88. package/dist/data-structures/tree/tree.js +60 -0
  89. package/dist/data-structures/trie/trie.d.ts +33 -10
  90. package/dist/data-structures/trie/trie.js +123 -208
  91. package/dist/index.d.ts +3 -0
  92. package/dist/index.js +3 -0
  93. package/dist/interfaces/abstract-binary-tree.d.ts +90 -0
  94. package/dist/interfaces/abstract-graph.d.ts +17 -0
  95. package/dist/interfaces/avl-tree.d.ts +9 -0
  96. package/dist/interfaces/binary-tree.d.ts +6 -0
  97. package/dist/interfaces/bst.d.ts +17 -0
  98. package/dist/interfaces/directed-graph.d.ts +12 -0
  99. package/{src/data-structures/types/index.ts → dist/interfaces/index.d.ts} +10 -8
  100. package/dist/interfaces/index.js +31 -0
  101. package/{src/data-structures/hash/hash-table.ts → dist/interfaces/priority-queue.d.ts} +1 -1
  102. package/dist/interfaces/rb-tree.d.ts +8 -0
  103. package/dist/interfaces/segment-tree.d.ts +1 -0
  104. package/dist/interfaces/singly-linked-list.d.ts +1 -0
  105. package/dist/interfaces/singly-linked-list.js +2 -0
  106. package/dist/interfaces/tree-multiset.d.ts +7 -0
  107. package/dist/interfaces/tree-multiset.js +2 -0
  108. package/dist/interfaces/undirected-graph.d.ts +5 -0
  109. package/dist/interfaces/undirected-graph.js +2 -0
  110. package/dist/types/data-structures/abstract-binary-tree.d.ts +34 -0
  111. package/dist/types/data-structures/abstract-binary-tree.js +25 -0
  112. package/dist/types/data-structures/abstract-graph.d.ts +11 -0
  113. package/dist/types/data-structures/abstract-graph.js +2 -0
  114. package/dist/types/data-structures/avl-tree.d.ts +4 -0
  115. package/dist/types/data-structures/avl-tree.js +2 -0
  116. package/dist/types/data-structures/binary-tree.d.ts +4 -0
  117. package/dist/types/data-structures/binary-tree.js +2 -0
  118. package/dist/types/data-structures/bst.d.ts +13 -0
  119. package/dist/types/data-structures/bst.js +9 -0
  120. package/dist/types/data-structures/directed-graph.d.ts +6 -0
  121. package/dist/types/data-structures/directed-graph.js +9 -0
  122. package/dist/types/data-structures/doubly-linked-list.d.ts +1 -0
  123. package/dist/types/data-structures/doubly-linked-list.js +2 -0
  124. package/dist/types/data-structures/heap.d.ts +3 -0
  125. package/dist/types/data-structures/heap.js +2 -0
  126. package/dist/{data-structures/types → types/data-structures}/index.d.ts +3 -1
  127. package/dist/{data-structures/types → types/data-structures}/index.js +3 -1
  128. package/dist/types/data-structures/map-graph.d.ts +1 -0
  129. package/dist/types/data-structures/map-graph.js +2 -0
  130. package/dist/{data-structures/types → types/data-structures}/navigator.d.ts +2 -2
  131. package/dist/types/data-structures/navigator.js +2 -0
  132. package/dist/{data-structures/types → types/data-structures}/priority-queue.d.ts +2 -2
  133. package/dist/types/data-structures/priority-queue.js +2 -0
  134. package/dist/types/data-structures/rb-tree.d.ts +8 -0
  135. package/dist/types/data-structures/rb-tree.js +8 -0
  136. package/dist/types/data-structures/segment-tree.js +2 -0
  137. package/dist/types/data-structures/singly-linked-list.d.ts +1 -0
  138. package/dist/types/data-structures/singly-linked-list.js +2 -0
  139. package/dist/types/data-structures/tree-multiset.d.ts +4 -0
  140. package/dist/types/data-structures/tree-multiset.js +2 -0
  141. package/dist/types/helpers.d.ts +1 -0
  142. package/dist/types/helpers.js +2 -0
  143. package/dist/types/index.d.ts +3 -0
  144. package/dist/types/index.js +19 -0
  145. package/dist/types/utils/index.d.ts +2 -0
  146. package/dist/types/utils/index.js +18 -0
  147. package/dist/types/utils/utils.d.ts +7 -0
  148. package/dist/types/utils/utils.js +2 -0
  149. package/dist/types/utils/validate-type.d.ts +19 -0
  150. package/dist/types/utils/validate-type.js +2 -0
  151. package/dist/utils/utils.d.ts +17 -103
  152. package/dist/utils/utils.js +40 -625
  153. package/package.json +134 -23
  154. package/.idea/data-structure-typed.iml +0 -12
  155. package/.idea/modules.xml +0 -8
  156. package/.idea/vcs.xml +0 -6
  157. package/dist/data-structures/trampoline.d.ts +0 -16
  158. package/dist/data-structures/trampoline.js +0 -130
  159. package/dist/data-structures/types/abstract-graph.d.ts +0 -29
  160. package/dist/data-structures/types/avl-tree.d.ts +0 -5
  161. package/dist/data-structures/types/binary-tree.d.ts +0 -16
  162. package/dist/data-structures/types/bst.d.ts +0 -7
  163. package/dist/data-structures/types/directed-graph.d.ts +0 -10
  164. package/dist/data-structures/types/doubly-linked-list.d.ts +0 -1
  165. package/dist/data-structures/types/heap.d.ts +0 -7
  166. package/dist/data-structures/types/singly-linked-list.d.ts +0 -5
  167. package/dist/data-structures/types/tree-multiset.d.ts +0 -5
  168. package/dist/data-structures/types/utils.d.ts +0 -52
  169. package/dist/data-structures/types/utils.js +0 -54
  170. package/src/data-structures/binary-tree/aa-tree.ts +0 -3
  171. package/src/data-structures/binary-tree/avl-tree.ts +0 -227
  172. package/src/data-structures/binary-tree/b-tree.ts +0 -3
  173. package/src/data-structures/binary-tree/binary-indexed-tree.ts +0 -33
  174. package/src/data-structures/binary-tree/binary-tree.ts +0 -1133
  175. package/src/data-structures/binary-tree/bst.ts +0 -395
  176. package/src/data-structures/binary-tree/diagrams/avl-tree-inserting.gif +0 -0
  177. package/src/data-structures/binary-tree/diagrams/bst-rotation.gif +0 -0
  178. package/src/data-structures/binary-tree/diagrams/segment-tree.png +0 -0
  179. package/src/data-structures/binary-tree/index.ts +0 -11
  180. package/src/data-structures/binary-tree/rb-tree.ts +0 -3
  181. package/src/data-structures/binary-tree/segment-tree.ts +0 -172
  182. package/src/data-structures/binary-tree/splay-tree.ts +0 -3
  183. package/src/data-structures/binary-tree/tree-multiset.ts +0 -18
  184. package/src/data-structures/binary-tree/two-three-tree.ts +0 -3
  185. package/src/data-structures/diagrams/README.md +0 -7
  186. package/src/data-structures/graph/abstract-graph.ts +0 -753
  187. package/src/data-structures/graph/diagrams/adjacency-list-pros-cons.png +0 -0
  188. package/src/data-structures/graph/diagrams/adjacency-list.png +0 -0
  189. package/src/data-structures/graph/diagrams/adjacency-matrix-pros-cons.png +0 -0
  190. package/src/data-structures/graph/diagrams/adjacency-matrix.png +0 -0
  191. package/src/data-structures/graph/diagrams/dfs-can-do.png +0 -0
  192. package/src/data-structures/graph/diagrams/edge-list-pros-cons.png +0 -0
  193. package/src/data-structures/graph/diagrams/edge-list.png +0 -0
  194. package/src/data-structures/graph/diagrams/max-flow.png +0 -0
  195. package/src/data-structures/graph/diagrams/mst.png +0 -0
  196. package/src/data-structures/graph/diagrams/tarjan-articulation-point-bridge.png +0 -0
  197. package/src/data-structures/graph/diagrams/tarjan-complicate-simple.png +0 -0
  198. package/src/data-structures/graph/diagrams/tarjan-strongly-connected-component.png +0 -0
  199. package/src/data-structures/graph/diagrams/tarjan.mp4 +0 -0
  200. package/src/data-structures/graph/directed-graph.ts +0 -306
  201. package/src/data-structures/graph/index.ts +0 -3
  202. package/src/data-structures/graph/undirected-graph.ts +0 -155
  203. package/src/data-structures/hash/coordinate-map.ts +0 -24
  204. package/src/data-structures/hash/coordinate-set.ts +0 -20
  205. package/src/data-structures/hash/index.ts +0 -6
  206. package/src/data-structures/heap/heap.ts +0 -127
  207. package/src/data-structures/heap/index.ts +0 -3
  208. package/src/data-structures/heap/max-heap.ts +0 -23
  209. package/src/data-structures/heap/min-heap.ts +0 -25
  210. package/src/data-structures/index.ts +0 -12
  211. package/src/data-structures/linked-list/doubly-linked-list.ts +0 -250
  212. package/src/data-structures/linked-list/index.ts +0 -2
  213. package/src/data-structures/linked-list/singly-linked-list.ts +0 -736
  214. package/src/data-structures/linked-list/skip-linked-list.ts +0 -1
  215. package/src/data-structures/matrix/index.ts +0 -4
  216. package/src/data-structures/matrix/matrix.ts +0 -13
  217. package/src/data-structures/matrix/matrix2d.ts +0 -125
  218. package/src/data-structures/matrix/navigator.ts +0 -87
  219. package/src/data-structures/matrix/vector2d.ts +0 -189
  220. package/src/data-structures/priority-queue/index.ts +0 -3
  221. package/src/data-structures/priority-queue/max-priority-queue.ts +0 -13
  222. package/src/data-structures/priority-queue/min-priority-queue.ts +0 -13
  223. package/src/data-structures/priority-queue/priority-queue.ts +0 -200
  224. package/src/data-structures/queue/deque.ts +0 -139
  225. package/src/data-structures/queue/index.ts +0 -2
  226. package/src/data-structures/queue/queue.ts +0 -122
  227. package/src/data-structures/stack/index.ts +0 -1
  228. package/src/data-structures/stack/stack.ts +0 -103
  229. package/src/data-structures/trampoline.ts +0 -51
  230. package/src/data-structures/trie/index.ts +0 -1
  231. package/src/data-structures/trie/trie.ts +0 -203
  232. package/src/data-structures/types/abstract-graph.ts +0 -51
  233. package/src/data-structures/types/avl-tree.ts +0 -6
  234. package/src/data-structures/types/binary-tree.ts +0 -15
  235. package/src/data-structures/types/bst.ts +0 -5
  236. package/src/data-structures/types/directed-graph.ts +0 -18
  237. package/src/data-structures/types/doubly-linked-list.ts +0 -1
  238. package/src/data-structures/types/heap.ts +0 -8
  239. package/src/data-structures/types/navigator.ts +0 -12
  240. package/src/data-structures/types/priority-queue.ts +0 -9
  241. package/src/data-structures/types/segment-tree.ts +0 -1
  242. package/src/data-structures/types/singly-linked-list.ts +0 -15
  243. package/src/data-structures/types/tree-multiset.ts +0 -3
  244. package/src/data-structures/types/utils.ts +0 -173
  245. package/src/index.ts +0 -1
  246. package/src/utils/index.ts +0 -1
  247. package/src/utils/utils.ts +0 -505
  248. package/tsconfig.json +0 -56
  249. /package/dist/{data-structures/types/abstract-graph.js → interfaces/abstract-binary-tree.js} +0 -0
  250. /package/dist/{data-structures/types/avl-tree.js → interfaces/abstract-graph.js} +0 -0
  251. /package/dist/{data-structures/types/binary-tree.js → interfaces/avl-tree.js} +0 -0
  252. /package/dist/{data-structures/types/bst.js → interfaces/binary-tree.js} +0 -0
  253. /package/dist/{data-structures/types/directed-graph.js → interfaces/bst.js} +0 -0
  254. /package/dist/{data-structures/types/doubly-linked-list.js → interfaces/directed-graph.js} +0 -0
  255. /package/{src/data-structures/hash/pair.ts → dist/interfaces/doubly-linked-list.d.ts} +0 -0
  256. /package/dist/{data-structures/types/heap.js → interfaces/doubly-linked-list.js} +0 -0
  257. /package/{src/data-structures/hash/tree-map.ts → dist/interfaces/heap.d.ts} +0 -0
  258. /package/dist/{data-structures/types/navigator.js → interfaces/heap.js} +0 -0
  259. /package/{src/data-structures/hash/tree-set.ts → dist/interfaces/navigator.d.ts} +0 -0
  260. /package/dist/{data-structures/types/priority-queue.js → interfaces/navigator.js} +0 -0
  261. /package/dist/{data-structures/types/segment-tree.js → interfaces/priority-queue.js} +0 -0
  262. /package/dist/{data-structures/types/singly-linked-list.js → interfaces/rb-tree.js} +0 -0
  263. /package/dist/{data-structures/types/tree-multiset.js → interfaces/segment-tree.js} +0 -0
  264. /package/dist/{data-structures/types → types/data-structures}/segment-tree.d.ts +0 -0
@@ -1,736 +0,0 @@
1
- import type {TMapFunction, TTestFunction} from '../types';
2
-
3
- /**
4
- * The class which represents one link or node in a linked list
5
- * ```ts
6
- * const node = new SinglyLinkedListNode(1, null, null, null);
7
- * ```
8
- */
9
- export class SinglyLinkedListNode<NodeData = any> {
10
- constructor(
11
- /** Data stored on the node */
12
- public val: NodeData,
13
- /** The previous node in the list */
14
- public prev: SinglyLinkedListNode<NodeData> | null,
15
- /** The next link in the list */
16
- public next: SinglyLinkedListNode<NodeData> | null,
17
- /** The list this node belongs to */
18
- public list: SinglyLinkedList<NodeData> | null,
19
- ) {
20
- }
21
-
22
- /**
23
- * Alias to .val
24
- * ```ts
25
- * new LinkedList(1, 2, 3).head.value; // 1
26
- * ```
27
- */
28
- public get value() {
29
- return this.val;
30
- }
31
-
32
- /**
33
- * Get the index of this node
34
- * ```ts
35
- * new LinkedList(1, 2, 3).head.index; // 0
36
- * ```
37
- */
38
- public get index() {
39
- if (!this.list) {
40
- return undefined;
41
- }
42
- return this.list.findIndex((value) => value === this.value);
43
- }
44
-
45
- /**
46
- * Insert a new node before this one
47
- * ```ts
48
- * new LinkedList(2, 3).head.insertBefore(1); // 1 <=> 2 <=> 3
49
- * ```
50
- * @param val Data to save in the node
51
- */
52
- public insertBefore(val: NodeData): SinglyLinkedList<NodeData> {
53
- return this.list !== null
54
- ? this.list.insertBefore(this, val)
55
- : new SinglyLinkedList(val, this.val);
56
- }
57
-
58
- /**
59
- * Insert new val after this node
60
- * ```ts
61
- * new LinkedList(1, 2).tail.insertAfter(3); // 1 <=> 2 <=> 3
62
- * ```
63
- * @param val Data to be saved in the node
64
- */
65
- public insertAfter(val: NodeData): SinglyLinkedList<NodeData> {
66
- return this.list !== null
67
- ? this.list.insertAfter(this, val)
68
- : new SinglyLinkedList(this.val, val);
69
- }
70
-
71
- /**
72
- * Remove this node
73
- * ```ts
74
- * new LinkedList(1, 2, 3, 4).tail.remove(); // 1 <=> 2 <=> 3
75
- * ```
76
- */
77
- public remove(): SinglyLinkedListNode<NodeData> {
78
- if (this.list === null) {
79
- throw new ReferenceError('Node does not belong to any list');
80
- }
81
- return this.list.removeNode(this);
82
- }
83
- }
84
-
85
-
86
- /**
87
- * A doubly linked list
88
- * ```ts
89
- * const list = new LinkedList(1, 2, 3);
90
- * const listFromArray = LinkedList.from([1, 2, 3]);
91
- * ```
92
- */
93
- export class SinglyLinkedList<NodeData = any> {
94
-
95
- /** The head of the list, the first node */
96
- public head: SinglyLinkedListNode<NodeData> | null;
97
- /** The tail of the list, the last node */
98
- public tail: SinglyLinkedListNode<NodeData> | null;
99
- /** Internal size reference */
100
- private size: number;
101
-
102
- constructor(...args: NodeData[]) {
103
- this.head = null;
104
- this.tail = null;
105
- this.size = 0;
106
-
107
- for (let i = 0; i < arguments.length; i++) {
108
- this.append(args[i]);
109
- }
110
- }
111
-
112
- /**
113
- * The length of the list
114
- */
115
- public get length(): number {
116
- return this.size;
117
- }
118
-
119
- /**
120
- * Convert any iterable to a new linked list
121
- * ```javascript
122
- * const array = [1, 2, 3];
123
- * const list = LinkedList.from(array);
124
- * ```
125
- * @param iterable Any iterable datatype like Array or Map
126
- */
127
- public static from<T>(iterable: Iterable<T>): SinglyLinkedList<T> {
128
- return new SinglyLinkedList(...iterable);
129
- }
130
-
131
- /**
132
- * Get the node val at a specified index, zero based
133
- * ```ts
134
- * new LinkedList(1, 2, 3).get(0); // 1
135
- * ```
136
- * @param index to retrieve val at
137
- */
138
- public get(index: number): NodeData | undefined {
139
- const node = this.getNode(index);
140
- return node !== undefined ? node.val : undefined;
141
- }
142
-
143
- /**
144
- * Get the node at index, zero based
145
- * ```ts
146
- * new LinkedList(1, 2, 3).getNode(0);
147
- * // { prev: null, val: 1, next: SinglyLinkedListNode }
148
- * ```
149
- */
150
- public getNode(index: number): SinglyLinkedListNode<NodeData> | undefined {
151
- if (this.head === null || index < 0 || index >= this.length) {
152
- return undefined;
153
- }
154
- const asc = index < this.length / 2;
155
- const stopAt = asc ? index : this.length - index - 1;
156
- const nextNode = asc ? 'next' : 'prev';
157
- let currentNode = asc ? this.head : this.tail;
158
- // TODO after no-non-null-assertion not ensure the logic
159
- for (let currentIndex = 0; currentIndex < stopAt; currentIndex++) {
160
- if (currentNode) {
161
- currentNode = currentNode[nextNode];
162
- }
163
- }
164
- return currentNode || undefined;
165
- }
166
-
167
- /**
168
- * Return the first node and its index in the list that
169
- * satisfies the testing function
170
- * ```ts
171
- * new LinkedList(1, 2, 3).findNodeIndex(val => val === 1);
172
- * // { node: SinglyLinkedListNode, index: 0 }
173
- * ```
174
- * @param f A function to be applied to the val of each node
175
- */
176
- public findNodeIndex(f: TTestFunction<NodeData>): ({
177
- node: SinglyLinkedListNode<NodeData>,
178
- index: number,
179
- }) | undefined {
180
- let currentIndex = 0;
181
- let currentNode = this.head;
182
- while (currentNode) {
183
- if (f(currentNode.val, currentIndex, this)) {
184
- return {
185
- index: currentIndex,
186
- node: currentNode,
187
- };
188
- }
189
- currentNode = currentNode.next;
190
- currentIndex += 1;
191
- }
192
- return undefined;
193
- }
194
-
195
- /**
196
- * Returns the first node in the list that
197
- * satisfies the provided testing function. Otherwise undefined is returned.
198
- * ```ts
199
- * new LinkedList(1, 2, 3).findNode(val => val === 1);
200
- * // { prev: null, val: 1, next: SinglyLinkedListNode }
201
- * ```
202
- * @param f Function to test val against
203
- */
204
- public findNode(f: TTestFunction<NodeData>): SinglyLinkedListNode<NodeData> | undefined {
205
- const nodeIndex = this.findNodeIndex(f);
206
- return nodeIndex !== undefined ? nodeIndex.node : undefined;
207
- }
208
-
209
- /**
210
- * Returns the value of the first element in the list that
211
- * satisfies the provided testing function. Otherwise undefined is returned.
212
- * ```ts
213
- * new LinkedList(1, 2, 3).find(val => val === 1); // 1
214
- * ```
215
- * @param f Function to test val against
216
- */
217
- public find(f: TTestFunction<NodeData>): NodeData | undefined {
218
- const nodeIndex = this.findNodeIndex(f);
219
- return nodeIndex !== undefined ? nodeIndex.node.val : undefined;
220
- }
221
-
222
- /**
223
- * Returns the index of the first node in the list that
224
- * satisfies the provided testing function. Ohterwise -1 is returned.
225
- * ```ts
226
- * new LinkedList(1, 2, 3).findIndex(val => val === 3); // 2
227
- * ```
228
- * @param f Function to test val against
229
- */
230
- public findIndex(f: TTestFunction<NodeData>): number {
231
- const nodeIndex = this.findNodeIndex(f);
232
- return nodeIndex !== undefined ? nodeIndex.index : -1;
233
- }
234
-
235
- /**
236
- * Append one or any number of nodes to the end of the list.
237
- * This modifies the list in place and returns the list itself
238
- * to make this method chainable.
239
- * ```ts
240
- * new LinkedList(1).append(2).append(3, 4); // 1 <=> 2 <=> 3 <=> 4
241
- * ```
242
- * @param args Data to be stored in the node, takes any number of arguments
243
- */
244
- public append(...args: NodeData[]): SinglyLinkedList<NodeData> {
245
- for (const val of args) {
246
- const node = new SinglyLinkedListNode(val, this.tail, null, this);
247
- if (this.head === null) {
248
- this.head = node;
249
- }
250
- if (this.tail !== null) {
251
- this.tail.next = node;
252
- }
253
- this.tail = node;
254
- this.size += 1;
255
- }
256
- return this;
257
- }
258
-
259
- /**
260
- * Synonym for append
261
- * ```ts
262
- * new LinkedList(1).push(2).push(3, 4); // 1 <=> 2 <=> 3 <=> 4
263
- * ```
264
- * @param args Data to be stored, takes any number of arguments
265
- */
266
- public push(...args: NodeData[]): number {
267
- this.append(...args);
268
- return this.length;
269
- }
270
-
271
- /**
272
- * Prepend any number of val arguments to the list. The
273
- * argument list is prepended as a block to reduce confusion:
274
- * ```javascript
275
- * new LinkedList(3, 4).prepend(0, 1, 2); // [0, 1, 2, 3, 4]
276
- * ```
277
- * @param args Data to be stored in the node, accepts any number of arguments
278
- */
279
- public prepend(...args: NodeData[]): SinglyLinkedList<NodeData> {
280
- const reverseArgs = Array.from(args).reverse();
281
- for (const val of reverseArgs) {
282
- const node = new SinglyLinkedListNode(val, null, this.head, this);
283
- if (this.tail === null) {
284
- this.tail = node;
285
- }
286
- if (this.head !== null) {
287
- this.head.prev = node;
288
- }
289
- this.head = node;
290
- this.size += 1;
291
- }
292
- return this;
293
- }
294
-
295
- /**
296
- * Insert a new node at a given index position. If index is
297
- * out of bounds, the node is appended, if index is negative
298
- * or 0, it will be prepended.
299
- * ```ts
300
- * new LinkedList(1, 3).insertAt(1, 2); // 1 <=> 2 <=> 3
301
- * ```
302
- * @param index The index to insert the new node at
303
- * @param val Data to be stored on the new node
304
- */
305
- public insertAt(index: number, val: NodeData): SinglyLinkedList<NodeData> {
306
- if (this.head === null) {
307
- return this.append(val);
308
- }
309
- if (index <= 0) {
310
- return this.prepend(val);
311
- }
312
-
313
- let currentNode = this.head;
314
- let currentIndex = 0;
315
- while (currentIndex < index - 1 && currentNode.next !== null) {
316
- currentIndex += 1;
317
- currentNode = currentNode.next;
318
- }
319
- currentNode.insertAfter(val);
320
- return this;
321
- }
322
-
323
- /**
324
- * Remove the specified node from the list and return the removed
325
- * node afterwards.
326
- * ```ts
327
- * const list = new LinkedList(1, 2, 3);
328
- * list.removeNode(list.tail); // { prev: null, val: 3, next: null, list: null }
329
- * ```
330
- * @param node The node to be removed
331
- */
332
- public removeNode(node: SinglyLinkedListNode<NodeData>): SinglyLinkedListNode<NodeData> {
333
- if (node.list !== this) {
334
- throw new ReferenceError('Node does not belong to this list');
335
- }
336
-
337
- if (node.prev !== null) {
338
- node.prev.next = node.next;
339
- }
340
-
341
- if (node.next !== null) {
342
- node.next.prev = node.prev;
343
- }
344
-
345
- if (this.head === node) {
346
- this.head = node.next;
347
- }
348
-
349
- if (this.tail === node) {
350
- this.tail = node.prev;
351
- }
352
-
353
- this.size -= 1;
354
- node.next = null;
355
- node.prev = null;
356
- node.list = null;
357
- return node;
358
- }
359
-
360
- /**
361
- * Remove the node at the specified index
362
- * ```ts
363
- * new LinkedList(1, 2, 3).removeAt(2); // { prev: null, val: 3, next: null, list: null }
364
- * ```
365
- * @param index Index at which to remove
366
- */
367
- public removeAt(index: number): SinglyLinkedListNode<NodeData> | undefined {
368
- const node = this.getNode(index);
369
- return node !== undefined ? this.removeNode(node) : undefined;
370
- }
371
-
372
- /**
373
- * Insert a new node before the reference node
374
- * ```ts
375
- * const list = new LinkedList(1, 3);
376
- * list.insertBefore(list.tail, 2); // 1 <=> 2 <=> 3
377
- * ```
378
- * @param referenceNode The node reference
379
- * @param val Data to save in the node
380
- */
381
- public insertBefore(
382
- referenceNode: SinglyLinkedListNode<NodeData>,
383
- val: NodeData,
384
- ): SinglyLinkedList<NodeData> {
385
- const node = new SinglyLinkedListNode(val, referenceNode.prev, referenceNode, this);
386
- if (referenceNode.prev === null) {
387
- this.head = node;
388
- }
389
- if (referenceNode.prev !== null) {
390
- referenceNode.prev.next = node;
391
- }
392
- referenceNode.prev = node;
393
- this.size += 1;
394
- return this;
395
- }
396
-
397
- /**
398
- * Sorts the linked list using the provided compare function
399
- * @param compare A function used to compare the val of two nodes. It should return
400
- * a boolean. True will insert a before b, false will insert b before a.
401
- * (a, b) => a < b or (1, 2) => 1 < 2 === true, 2 will be inserted after 1,
402
- * the sort order will be ascending.
403
- */
404
- public sort(compare: (a: NodeData, b: NodeData) => boolean): SinglyLinkedList<NodeData> {
405
- if (this.head === null || this.tail === null) {
406
- return this;
407
- }
408
- if (this.length < 2) {
409
- return this;
410
- }
411
-
412
- const quicksort = (
413
- start: SinglyLinkedListNode<NodeData>,
414
- end: SinglyLinkedListNode<NodeData>,
415
- ) => {
416
- if (start === end) {
417
- return;
418
- }
419
- const pivotData = end.val;
420
- let current: SinglyLinkedListNode | null = start;
421
- let split: SinglyLinkedListNode = start;
422
- while (current && current !== end) {
423
- const sort = compare(current.val, pivotData);
424
- if (sort) {
425
- if (current !== split) {
426
- const temp = split.val;
427
- split.val = current.val;
428
- current.val = temp;
429
- }
430
- // TODO after no-non-null-assertion not ensure the logic
431
- if (split.next) {
432
- split = split.next;
433
- }
434
- }
435
- current = current.next;
436
- }
437
- end.val = split.val;
438
- split.val = pivotData;
439
-
440
- if (start.next === end.prev) {
441
- return;
442
- }
443
-
444
- if (split.prev && split !== start) {
445
- quicksort(start, split.prev);
446
- }
447
- if (split.next && split !== end) {
448
- quicksort(split.next, end);
449
- }
450
- };
451
-
452
- quicksort(this.head, this.tail);
453
- return this;
454
- }
455
-
456
- /**
457
- * Insert a new node after this one
458
- * ```ts
459
- * const list = new LinkedList(2, 3);
460
- * list.insertAfter(list.head, 1); // 1 <=> 2 <=> 3
461
- * ```
462
- * @param referenceNode The reference node
463
- * @param val Data to be saved in the node
464
- */
465
- public insertAfter(
466
- referenceNode: SinglyLinkedListNode<NodeData>,
467
- val: NodeData,
468
- ): SinglyLinkedList<NodeData> {
469
- const node = new SinglyLinkedListNode(val, referenceNode, referenceNode.next, this);
470
- if (referenceNode.next === null) {
471
- this.tail = node;
472
- }
473
- if (referenceNode.next !== null) {
474
- referenceNode.next.prev = node;
475
- }
476
- referenceNode.next = node;
477
- this.size += 1;
478
- return this;
479
- }
480
-
481
- /**
482
- * Remove the first node from the list and return the val of the removed node
483
- * or undefined
484
- * ```ts
485
- * new LinkedList(1, 2, 3).shift(); // 1
486
- * ```
487
- */
488
- public shift(): NodeData | undefined {
489
- return this.removeFromAnyEnd(this.head);
490
- }
491
-
492
- /**
493
- * Remove the last node from the list and return the val of the removed node
494
- * or undefined if the list was empty
495
- * ```ts
496
- * new LinkedList(1, 2, 3).pop(); // 3
497
- * ```
498
- */
499
- public pop(): NodeData | undefined {
500
- return this.removeFromAnyEnd(this.tail);
501
- }
502
-
503
- /**
504
- * Merge the current list with another. Both lists will be
505
- * equal after merging.
506
- * ```ts
507
- * const list = new LinkedList(1, 2);
508
- * const otherList = new LinkedList(3);
509
- * list.merge(otherList);
510
- * (list === otherList); // true
511
- * ```
512
- * @param list The list to be merged
513
- */
514
- public merge(list: SinglyLinkedList<NodeData>): void {
515
- if (this.tail !== null) {
516
- this.tail.next = list.head;
517
- }
518
- if (list.head !== null) {
519
- list.head.prev = this.tail;
520
- }
521
- this.head = this.head || list.head;
522
- this.tail = list.tail || this.tail;
523
- this.size += list.size;
524
- list.size = this.size;
525
- list.head = this.head;
526
- list.tail = this.tail;
527
- }
528
-
529
- /**
530
- * Removes all nodes from a list
531
- *
532
- * ```ts
533
- * list.clear();
534
- * ```
535
- */
536
- public clear() {
537
- this.head = null;
538
- this.tail = null;
539
- this.size = 0;
540
- return this;
541
- }
542
-
543
- /**
544
- * The slice() method returns a shallow copy of a
545
- * portion of a list into a new list object selected
546
- * from start to end (end not included).
547
- * The original list will not be modified.
548
- * ```ts
549
- * const list = new LinkedList(1, 2, 3, 4, 5);
550
- * const newList = list.slice(0, 3); // 1 <=> 2 <=> 3
551
- * ```
552
- * @param start Start index
553
- * @param end End index, optional
554
- */
555
- // eslint-disable-next-line @typescript-eslint/ban-types
556
- public slice(start: number, end?: number): SinglyLinkedList<NodeData | {}> {
557
- const list = new SinglyLinkedList();
558
- let finish = end;
559
-
560
- if (this.head === null || this.tail === null) {
561
- return list;
562
- }
563
- if (finish === undefined || finish < start) {
564
- finish = this.length;
565
- }
566
-
567
- let head: SinglyLinkedListNode<NodeData> | null | undefined = this.getNode(start);
568
- for (let i = 0; i < finish - start && head !== null && head !== undefined; i++) {
569
- list.append(head.val);
570
- head = head.next;
571
- }
572
- return list;
573
- }
574
-
575
- /**
576
- * The reverse() function reverses the list in place and returns the list
577
- * itself.
578
- * ```ts
579
- * new LinkedList(1, 2, 3).reverse(); // 3 <=> 2 <=> 1
580
- * ```
581
- */
582
- public reverse(): SinglyLinkedList<NodeData> {
583
- let currentNode = this.head;
584
- while (currentNode) {
585
- const next = currentNode.next;
586
- currentNode.next = currentNode.prev;
587
- currentNode.prev = next;
588
- currentNode = currentNode.prev;
589
- }
590
- const tail = this.tail;
591
- this.tail = this.head;
592
- this.head = tail;
593
- return this;
594
- }
595
-
596
- /**
597
- * The forEach() method executes a provided function once for each list node.
598
- * ```ts
599
- * new LinkedList(1, 2, 3).forEach(val => log(val)); // 1 2 3
600
- * ```
601
- * @param f Function to execute for each element, taking up to three arguments.
602
- * @param reverse Indicates if the list should be walked in reverse order, default is false
603
- */
604
- public forEach(f: TMapFunction<NodeData>, reverse = false): void {
605
- let currentIndex = reverse ? this.length - 1 : 0;
606
- let currentNode = reverse ? this.tail : this.head;
607
- const modifier = reverse ? -1 : 1;
608
- const nextNode = reverse ? 'prev' : 'next';
609
- while (currentNode) {
610
- f(currentNode.val, currentIndex, this);
611
- currentNode = currentNode[nextNode];
612
- currentIndex += modifier;
613
- }
614
- }
615
-
616
- /**
617
- * The map() method creates a new list with the results of
618
- * calling a provided function on every node in the calling list.
619
- * ```ts
620
- * new LinkedList(1, 2, 3).map(val => val + 10); // 11 <=> 12 <=> 13
621
- * ```
622
- * @param f Function that produces an node of the new list, taking up to three arguments
623
- * @param reverse Indicates if the list should be mapped in reverse order, default is false
624
- */
625
- // eslint-disable-next-line @typescript-eslint/ban-types
626
- public map(f: TMapFunction<NodeData>, reverse = false): SinglyLinkedList<NodeData | {}> {
627
- const list = new SinglyLinkedList();
628
- this.forEach((val, index) => list.append(f(val, index, this)), reverse);
629
- return list;
630
- }
631
-
632
- /**
633
- * The filter() method creates a new list with all nodes
634
- * that pass the test implemented by the provided function.
635
- * ```ts
636
- * new LinkedList(1, 2, 3, 4, 5).filter(val => val < 4); // 1 <=> 2 <=> 3
637
- * ```
638
- * @param f Function to test each node val in the list. Return true to keep the node
639
- * @param reverse Indicates if the list should be filtered in reverse order, default is false
640
- */
641
- // eslint-disable-next-line @typescript-eslint/ban-types
642
- public filter(f: TTestFunction<NodeData>, reverse = false): SinglyLinkedList<NodeData | {}> {
643
- const list = new SinglyLinkedList();
644
- this.forEach((val, index) => {
645
- if (f(val, index, this)) {
646
- list.append(val);
647
- }
648
- }, reverse);
649
- return list;
650
- }
651
-
652
- /**
653
- * Reduce over each node in the list
654
- * ```ts
655
- * new LinkedList(1, 2, 3).reduce(n => n += 1, 0); // 3
656
- * ```
657
- * @param f A reducer function
658
- * @param start An initial value
659
- * @returns The final state of the accumulator
660
- */
661
- public reduce(
662
- f: (
663
- accumulator: any,
664
- currentNode: NodeData,
665
- index: number,
666
- list: SinglyLinkedList<NodeData>,
667
- ) => any,
668
- start?: any,
669
- reverse = false,
670
- ): any {
671
- let currentIndex = reverse ? this.length - 1 : 0;
672
- const modifier = reverse ? -1 : 1;
673
- const nextNode = reverse ? 'prev' : 'next';
674
- let currentElement = reverse ? this.tail : this.head;
675
- let result;
676
-
677
- if (start !== undefined) {
678
- result = start;
679
- } else if (currentElement) {
680
- result = currentElement.val;
681
- currentElement = currentElement[nextNode];
682
- } else {
683
- throw new TypeError('Reduce of empty LinkedList with no initial value');
684
- }
685
-
686
- while (currentElement) {
687
- result = f(result, currentElement.val, currentIndex, this);
688
- currentIndex += modifier;
689
- currentElement = currentElement[nextNode];
690
- }
691
-
692
- return result;
693
- }
694
-
695
- /**
696
- * Convert the linked list to an array
697
- * ```ts
698
- * new LinkedList(1, 2, 3).toArray(); // [1, 2, 3]
699
- * ```
700
- */
701
- public toArray(): NodeData[] {
702
- return [...this];
703
- }
704
-
705
- /**
706
- * Convert a linked list to string
707
- * ```ts
708
- * new LinkedList('one', 'two', 'three').toString(' <=> ') === 'one <=> two <=> three';
709
- * ```
710
- * @param separator Optional string to be placed in between val nodes, default is one space
711
- */
712
- public toString(separator = ' '): string {
713
- return this.reduce((s, val) => `${s}${separator}${val}`);
714
- }
715
-
716
- /**
717
- * The iterator implementation
718
- * ```ts
719
- * const list = new LinkedList(1, 2, 3);
720
- * for (const val of list) { log(val); } // 1 2 3
721
- * ```
722
- */
723
- public* [Symbol.iterator](): IterableIterator<NodeData> {
724
- let element = this.head;
725
-
726
- while (element !== null) {
727
- yield element.val;
728
- element = element.next;
729
- }
730
- }
731
-
732
- /** Private helper function to reduce duplication of pop() and shift() methods */
733
- private removeFromAnyEnd(node: SinglyLinkedListNode<NodeData> | null) {
734
- return node !== null ? this.removeNode(node).val : undefined;
735
- }
736
- }