@raikuxq/alg-ds 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +14 -0
- package/LICENSE +21 -0
- package/README.md +221 -0
- package/jest.config.js +4 -0
- package/nodemon.json +6 -0
- package/package.json +43 -0
- package/src/algorithms/binary-search.ts +28 -0
- package/src/algorithms/factorial.ts +18 -0
- package/src/algorithms/fibonacci.ts +18 -0
- package/src/algorithms/memoize.ts +21 -0
- package/src/algorithms/sorts/bubble-sort.ts +21 -0
- package/src/algorithms/sorts/insertion-sort.ts +25 -0
- package/src/algorithms/sorts/merge-sort.ts +74 -0
- package/src/algorithms/sorts/quick-sort.ts +54 -0
- package/src/algorithms/sorts/select-sort.ts +19 -0
- package/src/algorithms/transpose-matrix.ts +19 -0
- package/src/constants.ts +2 -0
- package/src/data-structures/BinaryTree/AbstractBinaryTree/AbstractBinaryNode.ts +45 -0
- package/src/data-structures/BinaryTree/AbstractBinaryTree/AbstractBinaryTree.ts +80 -0
- package/src/data-structures/BinaryTree/BinarySearchTree/BinarySearchNode.ts +38 -0
- package/src/data-structures/BinaryTree/BinarySearchTree/BinarySearchTree.ts +286 -0
- package/src/data-structures/BinaryTree/RandBinarySearchTree/RandBinarySearchNode.ts +48 -0
- package/src/data-structures/BinaryTree/RandBinarySearchTree/RandBinarySearchTree.ts +228 -0
- package/src/data-structures/Graph/AbstractGraph.ts +189 -0
- package/src/data-structures/Graph/DirectedGraph.ts +84 -0
- package/src/data-structures/Graph/GraphEdge.ts +33 -0
- package/src/data-structures/Graph/UndirectedGraph.ts +108 -0
- package/src/data-structures/Graph/demo/generateRandomGraph.ts +93 -0
- package/src/data-structures/Graph/iterator/AbstractGraphIterator.ts +99 -0
- package/src/data-structures/Graph/iterator/GraphIteratorBFS.ts +60 -0
- package/src/data-structures/Graph/iterator/GraphIteratorDFS.ts +60 -0
- package/src/data-structures/Graph/iterator/GraphIteratorDijkstra.ts +94 -0
- package/src/data-structures/Graph/presenter/presenterAdjacencyLists.ts +29 -0
- package/src/data-structures/Graph/presenter/presenterAdjacencyMatrix.ts +51 -0
- package/src/data-structures/Graph/searching/hasPath.ts +38 -0
- package/src/data-structures/Graph/searching/shortestPath.ts +38 -0
- package/src/data-structures/Graph/strategy/BFSIterationStrategy.ts +11 -0
- package/src/data-structures/Graph/strategy/DFSIterationStrategy.ts +11 -0
- package/src/data-structures/Graph/strategy/DijkstraIterationStrategy.ts +11 -0
- package/src/data-structures/Graph/transposing/transposeDirectedGraph.ts +19 -0
- package/src/data-structures/LinkedList/AbstractLinkedList/AbstractLinkedList.ts +310 -0
- package/src/data-structures/LinkedList/AbstractLinkedList/AbstractLinkedNode.ts +33 -0
- package/src/data-structures/LinkedList/DoubleLinkedList/DoubleLinkedList.ts +156 -0
- package/src/data-structures/LinkedList/DoubleLinkedList/DoubleLinkedNode.ts +47 -0
- package/src/data-structures/LinkedList/SingleLinkedList/SingleLinkedList.ts +147 -0
- package/src/data-structures/LinkedList/SingleLinkedList/SingleLinkedNode.ts +10 -0
- package/src/data-structures/LoopedArray/LoopedArray.ts +182 -0
- package/src/data-structures/Queue/Queue.ts +92 -0
- package/src/data-structures/Stack/Stack.ts +92 -0
- package/src/demo/demo.bst.ts +67 -0
- package/src/demo/demo.graph.ts +246 -0
- package/src/demo/demo.linked-list.ts +78 -0
- package/src/demo/demo.looped-array.ts +104 -0
- package/src/demo/demo.queue.ts +40 -0
- package/src/demo/demo.stack.ts +40 -0
- package/src/demo/performance/bst-compare.ts +38 -0
- package/src/demo/performance/ds-compare.ts +58 -0
- package/src/demo/performance/sort-compare.ts +60 -0
- package/src/exports/algotirhms.ts +35 -0
- package/src/exports/constants.ts +3 -0
- package/src/exports/helpers.ts +13 -0
- package/src/exports/main.ts +21 -0
- package/src/exports/sorts.ts +7 -0
- package/src/exports/types.ts +53 -0
- package/src/exports/utils.ts +21 -0
- package/src/helpers/createBinaryTree.ts +24 -0
- package/src/helpers/createGraph.ts +24 -0
- package/src/helpers/createGraphFromMatrix.ts +47 -0
- package/src/helpers/createLinkedList.ts +24 -0
- package/src/index.ts +40 -0
- package/src/types/ArrayMatrix.ts +1 -0
- package/src/types/EnumBinarySearchTreeType.ts +4 -0
- package/src/types/EnumGraphTraversalType.ts +5 -0
- package/src/types/EnumGraphType.ts +4 -0
- package/src/types/EnumLinkedListType.ts +4 -0
- package/src/types/EnumRandomGenerationFormat.ts +4 -0
- package/src/types/EnumSortType.ts +7 -0
- package/src/types/EnumTreeTraversalType.ts +5 -0
- package/src/types/FnCompareTwo.ts +1 -0
- package/src/types/FnSort.ts +1 -0
- package/src/types/FnToMemoize.ts +1 -0
- package/src/types/IArrayFacade.ts +6 -0
- package/src/types/IBiDirectIterable.ts +6 -0
- package/src/types/IBiDirectIterator.ts +12 -0
- package/src/types/IBinaryTree.ts +13 -0
- package/src/types/IConvertableToArray.ts +4 -0
- package/src/types/IGraph.ts +16 -0
- package/src/types/IGraphCreator.ts +5 -0
- package/src/types/IGraphIterationStrategy.ts +6 -0
- package/src/types/IGraphIterator.ts +13 -0
- package/src/types/IIterable.ts +5 -0
- package/src/types/IIterator.ts +14 -0
- package/src/types/ILinearStorage.ts +11 -0
- package/src/types/ILinearStorageRA.ts +14 -0
- package/src/types/ILinkedList.ts +6 -0
- package/src/utils.ts +65 -0
- package/test/unit/algorithms/binary-search.test.ts +25 -0
- package/test/unit/algorithms/factorial.test.ts +43 -0
- package/test/unit/algorithms/fibonacci.test.ts +41 -0
- package/test/unit/algorithms/sorts.test.ts +74 -0
- package/test/unit/algorithms/transpose-matrix.test.ts +39 -0
- package/test/unit/data-structures/binary-tree/binary-search-tree.test.ts +230 -0
- package/test/unit/data-structures/graph/graph.create-from-matrix.test.ts +106 -0
- package/test/unit/data-structures/graph/graph.has-path.test.ts +115 -0
- package/test/unit/data-structures/graph/graph.presenter.lists.test.ts +76 -0
- package/test/unit/data-structures/graph/graph.presenter.matrix.test.ts +73 -0
- package/test/unit/data-structures/graph/graph.shortest-path.test.ts +207 -0
- package/test/unit/data-structures/graph/graph.test.ts +394 -0
- package/test/unit/data-structures/graph/graph.transpose.test.ts +52 -0
- package/test/unit/data-structures/linked-list/linked-list.test.ts +477 -0
- package/test/unit/data-structures/looped-array/looped-array.test.ts +387 -0
- package/test/unit/data-structures/queue/queue.test.ts +147 -0
- package/test/unit/data-structures/stack/stack.test.ts +155 -0
- package/tsconfig.json +18 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import AbstractGraph from "../../../../src/data-structures/Graph/AbstractGraph";
|
|
2
|
+
import UndirectedGraph from "../../../../src/data-structures/Graph/UndirectedGraph";
|
|
3
|
+
import DirectedGraph from "../../../../src/data-structures/Graph/DirectedGraph";
|
|
4
|
+
import IGraphIterationStrategy from "../../../../src/types/IGraphIterationStrategy";
|
|
5
|
+
import BFSIterationStrategy from "../../../../src/data-structures/Graph/strategy/BFSIterationStrategy";
|
|
6
|
+
import DFSIterationStrategy from "../../../../src/data-structures/Graph/strategy/DFSIterationStrategy";
|
|
7
|
+
|
|
8
|
+
import { hasPath } from "../../../../src/data-structures/Graph/searching/hasPath";
|
|
9
|
+
import { shortestPath } from "../../../../src/data-structures/Graph/searching/shortestPath";
|
|
10
|
+
import { EnumGraphTraversalType } from "../../../../src/types/EnumGraphTraversalType";
|
|
11
|
+
|
|
12
|
+
describe("Has Path Algorithm", () => {
|
|
13
|
+
const strategy: IGraphIterationStrategy<string> = new BFSIterationStrategy();
|
|
14
|
+
|
|
15
|
+
describe("Any type of traversal in empty graph", () => {
|
|
16
|
+
const graph: AbstractGraph<string> = new UndirectedGraph();
|
|
17
|
+
|
|
18
|
+
it("should throw when graph is empty", () => {
|
|
19
|
+
expect(() => {
|
|
20
|
+
shortestPath(graph, "-", "-", strategy);
|
|
21
|
+
}).toThrowError();
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
describe("Any type of traversal in non empty graph", () => {
|
|
26
|
+
const graph: AbstractGraph<string> = new UndirectedGraph();
|
|
27
|
+
|
|
28
|
+
graph.addVertex("Mike").addVertex("Bob").addEdge("Mike", "Bob");
|
|
29
|
+
|
|
30
|
+
it("should throw when first node does not exist", () => {
|
|
31
|
+
expect(() => {
|
|
32
|
+
shortestPath(graph, "Mike", "NOT_EXISTED_NODE", strategy);
|
|
33
|
+
}).toThrowError();
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it("should throw when second node does not exist", () => {
|
|
37
|
+
expect(() => {
|
|
38
|
+
shortestPath(graph, "NOT_EXISTED_NODE", "Bob", strategy);
|
|
39
|
+
}).toThrowError();
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
describe.each([EnumGraphTraversalType.BFS, EnumGraphTraversalType.DFS])(
|
|
44
|
+
"%s",
|
|
45
|
+
(strategyType: EnumGraphTraversalType) => {
|
|
46
|
+
let strategy: IGraphIterationStrategy<string>;
|
|
47
|
+
|
|
48
|
+
switch (strategyType) {
|
|
49
|
+
case EnumGraphTraversalType.BFS:
|
|
50
|
+
strategy = new BFSIterationStrategy();
|
|
51
|
+
break;
|
|
52
|
+
case EnumGraphTraversalType.DFS:
|
|
53
|
+
strategy = new DFSIterationStrategy();
|
|
54
|
+
break;
|
|
55
|
+
default:
|
|
56
|
+
throw new Error("Invalid search method");
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
describe("in undirected graph", () => {
|
|
60
|
+
const graph: AbstractGraph<string> = new UndirectedGraph();
|
|
61
|
+
|
|
62
|
+
graph
|
|
63
|
+
.addVertex("Mike")
|
|
64
|
+
.addVertex("Bob")
|
|
65
|
+
.addVertex("Lisa")
|
|
66
|
+
.addVertex("Aaron")
|
|
67
|
+
.addVertex("James")
|
|
68
|
+
.addVertex("Anna")
|
|
69
|
+
.addVertex("John")
|
|
70
|
+
.addEdge("Mike", "Bob")
|
|
71
|
+
.addEdge("Mike", "Lisa")
|
|
72
|
+
.addEdge("Lisa", "James")
|
|
73
|
+
.addEdge("Lisa", "Aaron")
|
|
74
|
+
.addEdge("James", "Aaron")
|
|
75
|
+
.addEdge("James", "Anna");
|
|
76
|
+
|
|
77
|
+
it("should find element if it has an edge", () => {
|
|
78
|
+
expect(hasPath(graph, "Mike", "Anna", strategy)).toBe(true);
|
|
79
|
+
});
|
|
80
|
+
it("should not find element if it has not an edge", () => {
|
|
81
|
+
expect(hasPath(graph, "Mike", "John", strategy)).toBe(false);
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
describe("in directed graph", () => {
|
|
86
|
+
const graph: AbstractGraph<string> = new DirectedGraph();
|
|
87
|
+
|
|
88
|
+
graph
|
|
89
|
+
.addVertex("Mike")
|
|
90
|
+
.addVertex("Bob")
|
|
91
|
+
.addVertex("Lisa")
|
|
92
|
+
.addVertex("Aaron")
|
|
93
|
+
.addVertex("James")
|
|
94
|
+
.addVertex("Anna")
|
|
95
|
+
.addVertex("John")
|
|
96
|
+
.addEdge("Mike", "Bob")
|
|
97
|
+
.addEdge("Mike", "Lisa")
|
|
98
|
+
.addEdge("Lisa", "James")
|
|
99
|
+
.addEdge("Lisa", "Aaron")
|
|
100
|
+
.addEdge("James", "Aaron")
|
|
101
|
+
.addEdge("James", "Anna");
|
|
102
|
+
|
|
103
|
+
it("should find element if it has an edge", () => {
|
|
104
|
+
expect(hasPath(graph, "Mike", "Anna", strategy)).toBe(true);
|
|
105
|
+
});
|
|
106
|
+
it("should not find element if it has not an edge", () => {
|
|
107
|
+
expect(hasPath(graph, "Mike", "John", strategy)).toBe(false);
|
|
108
|
+
});
|
|
109
|
+
it("should not find element if and edge has wrong direction", () => {
|
|
110
|
+
expect(hasPath(graph, "Lisa", "Mike", strategy)).toBe(false);
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
);
|
|
115
|
+
});
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import IGraph from "../../../../src/types/IGraph";
|
|
2
|
+
import UndirectedGraph from "../../../../src/data-structures/Graph/UndirectedGraph";
|
|
3
|
+
import DirectedGraph from "../../../../src/data-structures/Graph/DirectedGraph";
|
|
4
|
+
import { createGraph } from "../../../../src/helpers/createGraph";
|
|
5
|
+
import { EnumGraphType } from "../../../../src/types/EnumGraphType";
|
|
6
|
+
import { presenterAdjacencyLists } from "../../../../src/data-structures/Graph/presenter/presenterAdjacencyLists";
|
|
7
|
+
|
|
8
|
+
describe.each([EnumGraphType.Directed, EnumGraphType.Undirected])(
|
|
9
|
+
"%s graph",
|
|
10
|
+
(graphType: EnumGraphType) => {
|
|
11
|
+
describe("in empty graph", () => {
|
|
12
|
+
const graph: IGraph<number> = createGraph(graphType);
|
|
13
|
+
|
|
14
|
+
it("should return empty list", () => {
|
|
15
|
+
const map = presenterAdjacencyLists(graph);
|
|
16
|
+
const emptyMap = new Map<number, number>();
|
|
17
|
+
expect(map).toEqual(emptyMap);
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
if (graphType === EnumGraphType.Undirected) {
|
|
22
|
+
describe("in non-empty graph", () => {
|
|
23
|
+
const graph: IGraph<number> = new UndirectedGraph();
|
|
24
|
+
graph
|
|
25
|
+
.addVertex(1)
|
|
26
|
+
.addVertex(2)
|
|
27
|
+
.addVertex(3)
|
|
28
|
+
.addVertex(4)
|
|
29
|
+
.addEdge(1, 2)
|
|
30
|
+
.addEdge(1, 3)
|
|
31
|
+
.addEdge(3, 4);
|
|
32
|
+
|
|
33
|
+
it("should return correct list", () => {
|
|
34
|
+
const list = presenterAdjacencyLists(graph);
|
|
35
|
+
const expectedList = new Map<number, Array<number>>();
|
|
36
|
+
|
|
37
|
+
// eslint-disable-next-line
|
|
38
|
+
expectedList
|
|
39
|
+
.set(1, [2, 3])
|
|
40
|
+
.set(2, [1])
|
|
41
|
+
.set(3, [1, 4])
|
|
42
|
+
.set(4, [3]);
|
|
43
|
+
|
|
44
|
+
expect(list).toEqual(expectedList);
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
if (graphType === EnumGraphType.Directed) {
|
|
49
|
+
describe("in non-empty graph", () => {
|
|
50
|
+
const graph: IGraph<number> = new DirectedGraph();
|
|
51
|
+
graph
|
|
52
|
+
.addVertex(1)
|
|
53
|
+
.addVertex(2)
|
|
54
|
+
.addVertex(3)
|
|
55
|
+
.addVertex(4)
|
|
56
|
+
.addEdge(1, 2)
|
|
57
|
+
.addEdge(1, 3)
|
|
58
|
+
.addEdge(3, 4);
|
|
59
|
+
|
|
60
|
+
it("should return correct list", () => {
|
|
61
|
+
const list = presenterAdjacencyLists(graph);
|
|
62
|
+
const expectedList = new Map<number, Array<number>>();
|
|
63
|
+
|
|
64
|
+
// eslint-disable-next-line
|
|
65
|
+
expectedList
|
|
66
|
+
.set(1, [2, 3])
|
|
67
|
+
.set(2, [])
|
|
68
|
+
.set(3, [4])
|
|
69
|
+
.set(4, []);
|
|
70
|
+
|
|
71
|
+
expect(list).toEqual(expectedList);
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
);
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import IGraph from "../../../../src/types/IGraph";
|
|
2
|
+
import UndirectedGraph from "../../../../src/data-structures/Graph/UndirectedGraph";
|
|
3
|
+
import DirectedGraph from "../../../../src/data-structures/Graph/DirectedGraph";
|
|
4
|
+
import { createGraph } from "../../../../src/helpers/createGraph";
|
|
5
|
+
import { EnumGraphType } from "../../../../src/types/EnumGraphType";
|
|
6
|
+
import { presenterAdjacencyMatrix } from "../../../../src/data-structures/Graph/presenter/presenterAdjacencyMatrix";
|
|
7
|
+
|
|
8
|
+
describe("Graph Presenter Matrix", () => {
|
|
9
|
+
describe.each([EnumGraphType.Directed, EnumGraphType.Undirected])(
|
|
10
|
+
"%s graph",
|
|
11
|
+
(graphType: EnumGraphType) => {
|
|
12
|
+
describe("in empty graph", () => {
|
|
13
|
+
const graph: IGraph<string> = createGraph(graphType);
|
|
14
|
+
|
|
15
|
+
it("should return empty list", () => {
|
|
16
|
+
const matrix = presenterAdjacencyMatrix(graph);
|
|
17
|
+
|
|
18
|
+
expect(matrix).toEqual([]);
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
if (graphType === EnumGraphType.Undirected) {
|
|
23
|
+
describe("in non-empty graph", () => {
|
|
24
|
+
const graph: IGraph<number> = new UndirectedGraph();
|
|
25
|
+
graph
|
|
26
|
+
.addVertex(1)
|
|
27
|
+
.addVertex(2)
|
|
28
|
+
.addVertex(3)
|
|
29
|
+
.addVertex(4)
|
|
30
|
+
.addEdge(1, 2)
|
|
31
|
+
.addEdge(1, 3)
|
|
32
|
+
.addEdge(3, 4);
|
|
33
|
+
|
|
34
|
+
it("should return correct matrix", () => {
|
|
35
|
+
const matrix = presenterAdjacencyMatrix(graph);
|
|
36
|
+
|
|
37
|
+
expect(matrix).toEqual([
|
|
38
|
+
[0, 1, 1, 0],
|
|
39
|
+
[1, 0, 0, 0],
|
|
40
|
+
[1, 0, 0, 1],
|
|
41
|
+
[0, 0, 1, 0],
|
|
42
|
+
]);
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (graphType === EnumGraphType.Directed) {
|
|
48
|
+
describe("in non-empty graph", () => {
|
|
49
|
+
const graph: IGraph<number> = new DirectedGraph();
|
|
50
|
+
graph
|
|
51
|
+
.addVertex(1)
|
|
52
|
+
.addVertex(2)
|
|
53
|
+
.addVertex(3)
|
|
54
|
+
.addVertex(4)
|
|
55
|
+
.addEdge(1, 2)
|
|
56
|
+
.addEdge(1, 3)
|
|
57
|
+
.addEdge(3, 4);
|
|
58
|
+
|
|
59
|
+
it("should return correct matrix", () => {
|
|
60
|
+
const matrix = presenterAdjacencyMatrix(graph);
|
|
61
|
+
|
|
62
|
+
expect(matrix).toEqual([
|
|
63
|
+
[0, 1, 1, 0],
|
|
64
|
+
[0, 0, 0, 0],
|
|
65
|
+
[0, 0, 0, 1],
|
|
66
|
+
[0, 0, 0, 0],
|
|
67
|
+
]);
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
);
|
|
73
|
+
});
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import AbstractGraph from "../../../../src/data-structures/Graph/AbstractGraph";
|
|
2
|
+
import UndirectedGraph from "../../../../src/data-structures/Graph/UndirectedGraph";
|
|
3
|
+
import DirectedGraph from "../../../../src/data-structures/Graph/DirectedGraph";
|
|
4
|
+
import IGraphIterationStrategy from "../../../../src/types/IGraphIterationStrategy";
|
|
5
|
+
import BFSIterationStrategy from "../../../../src/data-structures/Graph/strategy/BFSIterationStrategy";
|
|
6
|
+
import DijkstraIterationStrategy from "../../../../src/data-structures/Graph/strategy/DijkstraIterationStrategy";
|
|
7
|
+
|
|
8
|
+
import { shortestPath } from "../../../../src/data-structures/Graph/searching/shortestPath";
|
|
9
|
+
import { EnumGraphTraversalType } from "../../../../src/types/EnumGraphTraversalType";
|
|
10
|
+
|
|
11
|
+
describe("Shortest path algorithm", () => {
|
|
12
|
+
const strategy: IGraphIterationStrategy<string> = new BFSIterationStrategy();
|
|
13
|
+
|
|
14
|
+
describe("Any type of traversal in empty graph", () => {
|
|
15
|
+
const graph: AbstractGraph<string> = new UndirectedGraph();
|
|
16
|
+
|
|
17
|
+
it("should throw when graph is empty", () => {
|
|
18
|
+
expect(() => {
|
|
19
|
+
shortestPath(graph, "-", "-", strategy);
|
|
20
|
+
}).toThrowError();
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
describe("Any type of traversal in non empty graph", () => {
|
|
25
|
+
const graph: AbstractGraph<string> = new UndirectedGraph();
|
|
26
|
+
|
|
27
|
+
graph.addVertex("Mike").addVertex("Bob").addEdge("Mike", "Bob");
|
|
28
|
+
|
|
29
|
+
it("should throw when first node does not exist", () => {
|
|
30
|
+
expect(() => {
|
|
31
|
+
shortestPath(graph, "Mike", "NOT_EXISTED_NODE", strategy);
|
|
32
|
+
}).toThrowError();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("should throw when second node does not exist", () => {
|
|
36
|
+
expect(() => {
|
|
37
|
+
shortestPath(graph, "NOT_EXISTED_NODE", "Bob", strategy);
|
|
38
|
+
}).toThrowError();
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it("should find correct path between neighbor nodes", () => {
|
|
42
|
+
expect(shortestPath(graph, "Mike", "Bob", strategy)).toEqual([
|
|
43
|
+
"Mike",
|
|
44
|
+
"Bob",
|
|
45
|
+
]);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
describe.each([EnumGraphTraversalType.DIJKSTRA])(
|
|
50
|
+
"Weighted graph by %s",
|
|
51
|
+
(strategyType: EnumGraphTraversalType) => {
|
|
52
|
+
let strategy: IGraphIterationStrategy<string>;
|
|
53
|
+
|
|
54
|
+
switch (strategyType) {
|
|
55
|
+
case EnumGraphTraversalType.DIJKSTRA: {
|
|
56
|
+
strategy = new DijkstraIterationStrategy();
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
default: {
|
|
60
|
+
throw new Error("Invalid search method");
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
describe("in undirected graph", () => {
|
|
65
|
+
const graph: AbstractGraph<string> = new UndirectedGraph();
|
|
66
|
+
|
|
67
|
+
graph
|
|
68
|
+
.addVertex("Mike")
|
|
69
|
+
.addVertex("Bob")
|
|
70
|
+
.addVertex("Lisa")
|
|
71
|
+
.addVertex("Aaron")
|
|
72
|
+
.addVertex("James")
|
|
73
|
+
.addVertex("Anna")
|
|
74
|
+
.addEdge("Mike", "Bob", 5)
|
|
75
|
+
.addEdge("Mike", "Lisa", 3)
|
|
76
|
+
.addEdge("Lisa", "Aaron", 3)
|
|
77
|
+
.addEdge("Lisa", "James", 3)
|
|
78
|
+
.addEdge("James", "Aaron", 3)
|
|
79
|
+
.addEdge("James", "Anna", 6)
|
|
80
|
+
.addEdge("Bob", "Anna", 15);
|
|
81
|
+
|
|
82
|
+
it("should find correct path between multiple nodes", () => {
|
|
83
|
+
/**
|
|
84
|
+
* Bob -> Mike (5) -> Anna (15) = 20
|
|
85
|
+
* Mike -> Lisa (3) -> James (3) -> Anna (6) = 12
|
|
86
|
+
*/
|
|
87
|
+
expect(shortestPath(graph, "Mike", "Anna", strategy)).toEqual([
|
|
88
|
+
"Mike",
|
|
89
|
+
"Lisa",
|
|
90
|
+
"James",
|
|
91
|
+
"Anna",
|
|
92
|
+
]);
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
describe("in directed graph", () => {
|
|
97
|
+
const graph: AbstractGraph<string> = new DirectedGraph();
|
|
98
|
+
|
|
99
|
+
graph
|
|
100
|
+
.addVertex("Mike")
|
|
101
|
+
.addVertex("Bob")
|
|
102
|
+
.addVertex("Lisa")
|
|
103
|
+
.addVertex("Aaron")
|
|
104
|
+
.addVertex("James")
|
|
105
|
+
.addVertex("Anna")
|
|
106
|
+
.addEdge("Mike", "Bob", 5)
|
|
107
|
+
.addEdge("Mike", "Lisa", 3)
|
|
108
|
+
.addEdge("Lisa", "Aaron", 3)
|
|
109
|
+
.addEdge("Aaron", "James", 3)
|
|
110
|
+
.addEdge("James", "Lisa", 10)
|
|
111
|
+
.addEdge("James", "Aaron", 10)
|
|
112
|
+
.addEdge("James", "Anna", 6)
|
|
113
|
+
.addEdge("Bob", "Anna", 15);
|
|
114
|
+
|
|
115
|
+
it("should find correct path between multiple nodes", () => {
|
|
116
|
+
/**
|
|
117
|
+
* Bob -> Mike (5) -> Anna (15) = 20
|
|
118
|
+
* Mike -> Lisa (3) -> Aaron (3) -> James (3) -> Anna (6) = 15
|
|
119
|
+
*/
|
|
120
|
+
expect(shortestPath(graph, "Mike", "Anna", strategy)).toEqual([
|
|
121
|
+
"Mike",
|
|
122
|
+
"Lisa",
|
|
123
|
+
"Aaron",
|
|
124
|
+
"James",
|
|
125
|
+
"Anna",
|
|
126
|
+
]);
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
describe.each([EnumGraphTraversalType.BFS])(
|
|
133
|
+
"Unweighted graph by %s",
|
|
134
|
+
(strategyType: EnumGraphTraversalType) => {
|
|
135
|
+
let strategy: IGraphIterationStrategy<string>;
|
|
136
|
+
|
|
137
|
+
switch (strategyType) {
|
|
138
|
+
case EnumGraphTraversalType.BFS: {
|
|
139
|
+
strategy = new BFSIterationStrategy();
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
default: {
|
|
143
|
+
throw new Error("Invalid search method");
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
describe("in undirected graph", () => {
|
|
148
|
+
const graph: AbstractGraph<string> = new UndirectedGraph();
|
|
149
|
+
|
|
150
|
+
graph
|
|
151
|
+
.addVertex("Mike")
|
|
152
|
+
.addVertex("Bob")
|
|
153
|
+
.addVertex("Lisa")
|
|
154
|
+
.addVertex("Aaron")
|
|
155
|
+
.addVertex("James")
|
|
156
|
+
.addVertex("Anna")
|
|
157
|
+
.addEdge("Mike", "Bob")
|
|
158
|
+
.addEdge("Mike", "Aaron")
|
|
159
|
+
.addEdge("Mike", "Lisa")
|
|
160
|
+
.addEdge("Lisa", "James")
|
|
161
|
+
.addEdge("Lisa", "Aaron")
|
|
162
|
+
.addEdge("James", "Aaron")
|
|
163
|
+
.addEdge("James", "Anna")
|
|
164
|
+
.addEdge("Aaron", "Anna");
|
|
165
|
+
|
|
166
|
+
it("should find correct path between multiple nodes", () => {
|
|
167
|
+
/**
|
|
168
|
+
* Mike -> Aaron -> Lisa -> James -> Anna
|
|
169
|
+
* Mike -> Aaron -> Anna
|
|
170
|
+
* Mike -> Lisa -> James -> Anna
|
|
171
|
+
*/
|
|
172
|
+
expect(shortestPath(graph, "Mike", "Anna", strategy)).toEqual([
|
|
173
|
+
"Mike",
|
|
174
|
+
"Aaron",
|
|
175
|
+
"Anna",
|
|
176
|
+
]);
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
describe("in directed graph", () => {
|
|
181
|
+
const graph: AbstractGraph<string> = new DirectedGraph();
|
|
182
|
+
|
|
183
|
+
graph
|
|
184
|
+
.addVertex("Mike")
|
|
185
|
+
.addVertex("Bob")
|
|
186
|
+
.addVertex("Lisa")
|
|
187
|
+
.addVertex("Aaron")
|
|
188
|
+
.addVertex("James")
|
|
189
|
+
.addVertex("Anna")
|
|
190
|
+
.addEdge("Mike", "Bob")
|
|
191
|
+
.addEdge("Mike", "Lisa")
|
|
192
|
+
.addEdge("Lisa", "James")
|
|
193
|
+
.addEdge("James", "Aaron")
|
|
194
|
+
.addEdge("Aaron", "Anna")
|
|
195
|
+
.addEdge("Lisa", "Anna");
|
|
196
|
+
|
|
197
|
+
it("should find correct path between multiple nodes", () => {
|
|
198
|
+
expect(shortestPath(graph, "Mike", "Anna", strategy)).toEqual([
|
|
199
|
+
"Mike",
|
|
200
|
+
"Lisa",
|
|
201
|
+
"Anna",
|
|
202
|
+
]);
|
|
203
|
+
});
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
);
|
|
207
|
+
});
|