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,753 +0,0 @@
1
- import {arrayRemove, uuidV4} from '../../utils';
2
- import {PriorityQueue} from '../priority-queue';
3
- import type {DijkstraResult, IGraph, VertexId} from '../types';
4
-
5
- export class AbstractVertex {
6
- constructor(id: VertexId) {
7
- this._id = id;
8
- }
9
-
10
- private _id: VertexId;
11
-
12
- public get id(): VertexId {
13
- return this._id;
14
- }
15
-
16
- public set id(v: VertexId) {
17
- this._id = v;
18
- }
19
- }
20
-
21
- export abstract class AbstractEdge {
22
-
23
- static DEFAULT_EDGE_WEIGHT = 1;
24
-
25
- protected constructor(weight?: number) {
26
- if (weight === undefined) weight = AbstractEdge.DEFAULT_EDGE_WEIGHT;
27
- this._weight = weight;
28
- this._hashCode = uuidV4();
29
- }
30
-
31
- private _weight: number;
32
-
33
- get weight(): number {
34
- return this._weight;
35
- }
36
-
37
- set weight(v: number) {
38
- this._weight = v;
39
- }
40
-
41
- private _hashCode: string;
42
-
43
- get hashCode(): string {
44
- return this._hashCode;
45
- }
46
-
47
- set hashCode(v: string) {
48
- this._hashCode = v;
49
- }
50
- }
51
-
52
- // Connected Component === Largest Connected Sub-Graph
53
- export abstract class AbstractGraph<V extends AbstractVertex, E extends AbstractEdge> implements IGraph<V, E> {
54
-
55
- protected _vertices: Map<VertexId, V> = new Map<VertexId, V>();
56
-
57
- abstract removeEdgeBetween(srcOrId: V | VertexId, destOrId: V | VertexId): E | null;
58
-
59
- abstract removeEdge(edge: E): E | null;
60
-
61
- getVertex(vertexOrId: VertexId | V): V | null {
62
- const vertexId = this.getVertexId(vertexOrId);
63
- return this._vertices.get(vertexId) || null;
64
- }
65
-
66
- getVertexId(vertexOrId: V | VertexId): VertexId {
67
- return vertexOrId instanceof AbstractVertex ? vertexOrId.id : vertexOrId;
68
- }
69
-
70
- containsVertex(vertexOrId: V | VertexId): boolean {
71
- return this._vertices.has(this.getVertexId(vertexOrId));
72
- }
73
-
74
- vertexSet(): Map<VertexId, V> {
75
- return this._vertices;
76
- }
77
-
78
- abstract getEdge(srcOrId: V | null | VertexId, destOrId: V | null | VertexId): E | null;
79
-
80
- addVertex(newVertex: V): boolean {
81
- if (this.containsVertex(newVertex)) {
82
- return false;
83
- }
84
- this._vertices.set(newVertex.id, newVertex);
85
- return true;
86
- }
87
-
88
- removeVertex(vertexOrId: V | VertexId): boolean {
89
- const vertexId = this.getVertexId(vertexOrId);
90
- return this._vertices.delete(vertexId);
91
- }
92
-
93
- removeAllVertices(vertices: V[] | VertexId[]): boolean {
94
- const removed: boolean[] = [];
95
- for (const v of vertices) {
96
- removed.push(this.removeVertex(v));
97
- }
98
- return removed.length > 0;
99
- }
100
-
101
- abstract degreeOf(vertexOrId: V | VertexId): number;
102
-
103
- abstract edgeSet(): E[];
104
-
105
- abstract edgesOf(vertexOrId: V | VertexId): E[];
106
-
107
- containsEdge(v1: VertexId | V, v2: VertexId | V): boolean {
108
- const edge = this.getEdge(v1, v2);
109
- return !!edge;
110
- }
111
-
112
- abstract addEdge(edge: E): boolean;
113
-
114
- setEdgeWeight(srcOrId: VertexId | V, destOrId: VertexId | V, weight: number): boolean {
115
- const edge = this.getEdge(srcOrId, destOrId);
116
- if (edge) {
117
- edge.weight = weight;
118
- return true;
119
- } else {
120
- return false;
121
- }
122
- }
123
-
124
- abstract getNeighbors(vertexOrId: V | VertexId): V[];
125
-
126
- getAllPathsBetween(v1: V | VertexId, v2: V | VertexId): V[][] {
127
- const paths: V[][] = [];
128
- const vertex1 = this.getVertex(v1);
129
- const vertex2 = this.getVertex(v2);
130
- if (!(vertex1 && vertex2)) {
131
- return [];
132
- }
133
-
134
- const dfs = (cur: V, dest: V, visiting: Map<V, boolean>, path: V[]) => {
135
- visiting.set(cur, true);
136
-
137
- if (cur === dest) {
138
- paths.push([vertex1, ...path]);
139
- }
140
-
141
- const neighbors = this.getNeighbors(cur);
142
- for (const neighbor of neighbors) {
143
- if (!visiting.get(neighbor)) {
144
- path.push(neighbor);
145
- dfs(neighbor, dest, visiting, path);
146
- arrayRemove(path, (vertex: AbstractVertex) => vertex === neighbor);
147
- }
148
- }
149
-
150
- visiting.set(cur, false);
151
- };
152
-
153
- dfs(vertex1, vertex2, new Map<V, boolean>(), []);
154
- return paths;
155
- }
156
-
157
-
158
- getPathSumWeight(path: V[]): number {
159
- let sum = 0;
160
- for (let i = 0; i < path.length; i++) {
161
- sum += this.getEdge(path[i], path[i + 1])?.weight || 0;
162
- }
163
- return sum;
164
- }
165
-
166
- getMinCostBetween(v1: V | VertexId, v2: V | VertexId, isWeight?: boolean): number | null {
167
- if (isWeight === undefined) isWeight = false;
168
-
169
- if (isWeight) {
170
- const allPaths = this.getAllPathsBetween(v1, v2);
171
- let min = Infinity;
172
- for (const path of allPaths) {
173
- min = Math.min(this.getPathSumWeight(path), min);
174
- }
175
- return min;
176
- } else {
177
- // BFS
178
- const vertex2 = this.getVertex(v2);
179
- const vertex1 = this.getVertex(v1);
180
- if (!(vertex1 && vertex2)) {
181
- return null;
182
- }
183
-
184
- const visited: Map<V, boolean> = new Map();
185
- const queue: V[] = [vertex1];
186
- visited.set(vertex1, true);
187
- let cost = 0;
188
- while (queue.length > 0) {
189
- for (let i = 0; i < queue.length; i++) {
190
- const cur = queue.shift();
191
- if (cur === vertex2) {
192
- return cost;
193
- }
194
- // TODO consider optimizing to AbstractGraph
195
- if (cur !== undefined) {
196
- const neighbors = this.getNeighbors(cur);
197
- for (const neighbor of neighbors) {
198
- if (!visited.has(neighbor)) {
199
- visited.set(neighbor, true);
200
- queue.push(neighbor);
201
- }
202
- }
203
- }
204
- }
205
- cost++;
206
- }
207
- return null;
208
- }
209
- }
210
-
211
- getMinPathBetween(v1: V | VertexId, v2: V | VertexId, isWeight?: boolean): V[] | null {
212
- if (isWeight === undefined) isWeight = false;
213
-
214
- if (isWeight) {
215
- const allPaths = this.getAllPathsBetween(v1, v2);
216
- let min = Infinity;
217
- let minIndex = -1;
218
- let index = 0;
219
- for (const path of allPaths) {
220
- const pathSumWeight = this.getPathSumWeight(path);
221
- if (pathSumWeight < min) {
222
- min = pathSumWeight;
223
- minIndex = index;
224
- }
225
- index++;
226
- }
227
- return allPaths[minIndex] || null;
228
- } else {
229
- // BFS
230
- let minPath: V[] = [];
231
- const vertex1 = this.getVertex(v1);
232
- const vertex2 = this.getVertex(v2);
233
- if (!(vertex1 && vertex2)) {
234
- return [];
235
- }
236
-
237
- const dfs = (cur: V, dest: V, visiting: Map<V, boolean>, path: V[]) => {
238
- visiting.set(cur, true);
239
-
240
- if (cur === dest) {
241
- minPath = [vertex1, ...path];
242
- return;
243
- }
244
-
245
- const neighbors = this.getNeighbors(cur);
246
- for (const neighbor of neighbors) {
247
- if (!visiting.get(neighbor)) {
248
- path.push(neighbor);
249
- dfs(neighbor, dest, visiting, path);
250
- arrayRemove(path, (vertex: AbstractVertex) => vertex === neighbor);
251
- }
252
- }
253
-
254
- visiting.set(cur, false);
255
- };
256
-
257
- dfs(vertex1, vertex2, new Map<V, boolean>(), []);
258
- return minPath;
259
- }
260
- }
261
-
262
- /**
263
- * Dijkstra algorithm time: O(VE) space: O(V + E)
264
- * @param src
265
- * @param dest
266
- * @param getMinDist
267
- * @param genPaths
268
- */
269
- dijkstraWithoutHeap(src: V | VertexId, dest?: V | VertexId | null, getMinDist?: boolean, genPaths?: boolean): DijkstraResult<V> {
270
- if (getMinDist === undefined) getMinDist = false;
271
- if (genPaths === undefined) genPaths = false;
272
-
273
- if (dest === undefined) dest = null;
274
- let minDist = Infinity;
275
- let minDest: V | null = null;
276
- let minPath: V[] = [];
277
- const paths: V[][] = [];
278
-
279
- const vertices = this._vertices;
280
- const distMap: Map<V, number> = new Map();
281
- const seen: Set<V> = new Set();
282
- const preMap: Map<V, V | null> = new Map(); // predecessor
283
- const srcVertex = this.getVertex(src);
284
-
285
- const destVertex = dest ? this.getVertex(dest) : null;
286
-
287
- if (!srcVertex) {
288
- return null;
289
- }
290
-
291
- for (const vertex of vertices) {
292
- const vertexOrId = vertex[1];
293
- if (vertexOrId instanceof AbstractVertex) distMap.set(vertexOrId, Infinity);
294
- }
295
- distMap.set(srcVertex, 0);
296
- preMap.set(srcVertex, null);
297
-
298
- const getMinOfNoSeen = () => {
299
- let min = Infinity;
300
- let minV: V | null = null;
301
- for (const [key, val] of distMap) {
302
- if (!seen.has(key)) {
303
- if (val < min) {
304
- min = val;
305
- minV = key;
306
- }
307
- }
308
- }
309
- return minV;
310
- };
311
-
312
- const getPaths = (minV: V | null) => {
313
- for (const vertex of vertices) {
314
- const vertexOrId = vertex[1];
315
-
316
- if (vertexOrId instanceof AbstractVertex) {
317
- const path: V[] = [vertexOrId];
318
- let parent = preMap.get(vertexOrId);
319
- while (parent) {
320
- path.push(parent);
321
- parent = preMap.get(parent);
322
- }
323
- const reversed = path.reverse();
324
- if (vertex[1] === minV) minPath = reversed;
325
- paths.push(reversed);
326
- }
327
- }
328
- };
329
-
330
- for (let i = 1; i < vertices.size; i++) {
331
- const cur = getMinOfNoSeen();
332
- if (cur) {
333
- seen.add(cur);
334
- if (destVertex && destVertex === cur) {
335
- if (getMinDist) {
336
- minDist = distMap.get(destVertex) || Infinity;
337
- }
338
- if (genPaths) {
339
- getPaths(destVertex);
340
- }
341
- return {distMap, preMap, seen, paths, minDist, minPath};
342
- }
343
- const neighbors = this.getNeighbors(cur);
344
- for (const neighbor of neighbors) {
345
- if (!seen.has(neighbor)) {
346
- const edge = this.getEdge(cur, neighbor);
347
- if (edge) {
348
- const curFromMap = distMap.get(cur);
349
- const neighborFromMap = distMap.get(neighbor);
350
- // TODO after no-non-null-assertion not ensure the logic
351
- if (curFromMap !== undefined && neighborFromMap !== undefined) {
352
- if (edge.weight + curFromMap < neighborFromMap) {
353
- distMap.set(neighbor, edge.weight + curFromMap);
354
- preMap.set(neighbor, cur);
355
- }
356
- }
357
-
358
- }
359
- }
360
- }
361
- }
362
- }
363
-
364
- getMinDist && distMap.forEach((d, v) => {
365
- if (v !== srcVertex) {
366
- if (d < minDist) {
367
- minDist = d;
368
- if (genPaths) minDest = v;
369
- }
370
- }
371
- });
372
-
373
- genPaths && getPaths(minDest);
374
-
375
- return {distMap, preMap, seen, paths, minDist, minPath};
376
- }
377
-
378
-
379
- /**
380
- * Dijkstra algorithm time: O(logVE) space: O(V + E)
381
- * @param src
382
- * @param dest
383
- * @param getMinDist
384
- * @param genPaths
385
- */
386
- dijkstra(src: V | VertexId, dest?: V | VertexId | null, getMinDist?: boolean, genPaths?: boolean): DijkstraResult<V> {
387
- if (getMinDist === undefined) getMinDist = false;
388
- if (genPaths === undefined) genPaths = false;
389
-
390
- if (dest === undefined) dest = null;
391
- let minDist = Infinity;
392
- let minDest: V | null = null;
393
- let minPath: V[] = [];
394
- const paths: V[][] = [];
395
- const vertices = this._vertices;
396
- const distMap: Map<V, number> = new Map();
397
- const seen: Set<V> = new Set();
398
- const preMap: Map<V, V | null> = new Map(); // predecessor
399
-
400
- const srcVertex = this.getVertex(src);
401
- const destVertex = dest ? this.getVertex(dest) : null;
402
-
403
- if (!srcVertex) {
404
- return null;
405
- }
406
-
407
- for (const vertex of vertices) {
408
- const vertexOrId = vertex[1];
409
- if (vertexOrId instanceof AbstractVertex) distMap.set(vertexOrId, Infinity);
410
- }
411
-
412
- const heap = new PriorityQueue<{ id: number, val: V }>({comparator: (a, b) => a.id - b.id});
413
- heap.offer({id: 0, val: srcVertex});
414
-
415
- distMap.set(srcVertex, 0);
416
- preMap.set(srcVertex, null);
417
-
418
- const getPaths = (minV: V | null) => {
419
- for (const vertex of vertices) {
420
- const vertexOrId = vertex[1];
421
- if (vertexOrId instanceof AbstractVertex) {
422
- const path: V[] = [vertexOrId];
423
- let parent = preMap.get(vertexOrId);
424
- while (parent) {
425
- path.push(parent);
426
- parent = preMap.get(parent);
427
- }
428
- const reversed = path.reverse();
429
- if (vertex[1] === minV) minPath = reversed;
430
- paths.push(reversed);
431
- }
432
-
433
- }
434
- };
435
-
436
- while (heap.size > 0) {
437
- const curHeapNode = heap.poll();
438
- const dist = curHeapNode?.id;
439
- const cur = curHeapNode?.val;
440
- if (dist !== undefined) {
441
- if (cur) {
442
- seen.add(cur);
443
- if (destVertex && destVertex === cur) {
444
- if (getMinDist) {
445
- minDist = distMap.get(destVertex) || Infinity;
446
- }
447
- if (genPaths) {
448
- getPaths(destVertex);
449
- }
450
- return {distMap, preMap, seen, paths, minDist, minPath};
451
- }
452
- const neighbors = this.getNeighbors(cur);
453
- for (const neighbor of neighbors) {
454
- if (!seen.has(neighbor)) {
455
- const weight = this.getEdge(cur, neighbor)?.weight;
456
- if (typeof weight === 'number') {
457
- const distSrcToNeighbor = distMap.get(neighbor);
458
- if (distSrcToNeighbor) {
459
- if (dist + weight < distSrcToNeighbor) {
460
- heap.offer({id: dist + weight, val: neighbor});
461
- preMap.set(neighbor, cur);
462
- distMap.set(neighbor, dist + weight);
463
- }
464
- }
465
- }
466
- }
467
- }
468
- }
469
- }
470
- }
471
-
472
-
473
- if (getMinDist) {
474
- distMap.forEach((d, v) => {
475
- if (v !== srcVertex) {
476
- if (d < minDist) {
477
- minDist = d;
478
- if (genPaths) minDest = v;
479
- }
480
- }
481
- });
482
- }
483
-
484
-
485
- if (genPaths) {
486
- getPaths(minDest);
487
- }
488
-
489
-
490
- return {distMap, preMap, seen, paths, minDist, minPath};
491
- }
492
-
493
- abstract getEndsOfEdge(edge: E): [V, V] | null;
494
-
495
-
496
- /**
497
- * BellmanFord time:O(VE) space:O(V)
498
- * one to rest pairs
499
- * @param src
500
- * @param scanNegativeCycle
501
- * @param getMin
502
- * @param genPath
503
- */
504
- bellmanFord(src: V | VertexId, scanNegativeCycle?: boolean, getMin?: boolean, genPath?: boolean) {
505
- if (getMin === undefined) getMin = false;
506
- if (genPath === undefined) genPath = false;
507
-
508
- const srcVertex = this.getVertex(src);
509
- const paths: V[][] = [];
510
- const distMap: Map<V, number> = new Map();
511
- const preMap: Map<V, V> = new Map(); // predecessor
512
- let min = Infinity;
513
- let minPath: V[] = [];
514
- // TODO
515
- let hasNegativeCycle: boolean | undefined;
516
- if (scanNegativeCycle) hasNegativeCycle = false;
517
- if (!srcVertex) return {hasNegativeCycle, distMap, preMap, paths, min, minPath};
518
-
519
- const vertices = this._vertices;
520
- const numOfVertices = vertices.size;
521
- const edges = this.edgeSet();
522
- const numOfEdges = edges.length;
523
-
524
- this._vertices.forEach(vertex => {
525
- distMap.set(vertex, Infinity);
526
- });
527
-
528
- distMap.set(srcVertex, 0);
529
-
530
- for (let i = 1; i < numOfVertices; ++i) {
531
- for (let j = 0; j < numOfEdges; ++j) {
532
- const ends = this.getEndsOfEdge(edges[j]);
533
- if (ends) {
534
- const [s, d] = ends;
535
- const weight = edges[j].weight;
536
- const sWeight = distMap.get(s);
537
- const dWeight = distMap.get(d);
538
- if (sWeight !== undefined && dWeight !== undefined) {
539
- if (distMap.get(s) !== Infinity && sWeight + weight < dWeight) {
540
- distMap.set(d, sWeight + weight);
541
- genPath && preMap.set(d, s);
542
- }
543
- }
544
- }
545
- }
546
- }
547
-
548
- let minDest: V | null = null;
549
- if (getMin) {
550
- distMap.forEach((d, v) => {
551
- if (v !== srcVertex) {
552
- if (d < min) {
553
- min = d;
554
- if (genPath) minDest = v;
555
- }
556
- }
557
- });
558
- }
559
-
560
- if (genPath) {
561
- for (const vertex of vertices) {
562
- const vertexOrId = vertex[1];
563
- if (vertexOrId instanceof AbstractVertex) {
564
- const path: V[] = [vertexOrId];
565
- let parent = preMap.get(vertexOrId);
566
- while (parent !== undefined) {
567
- path.push(parent);
568
- parent = preMap.get(parent);
569
- }
570
- const reversed = path.reverse();
571
- if (vertex[1] === minDest) minPath = reversed;
572
- paths.push(reversed);
573
- }
574
- }
575
- }
576
-
577
- for (let j = 0; j < numOfEdges; ++j) {
578
- const ends = this.getEndsOfEdge(edges[j]);
579
- if (ends) {
580
- const [s] = ends;
581
- const weight = edges[j].weight;
582
- const sWeight = distMap.get(s);
583
- if (sWeight) {
584
- if (sWeight !== Infinity && sWeight + weight < sWeight) hasNegativeCycle = true;
585
- }
586
- }
587
- }
588
-
589
- return {hasNegativeCycle, distMap, preMap, paths, min, minPath};
590
- }
591
-
592
- /**
593
- * Floyd algorithm time: O(V^3) space: O(V^2), not support graph with negative weight cycle
594
- * all pairs
595
- */
596
- floyd(): { costs: number[][], predecessor: (V | null)[][] } {
597
- const idAndVertices = [...this._vertices];
598
- const n = idAndVertices.length;
599
-
600
- const costs: number[][] = [];
601
- const predecessor: (V | null)[][] = [];
602
- // successors
603
-
604
- for (let i = 0; i < n; i++) {
605
- costs[i] = [];
606
- predecessor[i] = [];
607
- for (let j = 0; j < n; j++) {
608
- predecessor[i][j] = null;
609
- }
610
- }
611
-
612
- for (let i = 0; i < n; i++) {
613
- for (let j = 0; j < n; j++) {
614
- costs[i][j] = this.getEdge(idAndVertices[i][1], idAndVertices[j][1])?.weight || Infinity;
615
- }
616
- }
617
-
618
- for (let k = 0; k < n; k++) {
619
- for (let i = 0; i < n; i++) {
620
- for (let j = 0; j < n; j++) {
621
- if (costs[i][j] > costs[i][k] + costs[k][j]) {
622
- costs[i][j] = costs[i][k] + costs[k][j];
623
- predecessor[i][j] = idAndVertices[k][1];
624
- }
625
- }
626
- }
627
- }
628
- return {costs, predecessor};
629
-
630
- }
631
-
632
-
633
- /**--- start find cycles --- */
634
-
635
- /**
636
- * Tarjan is an algorithm based on DFS,which is used to solve the connectivity problem of graphs.
637
- * Tarjan can find cycles in directed or undirected graph
638
- * Tarjan can find the articulation points and bridges(critical edges) of undirected graphs in linear time,
639
- * Tarjan solve the bi-connected components of undirected graphs;
640
- * Tarjan can find the SSC(strongly connected components), articulation points, and bridges of directed graphs.
641
- */
642
- tarjan(needArticulationPoints?: boolean, needBridges?: boolean, needSCCs?: boolean, needCycles?: boolean) {
643
- // !! in undirected graph we will not let child visit parent when DFS
644
- // !! articulation point(in DFS search tree not in graph): (cur !== root && cur.has(child)) && (low(child) >= dfn(cur)) || (cur === root && cur.children() >= 2)
645
- // !! bridge: low(child) > dfn(cur)
646
-
647
- const defaultConfig = false;
648
- if (needArticulationPoints === undefined) needArticulationPoints = defaultConfig;
649
- if (needBridges === undefined) needBridges = defaultConfig;
650
- if (needSCCs === undefined) needSCCs = defaultConfig;
651
- if (needCycles === undefined) needCycles = defaultConfig;
652
-
653
- const dfnMap: Map<V, number> = new Map();
654
- const lowMap: Map<V, number> = new Map();
655
- const vertices = this._vertices;
656
- vertices.forEach(v => {
657
- dfnMap.set(v, -1);
658
- lowMap.set(v, Infinity);
659
- });
660
-
661
- const [root] = vertices.values();
662
-
663
- const articulationPoints: V[] = [];
664
- const bridges: E[] = [];
665
- let dfn = 0;
666
- const dfs = (cur: V, parent: V | null) => {
667
- dfn++;
668
- dfnMap.set(cur, dfn);
669
- lowMap.set(cur, dfn);
670
-
671
- const neighbors = this.getNeighbors(cur);
672
- let childCount = 0; // child in DFS tree not child in graph
673
- for (const neighbor of neighbors) {
674
- if (neighbor !== parent) {
675
- if (dfnMap.get(neighbor) === -1) {
676
- childCount++;
677
- dfs(neighbor, cur);
678
- }
679
- const childLow = lowMap.get(neighbor);
680
- const curLow = lowMap.get(cur);
681
- // TODO after no-non-null-assertion not ensure the logic
682
- if (curLow !== undefined && childLow !== undefined) {
683
- lowMap.set(cur, Math.min(curLow, childLow));
684
- }
685
- const curFromMap = dfnMap.get(cur);
686
- if (childLow !== undefined && curFromMap !== undefined) {
687
- if (needArticulationPoints) {
688
- if ((cur === root && childCount >= 2) || ((cur !== root) && (childLow >= curFromMap))) {
689
- // todo not ensure the logic if (cur === root && childCount >= 2 || ((cur !== root) && (childLow >= curFromMap))) {
690
- articulationPoints.push(cur);
691
- }
692
- }
693
-
694
- if (needBridges) {
695
- if (childLow > curFromMap) {
696
- const edgeCurToNeighbor = this.getEdge(cur, neighbor);
697
- if (edgeCurToNeighbor) {
698
- bridges.push(edgeCurToNeighbor);
699
- }
700
- }
701
- }
702
- }
703
- }
704
- }
705
-
706
- };
707
-
708
- dfs(root, null);
709
-
710
- let SCCs: Map<number, V[]> = new Map();
711
-
712
- const getSCCs = () => {
713
- const SCCs: Map<number, V[]> = new Map();
714
- lowMap.forEach((low, vertex) => {
715
- if (!SCCs.has(low)) {
716
- SCCs.set(low, [vertex]);
717
- } else {
718
- SCCs.get(low)?.push(vertex);
719
- }
720
- });
721
- return SCCs;
722
- };
723
-
724
- if (needSCCs) {
725
- SCCs = getSCCs();
726
- }
727
-
728
- const cycles: Map<number, V[]> = new Map();
729
- if (needCycles) {
730
- let SCCs: Map<number, V[]> = new Map();
731
- if (SCCs.size < 1) {
732
- SCCs = getSCCs();
733
- }
734
-
735
- SCCs.forEach((SCC, low) => {
736
- if (SCC.length > 1) {
737
- cycles.set(low, SCC);
738
- }
739
- });
740
- }
741
-
742
- return {dfnMap, lowMap, bridges, articulationPoints, SCCs, cycles};
743
- }
744
-
745
-
746
- // unionFind() {
747
- // }
748
-
749
- /**--- end find cycles --- */
750
-
751
-
752
- // Minimum Spanning Tree
753
- }