@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,14 @@
|
|
|
1
|
+
import ILinearStorage from "./ILinearStorage";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Interface extends default linear storage with methods that allows read/write operations for all storage elements
|
|
5
|
+
* RA - randomly accessible
|
|
6
|
+
*/
|
|
7
|
+
export default interface ILinearStorageRA<T> extends ILinearStorage<T> {
|
|
8
|
+
peekFromStart(): T;
|
|
9
|
+
peekByIndex(index: number): T;
|
|
10
|
+
unshift(value: T): void;
|
|
11
|
+
pushFromIndex(value: T, fromIndex: number): void;
|
|
12
|
+
shift(): T;
|
|
13
|
+
deleteFromIndex(fromIndex: number): T;
|
|
14
|
+
}
|
package/src/utils.ts
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { performance } from "perf_hooks";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Will find min value in the whole array and return its index
|
|
5
|
+
*/
|
|
6
|
+
export const getMinIndex = (arr: Array<number>): number => {
|
|
7
|
+
return arr.reduce((minIndex, item, index): number => {
|
|
8
|
+
return item < arr[minIndex] ? index : minIndex;
|
|
9
|
+
}, 0);
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Will find min value in range between fromIndex and end of array
|
|
14
|
+
*/
|
|
15
|
+
export const getMinIndexFromIndex = (
|
|
16
|
+
arr: Array<number>,
|
|
17
|
+
fromIndex: number
|
|
18
|
+
): number => {
|
|
19
|
+
return fromIndex + getMinIndex(arr.slice(fromIndex));
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Will swap two items in array
|
|
24
|
+
* @example swapArrayItems([2,3,5], 1, 2) -> [2,5,3]
|
|
25
|
+
*/
|
|
26
|
+
export const swapArrayItems = <T>(
|
|
27
|
+
arr: Array<T>,
|
|
28
|
+
leftIndex: number,
|
|
29
|
+
rightIndex: number
|
|
30
|
+
): void => {
|
|
31
|
+
if (leftIndex !== rightIndex) {
|
|
32
|
+
const temp: T = arr[leftIndex];
|
|
33
|
+
arr[leftIndex] = arr[rightIndex];
|
|
34
|
+
arr[rightIndex] = temp;
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Get random number in range
|
|
40
|
+
*/
|
|
41
|
+
export const randomizeNumberInRange = (min: number, max: number): number =>
|
|
42
|
+
Math.floor(Math.random() * (max - min)) + min;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Round number to 3 digits after
|
|
46
|
+
*/
|
|
47
|
+
export const roundNumber = (num: number): number =>
|
|
48
|
+
Math.round(num * 1000) / 1000;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Get time execution of function
|
|
52
|
+
*/
|
|
53
|
+
export const perf = (fn: () => void): number => {
|
|
54
|
+
const perfStart = performance.now();
|
|
55
|
+
fn();
|
|
56
|
+
const perfEnd = performance.now();
|
|
57
|
+
return perfEnd - perfStart;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Get time execution of function
|
|
62
|
+
*/
|
|
63
|
+
export const perfAsync = async (fn: () => void): Promise<number> => {
|
|
64
|
+
return Promise.resolve(perf(fn));
|
|
65
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { binarySearch } from "../../../src/algorithms/binary-search";
|
|
2
|
+
|
|
3
|
+
describe("Binary search", () => {
|
|
4
|
+
it("should find in positive 100 elements", () => {
|
|
5
|
+
const arr: Array<number> = [];
|
|
6
|
+
for (let i = 0; i < 100; i++) arr.push(i + 1);
|
|
7
|
+
const foundElement = binarySearch(arr, 97);
|
|
8
|
+
|
|
9
|
+
expect(foundElement).toBe(96);
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it("should find in negative 100 elements", () => {
|
|
13
|
+
const arr: Array<number> = [];
|
|
14
|
+
for (let i = 0; i < 100; i++) arr.push(-100 + i - 1);
|
|
15
|
+
const foundElement = binarySearch(arr, -97);
|
|
16
|
+
|
|
17
|
+
expect(foundElement).toBe(4);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it("should return null in empty list", () => {
|
|
21
|
+
const arr: Array<number> = [];
|
|
22
|
+
|
|
23
|
+
expect(binarySearch(arr, 10)).toBeNull();
|
|
24
|
+
});
|
|
25
|
+
});
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import {
|
|
2
|
+
factorial,
|
|
3
|
+
memoizedFactorial,
|
|
4
|
+
} from "../../../src/algorithms/factorial";
|
|
5
|
+
|
|
6
|
+
describe("Factorial", () => {
|
|
7
|
+
const results = new Map<number, number>();
|
|
8
|
+
const resultsBigValues = new Map<number, number>();
|
|
9
|
+
|
|
10
|
+
results
|
|
11
|
+
.set(5, 120)
|
|
12
|
+
.set(6, 720)
|
|
13
|
+
.set(10, 3628800)
|
|
14
|
+
.set(15, 1307674368000)
|
|
15
|
+
.set(20, 2432902008176640000)
|
|
16
|
+
.set(25, 15511210043330985984000000);
|
|
17
|
+
|
|
18
|
+
resultsBigValues
|
|
19
|
+
.set(35, 1.0333147966386144e40)
|
|
20
|
+
.set(45, 1.1962222086548019e56)
|
|
21
|
+
.set(77, 1.4518309202828584e113)
|
|
22
|
+
.set(90, 1.4857159644817607e138)
|
|
23
|
+
.set(99, 9.33262154439441e155)
|
|
24
|
+
.set(100, 9.33262154439441e157);
|
|
25
|
+
|
|
26
|
+
const resultsKeys = Array.from(results.keys());
|
|
27
|
+
const resultsBigValuesKeys = Array.from(resultsBigValues.keys());
|
|
28
|
+
|
|
29
|
+
describe("without memoize", () => {
|
|
30
|
+
test.each(resultsKeys)("with n = %i", (n) => {
|
|
31
|
+
expect(factorial(n)).toBe(results.get(n));
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
describe("with memoize", () => {
|
|
36
|
+
test.each(resultsKeys)("with n = %i", (n) => {
|
|
37
|
+
expect(memoizedFactorial(n)).toBe(results.get(n));
|
|
38
|
+
});
|
|
39
|
+
test.each(resultsBigValuesKeys)("with n = %i", (n) => {
|
|
40
|
+
expect(memoizedFactorial(n)).toBe(resultsBigValues.get(n));
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import {
|
|
2
|
+
fibonacci,
|
|
3
|
+
memoizedFibonacci,
|
|
4
|
+
} from "../../../src/algorithms/fibonacci";
|
|
5
|
+
|
|
6
|
+
describe("Fibonacci", () => {
|
|
7
|
+
const results = new Map<number, number>();
|
|
8
|
+
const resultsBigValues = new Map<number, number>();
|
|
9
|
+
|
|
10
|
+
results
|
|
11
|
+
.set(5, 5)
|
|
12
|
+
.set(6, 8)
|
|
13
|
+
.set(10, 55)
|
|
14
|
+
.set(15, 610)
|
|
15
|
+
.set(20, 6765)
|
|
16
|
+
.set(25, 75025);
|
|
17
|
+
|
|
18
|
+
resultsBigValues
|
|
19
|
+
.set(40, 102334155)
|
|
20
|
+
.set(45, 1134903170)
|
|
21
|
+
.set(77, 5527939700884757)
|
|
22
|
+
.set(90, 2880067194370816120);
|
|
23
|
+
|
|
24
|
+
const resultsKeys = Array.from(results.keys());
|
|
25
|
+
const resultsBigValuesKeys = Array.from(resultsBigValues.keys());
|
|
26
|
+
|
|
27
|
+
describe("without memoize", () => {
|
|
28
|
+
test.each(resultsKeys)("with n = %i", (n) => {
|
|
29
|
+
expect(fibonacci(n)).toBe(results.get(n));
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
describe("with memoize", () => {
|
|
34
|
+
test.each(resultsKeys)("with n = %i", (n) => {
|
|
35
|
+
expect(memoizedFibonacci(n)).toBe(results.get(n));
|
|
36
|
+
});
|
|
37
|
+
test.each(resultsBigValuesKeys)("with n = %i", (n) => {
|
|
38
|
+
expect(memoizedFibonacci(n)).toBe(resultsBigValues.get(n));
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
});
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { quickSort } from "../../../src/algorithms/sorts/quick-sort";
|
|
2
|
+
import { mergeSort } from "../../../src/algorithms/sorts/merge-sort";
|
|
3
|
+
import { selectSort } from "../../../src/algorithms/sorts/select-sort";
|
|
4
|
+
import { bubbleSort } from "../../../src/algorithms/sorts/bubble-sort";
|
|
5
|
+
import { insertionSort } from "../../../src/algorithms/sorts/insertion-sort";
|
|
6
|
+
import { randomizeArray } from "../../../src/demo/performance/sort-compare";
|
|
7
|
+
import { EnumSortType } from "../../../src/types/EnumSortType";
|
|
8
|
+
|
|
9
|
+
const createSortFunction = (
|
|
10
|
+
sortType: string
|
|
11
|
+
): ((arr: Array<number>) => Array<number>) => {
|
|
12
|
+
switch (sortType) {
|
|
13
|
+
case EnumSortType.Quick:
|
|
14
|
+
return quickSort;
|
|
15
|
+
case EnumSortType.Merge:
|
|
16
|
+
return mergeSort;
|
|
17
|
+
case EnumSortType.Selection:
|
|
18
|
+
return selectSort;
|
|
19
|
+
case EnumSortType.Bubble:
|
|
20
|
+
return bubbleSort;
|
|
21
|
+
case EnumSortType.Insertion:
|
|
22
|
+
return insertionSort;
|
|
23
|
+
default:
|
|
24
|
+
throw new Error("Invalid sort type");
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
describe.each([
|
|
29
|
+
EnumSortType.Merge,
|
|
30
|
+
EnumSortType.Quick,
|
|
31
|
+
EnumSortType.Bubble,
|
|
32
|
+
EnumSortType.Insertion,
|
|
33
|
+
EnumSortType.Selection,
|
|
34
|
+
])("%s sort", (sortStrategyType: EnumSortType) => {
|
|
35
|
+
const sort = createSortFunction(sortStrategyType);
|
|
36
|
+
|
|
37
|
+
it("should correctly sort with random numbers", () => {
|
|
38
|
+
const notSortedArr: Array<number> = randomizeArray(100, 500);
|
|
39
|
+
|
|
40
|
+
const sortedArr = [...notSortedArr].sort((a: number, b: number) => {
|
|
41
|
+
if (a > b) return 1;
|
|
42
|
+
if (a < b) return -1;
|
|
43
|
+
return 0;
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
expect(sort(notSortedArr)).toEqual(sortedArr);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it("should correctly sort an empty array", () => {
|
|
50
|
+
const emptyArr: Array<number> = [];
|
|
51
|
+
|
|
52
|
+
expect(sort(emptyArr)).toEqual(emptyArr);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it("should correctly sort already sorted array", () => {
|
|
56
|
+
const sortedArr = [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5];
|
|
57
|
+
|
|
58
|
+
expect(sort(sortedArr)).toEqual(sortedArr);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it("should correctly sort an array with repeated numbers", () => {
|
|
62
|
+
const notSortedArr = [7, 2, 1, 2, 7];
|
|
63
|
+
const sortedArr = [1, 2, 2, 7, 7];
|
|
64
|
+
|
|
65
|
+
expect(sort(notSortedArr)).toEqual(sortedArr);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it("should correctly sort an array with float numbers", () => {
|
|
69
|
+
const notSortedArr = [2.5, -2.5, 0, 5.5, -5.5];
|
|
70
|
+
const sortedArr = [-5.5, -2.5, 0, 2.5, 5.5];
|
|
71
|
+
|
|
72
|
+
expect(sort(notSortedArr)).toEqual(sortedArr);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { transposeMatrix } from "../../../src/algorithms/transpose-matrix";
|
|
2
|
+
|
|
3
|
+
describe("transpose matrix", () => {
|
|
4
|
+
it("should throw when array is not a matrix", () => {
|
|
5
|
+
const srcMatrix = [
|
|
6
|
+
[0, 1],
|
|
7
|
+
[1, 0],
|
|
8
|
+
[0, 1],
|
|
9
|
+
];
|
|
10
|
+
|
|
11
|
+
expect(() => {
|
|
12
|
+
transposeMatrix(srcMatrix);
|
|
13
|
+
}).toThrowError();
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it("should transpose matrix correctly", () => {
|
|
17
|
+
const srcMatrix = [
|
|
18
|
+
[0, 1, 1],
|
|
19
|
+
[0, 0, 1],
|
|
20
|
+
[1, 0, 0],
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
expect(transposeMatrix(srcMatrix)).toEqual([
|
|
24
|
+
[0, 0, 1],
|
|
25
|
+
[1, 0, 0],
|
|
26
|
+
[1, 1, 0],
|
|
27
|
+
]);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it("should return same matrix in case of symmetric matrix", () => {
|
|
31
|
+
const srcMatrix = [
|
|
32
|
+
[0, 1, 0],
|
|
33
|
+
[1, 0, 1],
|
|
34
|
+
[0, 1, 0],
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
expect(transposeMatrix(srcMatrix)).toEqual(srcMatrix);
|
|
38
|
+
});
|
|
39
|
+
});
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { EnumBinarySearchTreeType } from "../../../../src/types/EnumBinarySearchTreeType";
|
|
2
|
+
import { createBinaryTree } from "../../../../src/helpers/createBinaryTree";
|
|
3
|
+
import { EnumTreeTraversalType } from "../../../../src/types/EnumTreeTraversalType";
|
|
4
|
+
|
|
5
|
+
describe.each([
|
|
6
|
+
EnumBinarySearchTreeType.BST,
|
|
7
|
+
EnumBinarySearchTreeType.RANDOMIZED_BST,
|
|
8
|
+
])("%s", (treeType: EnumBinarySearchTreeType) => {
|
|
9
|
+
describe("constructor", () => {
|
|
10
|
+
it("should create an empty instance", () => {
|
|
11
|
+
const tree = createBinaryTree(treeType);
|
|
12
|
+
|
|
13
|
+
expect(tree.length()).toBe(0);
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
describe("method insert", function () {
|
|
18
|
+
it("should have added elements to be in order", () => {
|
|
19
|
+
const tree = createBinaryTree(treeType);
|
|
20
|
+
tree.insert(5);
|
|
21
|
+
tree.insert(15);
|
|
22
|
+
tree.insert(10);
|
|
23
|
+
tree.insert(0);
|
|
24
|
+
tree.insert(20);
|
|
25
|
+
|
|
26
|
+
expect(tree.traverse(EnumTreeTraversalType.InOrder)).toEqual([
|
|
27
|
+
0,
|
|
28
|
+
5,
|
|
29
|
+
10,
|
|
30
|
+
15,
|
|
31
|
+
20,
|
|
32
|
+
]);
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
describe("method length", function () {
|
|
37
|
+
describe("when tree is non empty", () => {
|
|
38
|
+
describe("after adding", () => {
|
|
39
|
+
it("should return updated length value", () => {
|
|
40
|
+
const tree = createBinaryTree(treeType);
|
|
41
|
+
tree.insert(5);
|
|
42
|
+
tree.insert(15);
|
|
43
|
+
tree.insert(10);
|
|
44
|
+
|
|
45
|
+
expect(tree.length()).toBe(3);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
describe("after deleting", () => {
|
|
50
|
+
it("should return updated length value", () => {
|
|
51
|
+
const tree = createBinaryTree(treeType);
|
|
52
|
+
tree.insert(5);
|
|
53
|
+
tree.insert(15);
|
|
54
|
+
tree.insert(10);
|
|
55
|
+
tree.delete(5);
|
|
56
|
+
|
|
57
|
+
expect(tree.length()).toBe(2);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
describe("when tree is empty", () => {
|
|
63
|
+
it("should return zero value", () => {
|
|
64
|
+
const tree = createBinaryTree(treeType);
|
|
65
|
+
|
|
66
|
+
expect(tree.length()).toBe(0);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
describe("method height", function () {
|
|
72
|
+
describe("when tree is non empty", () => {
|
|
73
|
+
describe("after adding", () => {
|
|
74
|
+
const tree = createBinaryTree(treeType);
|
|
75
|
+
const length = 300;
|
|
76
|
+
const arraySrc = Array.from(Array(length).keys());
|
|
77
|
+
const arrayShuffled = arraySrc
|
|
78
|
+
.map((item) => item)
|
|
79
|
+
.sort(() => Math.random() - 0.5);
|
|
80
|
+
arrayShuffled.forEach((num, index) => {
|
|
81
|
+
tree.insert(num);
|
|
82
|
+
});
|
|
83
|
+
const height = tree.height();
|
|
84
|
+
|
|
85
|
+
it("should be equal or greater than log(length)", () => {
|
|
86
|
+
const expected = Math.ceil(Math.log2(length));
|
|
87
|
+
expect(height).toBeGreaterThanOrEqual(expected);
|
|
88
|
+
});
|
|
89
|
+
it("should be equal or smaller than length", () => {
|
|
90
|
+
expect(height).toBeLessThanOrEqual(tree.length());
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
describe("when tree is empty", () => {
|
|
96
|
+
const tree = createBinaryTree(treeType);
|
|
97
|
+
|
|
98
|
+
it("should return zero value", () => {
|
|
99
|
+
expect(tree.height()).toBe(0);
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
describe("method has", function () {
|
|
105
|
+
const tree = createBinaryTree(treeType);
|
|
106
|
+
tree.insert(5);
|
|
107
|
+
|
|
108
|
+
it("should return true when value exists", () => {
|
|
109
|
+
expect(tree.has(5)).toBe(true);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it("should return false when value does not exist", () => {
|
|
113
|
+
expect(tree.has(10)).toBe(false);
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
describe("method delete", function () {
|
|
118
|
+
const tree = createBinaryTree(treeType);
|
|
119
|
+
tree.insert(5);
|
|
120
|
+
tree.insert(12);
|
|
121
|
+
tree.insert(7);
|
|
122
|
+
tree.insert(20);
|
|
123
|
+
|
|
124
|
+
tree.delete(12);
|
|
125
|
+
|
|
126
|
+
it("should delete element from the tree", () => {
|
|
127
|
+
expect(tree.has(12)).toBe(false);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
it("should restructure the tree correctly", () => {
|
|
131
|
+
expect(tree.traverse(EnumTreeTraversalType.InOrder)).toEqual([5, 7, 20]);
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
describe("method max", function () {
|
|
136
|
+
const tree = createBinaryTree(treeType);
|
|
137
|
+
tree.insert(5);
|
|
138
|
+
tree.insert(12);
|
|
139
|
+
tree.insert(7);
|
|
140
|
+
tree.insert(20);
|
|
141
|
+
|
|
142
|
+
it("should be in order", () => {
|
|
143
|
+
expect(tree.max()).toBe(20);
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
describe("method min", function () {
|
|
148
|
+
const tree = createBinaryTree(treeType);
|
|
149
|
+
tree.insert(5);
|
|
150
|
+
tree.insert(12);
|
|
151
|
+
tree.insert(7);
|
|
152
|
+
tree.insert(20);
|
|
153
|
+
tree.insert(2);
|
|
154
|
+
|
|
155
|
+
it("should be in order", () => {
|
|
156
|
+
expect(tree.min()).toBe(2);
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
if (treeType === EnumBinarySearchTreeType.BST) {
|
|
161
|
+
describe("method subtree", function () {
|
|
162
|
+
const bst = createBinaryTree(treeType);
|
|
163
|
+
bst.insert(22);
|
|
164
|
+
bst.insert(4);
|
|
165
|
+
bst.insert(16);
|
|
166
|
+
bst.insert(19);
|
|
167
|
+
bst.insert(15);
|
|
168
|
+
bst.insert(8);
|
|
169
|
+
bst.insert(23);
|
|
170
|
+
const subtree = bst.subtree(16);
|
|
171
|
+
|
|
172
|
+
it("should correctly create subtree", () => {
|
|
173
|
+
expect(subtree.traverse(EnumTreeTraversalType.InOrder)).toEqual([
|
|
174
|
+
8,
|
|
175
|
+
15,
|
|
176
|
+
16,
|
|
177
|
+
19,
|
|
178
|
+
]);
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
describe("method traverse", function () {
|
|
183
|
+
const bst = createBinaryTree(treeType);
|
|
184
|
+
|
|
185
|
+
bst.insert(22);
|
|
186
|
+
bst.insert(4);
|
|
187
|
+
bst.insert(16);
|
|
188
|
+
bst.insert(19);
|
|
189
|
+
bst.insert(15);
|
|
190
|
+
bst.insert(8);
|
|
191
|
+
bst.insert(23);
|
|
192
|
+
|
|
193
|
+
it("should correctly convert in-order type", () => {
|
|
194
|
+
expect(bst.traverse(EnumTreeTraversalType.InOrder)).toEqual([
|
|
195
|
+
4,
|
|
196
|
+
8,
|
|
197
|
+
15,
|
|
198
|
+
16,
|
|
199
|
+
19,
|
|
200
|
+
22,
|
|
201
|
+
23,
|
|
202
|
+
]);
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
it("should correctly convert pre-order type", () => {
|
|
206
|
+
expect(bst.traverse(EnumTreeTraversalType.PreOrder)).toEqual([
|
|
207
|
+
22,
|
|
208
|
+
4,
|
|
209
|
+
8,
|
|
210
|
+
15,
|
|
211
|
+
16,
|
|
212
|
+
19,
|
|
213
|
+
23,
|
|
214
|
+
]);
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
it("should correctly convert post-order type", () => {
|
|
218
|
+
expect(bst.traverse(EnumTreeTraversalType.PostOrder)).toEqual([
|
|
219
|
+
4,
|
|
220
|
+
8,
|
|
221
|
+
15,
|
|
222
|
+
16,
|
|
223
|
+
19,
|
|
224
|
+
23,
|
|
225
|
+
22,
|
|
226
|
+
]);
|
|
227
|
+
});
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
});
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { EnumGraphType } from "../../../../src/types/EnumGraphType";
|
|
2
|
+
import { createGraphFromMatrix } from "../../../../src/helpers/createGraphFromMatrix";
|
|
3
|
+
import { ArrayMatrix } from "../../../../src/types/ArrayMatrix";
|
|
4
|
+
import IGraph from "../../../../src/types/IGraph";
|
|
5
|
+
|
|
6
|
+
describe("in Directed graph", () => {
|
|
7
|
+
/**
|
|
8
|
+
* Get graph adjacency matrix N x N
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
*
|
|
12
|
+
* Directed graph:
|
|
13
|
+
* - Bob [Maria]
|
|
14
|
+
* - Maria [Bob, John]
|
|
15
|
+
* - John []
|
|
16
|
+
*
|
|
17
|
+
* Its matrix:
|
|
18
|
+
* | Bob | Maria | John |
|
|
19
|
+
* Bob | 0 | 1 | 0 |
|
|
20
|
+
* Maria | 1 | 0 | 1 |
|
|
21
|
+
* John | 0 | 0 | 0 |
|
|
22
|
+
*/
|
|
23
|
+
describe("created graph", () => {
|
|
24
|
+
const fieldsList: Array<string> = ["Bob", "Maria", "John"];
|
|
25
|
+
|
|
26
|
+
const matrix: ArrayMatrix = [
|
|
27
|
+
[0, 1, 0],
|
|
28
|
+
[1, 0, 1],
|
|
29
|
+
[0, 0, 0],
|
|
30
|
+
];
|
|
31
|
+
const graph: IGraph<string> = createGraphFromMatrix<string>(
|
|
32
|
+
matrix,
|
|
33
|
+
fieldsList,
|
|
34
|
+
EnumGraphType.Directed
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
it("should contain all vertices", () => {
|
|
38
|
+
expect(graph.vertices()).toEqual(fieldsList);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it("should contain all edges", () => {
|
|
42
|
+
expect(graph.hasEdge("Bob", "Bob")).toBe(false);
|
|
43
|
+
expect(graph.hasEdge("Bob", "Maria")).toBe(true);
|
|
44
|
+
expect(graph.hasEdge("Bob", "John")).toBe(false);
|
|
45
|
+
|
|
46
|
+
expect(graph.hasEdge("Maria", "Maria")).toBe(false);
|
|
47
|
+
expect(graph.hasEdge("Maria", "Bob")).toBe(true);
|
|
48
|
+
expect(graph.hasEdge("Maria", "John")).toBe(true);
|
|
49
|
+
|
|
50
|
+
expect(graph.hasEdge("John", "John")).toBe(false);
|
|
51
|
+
expect(graph.hasEdge("John", "Bob")).toBe(false);
|
|
52
|
+
expect(graph.hasEdge("John", "Maria")).toBe(false);
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
describe("in Undirected graph", () => {
|
|
58
|
+
/**
|
|
59
|
+
* Get graph adjacency matrix N x N
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
*
|
|
63
|
+
* Directed graph:
|
|
64
|
+
* - Bob [Maria]
|
|
65
|
+
* - Maria [Bob, John]
|
|
66
|
+
* - John []
|
|
67
|
+
*
|
|
68
|
+
* Its matrix:
|
|
69
|
+
* | Bob | Maria | John |
|
|
70
|
+
* Bob | 0 | 1 | 0 |
|
|
71
|
+
* Maria | 1 | 0 | 1 |
|
|
72
|
+
* John | 0 | 1 | 0 |
|
|
73
|
+
*/
|
|
74
|
+
describe("created graph", () => {
|
|
75
|
+
const fieldsList: Array<string> = ["Bob", "Maria", "John"];
|
|
76
|
+
|
|
77
|
+
const matrix: ArrayMatrix = [
|
|
78
|
+
[0, 1, 0],
|
|
79
|
+
[1, 0, 1],
|
|
80
|
+
[0, 1, 0],
|
|
81
|
+
];
|
|
82
|
+
const graph: IGraph<string> = createGraphFromMatrix<string>(
|
|
83
|
+
matrix,
|
|
84
|
+
fieldsList,
|
|
85
|
+
EnumGraphType.Undirected
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
it("should contain all vertices", () => {
|
|
89
|
+
expect(graph.vertices()).toEqual(fieldsList);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it("should contain all edges", () => {
|
|
93
|
+
expect(graph.hasEdge("Bob", "Bob")).toBe(false);
|
|
94
|
+
expect(graph.hasEdge("Bob", "Maria")).toBe(true);
|
|
95
|
+
expect(graph.hasEdge("Bob", "John")).toBe(false);
|
|
96
|
+
|
|
97
|
+
expect(graph.hasEdge("Maria", "Maria")).toBe(false);
|
|
98
|
+
expect(graph.hasEdge("Maria", "Bob")).toBe(true);
|
|
99
|
+
expect(graph.hasEdge("Maria", "John")).toBe(true);
|
|
100
|
+
|
|
101
|
+
expect(graph.hasEdge("John", "John")).toBe(false);
|
|
102
|
+
expect(graph.hasEdge("John", "Bob")).toBe(false);
|
|
103
|
+
expect(graph.hasEdge("John", "Maria")).toBe(true);
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
});
|