mirror of
https://github.com/zrwusa/data-structure-typed.git
synced 2024-11-23 12:54:04 +00:00
MIrror of DST.
https://data-structure-typed-docs.vercel.app
.idea | ||
src | ||
tests/unit/data-structures | ||
.dependency-cruiser.js | ||
.gitignore | ||
.npmignore | ||
jest.config.js | ||
package-lock.json | ||
package.json | ||
README.md | ||
rename_clear_files.sh | ||
tsconfig.json |
What
Brief
Javascript & TypeScript Data Structure Library.
Meticulously crafted to empower developers with a versatile set of essential data structures. Our library includes a wide range of data structures
Data Structures
Data Structure | Unit Test | Performance Test | API Documentation | Implemented |
---|---|---|---|---|
Binary Tree | Binary Tree | |||
Binary Search Tree (BST) | BST | |||
AVL Tree | AVLTree | |||
Tree Multiset | TreeMultiSet | |||
Segment Tree | SegmentTree | |||
Binary Indexed Tree | BinaryIndexedTree | |||
Graph | AbstractGraph | |||
Directed Graph | DirectedGraph | |||
Undirected Graph | UndirectedGraph | |||
Linked List | SinglyLinkedList | |||
Singly Linked List | SinglyLinkedList | |||
Doubly Linked List | DoublyLinkedList | |||
Queue | Queue | |||
Object Deque | ObjectDeque | |||
Array Deque | ArrayDeque | |||
Stack | Stack | |||
Coordinate Set | CoordinateSet | |||
Coordinate Map | CoordinateMap | |||
Heap | Heap | |||
Priority Queue | PriorityQueue | |||
Max Priority Queue | MaxPriorityQueue | |||
Min Priority Queue | MinPriorityQueue | |||
Trie | Trie |
Algorithms list only a few out, you can discover more in API docs
DFS, DFSIterative, BFS, morris, Bellman-Ford Algorithm, Dijkstra's Algorithm, Floyd-Warshall Algorithm, Tarjan's Algorithm
How
install
yarn
yarn add data-structure-typed
npm
npm install data-structure-typed
Binary Search Tree (BST) snippet
import {BST, BSTNode} from 'data-structure-typed';
const tree = new BST();
expect(tree).toBeInstanceOf(BST);
const ids = [11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5];
tree.addMany(ids);
expect(tree.root).toBeInstanceOf(BSTNode);
if (tree.root) expect(tree.root.id).toBe(11);
expect(tree.count).toBe(16);
expect(tree.has(6)).toBe(true);
const node6 = tree.get(6);
expect(node6 && tree.getHeight(node6)).toBe(2);
expect(node6 && tree.getDepth(node6)).toBe(3);
const nodeId10 = tree.get(10, 'id');
expect(nodeId10?.id).toBe(10);
const nodeVal9 = tree.get(9, 'val');
expect(nodeVal9?.id).toBe(9);
const nodesByCount1 = tree.getNodes(1, 'count');
expect(nodesByCount1.length).toBe(16);
const leftMost = tree.getLeftMost();
expect(leftMost?.id).toBe(1);
const node15 = tree.get(15);
const minNodeBySpecificNode = node15 && tree.getLeftMost(node15);
expect(minNodeBySpecificNode?.id).toBe(12);
const subTreeSum = node15 && tree.subTreeSum(node15);
expect(subTreeSum).toBe(70);
const lesserSum = tree.lesserSum(10);
expect(lesserSum).toBe(45);
expect(node15).toBeInstanceOf(BSTNode);
if (node15 instanceof BSTNode) {
const subTreeAdd = tree.subTreeAdd(node15, 1, 'count');
expect(subTreeAdd).toBeDefined();
}
const node11 = tree.get(11);
expect(node11).toBeInstanceOf(BSTNode);
if (node11 instanceof BSTNode) {
const allGreaterNodesAdded = tree.allGreaterNodesAdd(node11, 2, 'count');
expect(allGreaterNodesAdded).toBeDefined();
}
const dfsInorderNodes = tree.DFS('in', 'node');
expect(dfsInorderNodes[0].id).toBe(1);
expect(dfsInorderNodes[dfsInorderNodes.length - 1].id).toBe(16);
tree.balance();
expect(tree.isBalanced()).toBe(true);
const bfsNodesAfterBalanced = tree.BFS('node');
expect(bfsNodesAfterBalanced[0].id).toBe(8);
expect(bfsNodesAfterBalanced[bfsNodesAfterBalanced.length - 1].id).toBe(16);
const removed11 = tree.remove(11, true);
expect(removed11).toBeInstanceOf(Array);
expect(removed11[0]).toBeDefined();
expect(removed11[0].deleted).toBeDefined();
if (removed11[0].deleted) expect(removed11[0].deleted.id).toBe(11);
expect(tree.isAVLBalanced()).toBe(true);
expect(node15 && tree.getHeight(node15)).toBe(2);
const removed1 = tree.remove(1, true);
expect(removed1).toBeInstanceOf(Array);
expect(removed1[0]).toBeDefined();
expect(removed1[0].deleted).toBeDefined();
if (removed1[0].deleted) expect(removed1[0].deleted.id).toBe(1);
expect(tree.isAVLBalanced()).toBe(true);
expect(tree.getHeight()).toBe(4);
// The code for removing these nodes (4, 10, 15, 5, 13, 3, 8, 6, 7, 9, 14) in sequence has been omitted.
expect(tree.isAVLBalanced()).toBe(false);
const bfsIDs = tree.BFS();
expect(bfsIDs[0]).toBe(2);
expect(bfsIDs[1]).toBe(12);
expect(bfsIDs[2]).toBe(16);
const bfsNodes = tree.BFS('node');
expect(bfsNodes[0].id).toBe(2);
expect(bfsNodes[1].id).toBe(12);
expect(bfsNodes[2].id).toBe(16);
Directed Graph simple snippet
import {DirectedGraph, DirectedVertex, DirectedEdge, VertexId} from 'data-structure-typed';
let graph: DirectedGraph<DirectedVertex, DirectedEdge>;
beforeEach(() => {
graph = new DirectedGraph();
});
it('should add vertices', () => {
const vertex1 = new DirectedVertex('A');
const vertex2 = new DirectedVertex('B');
graph._addVertexOnly(vertex1);
graph._addVertexOnly(vertex2);
expect(graph.hasVertex(vertex1)).toBe(true);
expect(graph.hasVertex(vertex2)).toBe(true);
});
it('should add edges', () => {
const vertex1 = new DirectedVertex('A');
const vertex2 = new DirectedVertex('B');
const edge = new DirectedEdge('A', 'B');
graph._addVertexOnly(vertex1);
graph._addVertexOnly(vertex2);
graph._addEdgeOnly(edge);
expect(graph.hasEdge('A', 'B')).toBe(true);
expect(graph.hasEdge('B', 'A')).toBe(false);
});
it('should remove edges', () => {
const vertex1 = new DirectedVertex('A');
const vertex2 = new DirectedVertex('B');
const edge = new DirectedEdge('A', 'B');
graph._addVertexOnly(vertex1);
graph._addVertexOnly(vertex2);
graph._addEdgeOnly(edge);
expect(graph.removeEdge(edge)).toBe(edge);
expect(graph.hasEdge('A', 'B')).toBe(false);
});
it('should perform topological sort', () => {
const vertexA = new DirectedVertex('A');
const vertexB = new DirectedVertex('B');
const vertexC = new DirectedVertex('C');
const edgeAB = new DirectedEdge('A', 'B');
const edgeBC = new DirectedEdge('B', 'C');
graph._addVertexOnly(vertexA);
graph._addVertexOnly(vertexB);
graph._addVertexOnly(vertexC);
graph._addEdgeOnly(edgeAB);
graph._addEdgeOnly(edgeBC);
const topologicalOrder = graph.topologicalSort();
if (topologicalOrder) expect(topologicalOrder.map(v => v.id)).toEqual(['A', 'B', 'C']);
});
Directed Graph complex snippet
import {DirectedGraph, DirectedVertex, DirectedEdge, VertexId} from 'data-structure-typed';
class MyVertex extends DirectedVertex {
private _data: string;
get data(): string {
return this._data;
}
set data(value: string) {
this._data = value;
}
constructor(id: VertexId, data: string) {
super(id);
this._data = data;
}
}
class MyEdge extends DirectedEdge {
private _data: string;
get data(): string {
return this._data;
}
set data(value: string) {
this._data = value;
}
constructor(v1: VertexId, v2: VertexId, weight: number, data: string) {
super(v1, v2, weight);
this._data = data;
}
}
describe('DirectedGraph Test3', () => {
const myGraph = new DirectedGraph<MyVertex, MyEdge>();
it('should test graph operations', () => {
const vertex1 = new MyVertex(1, 'data1');
const vertex2 = new MyVertex(2, 'data2');
const vertex3 = new MyVertex(3, 'data3');
const vertex4 = new MyVertex(4, 'data4');
const vertex5 = new MyVertex(5, 'data5');
const vertex6 = new MyVertex(6, 'data6');
const vertex7 = new MyVertex(7, 'data7');
const vertex8 = new MyVertex(8, 'data8');
const vertex9 = new MyVertex(9, 'data9');
myGraph._addVertexOnly(vertex1);
myGraph._addVertexOnly(vertex2);
myGraph._addVertexOnly(vertex3);
myGraph._addVertexOnly(vertex4);
myGraph._addVertexOnly(vertex5);
myGraph._addVertexOnly(vertex6);
myGraph._addVertexOnly(vertex7);
myGraph._addVertexOnly(vertex8);
myGraph._addVertexOnly(vertex9);
myGraph._addEdgeOnly(new MyEdge(1, 2, 10, 'edge-data1-2'));
myGraph._addEdgeOnly(new MyEdge(2, 1, 20, 'edge-data2-1'));
expect(myGraph.getEdge(1, 2)).toBeTruthy();
expect(myGraph.getEdge(2, 1)).toBeTruthy();
expect(myGraph.getEdge(1, '100')).toBeFalsy();
myGraph.removeEdgeBetween(1, 2);
expect(myGraph.getEdge(1, 2)).toBeFalsy();
myGraph._addEdgeOnly(new MyEdge(3, 1, 3, 'edge-data-3-1'));
myGraph._addEdgeOnly(new MyEdge(1, 9, 19, 'edge-data1-9'));
myGraph._addEdgeOnly(new MyEdge(9, 7, 97, 'edge-data9-7'));
myGraph._addEdgeOnly(new MyEdge(7, 9, 79, 'edge-data7-9'));
myGraph._addEdgeOnly(new MyEdge(1, 4, 14, 'edge-data1-4'));
myGraph._addEdgeOnly(new MyEdge(4, 7, 47, 'edge-data4-7'));
myGraph._addEdgeOnly(new MyEdge(1, 2, 12, 'edge-data1-2'));
myGraph._addEdgeOnly(new MyEdge(2, 3, 23, 'edge-data2-3'));
myGraph._addEdgeOnly(new MyEdge(3, 5, 35, 'edge-data3-5'));
myGraph._addEdgeOnly(new MyEdge(5, 7, 57, 'edge-data5-7'));
myGraph._addEdgeOnly(new MyEdge(7, 3, 73, 'edge-data7-3'));
const topologicalSorted = myGraph.topologicalSort();
expect(topologicalSorted).toBeNull();
const minPath1to7 = myGraph.getMinPathBetween(1, 7);
expect(minPath1to7).toBeInstanceOf(Array);
if (minPath1to7 && minPath1to7.length > 0) {
expect(minPath1to7).toHaveLength(3);
expect(minPath1to7[0]).toBeInstanceOf(MyVertex);
expect(minPath1to7[0].id).toBe(1);
expect(minPath1to7[1].id).toBe(9);
expect(minPath1to7[2].id).toBe(7);
}
const fordResult1 = myGraph.bellmanFord(1);
expect(fordResult1).toBeTruthy();
expect(fordResult1.hasNegativeCycle).toBeUndefined();
const {distMap, preMap, paths, min, minPath} = fordResult1;
expect(distMap).toBeInstanceOf(Map);
expect(distMap.size).toBe(9);
expect(distMap.get(vertex1)).toBe(0);
expect(distMap.get(vertex2)).toBe(12);
expect(distMap.get(vertex3)).toBe(35);
expect(distMap.get(vertex4)).toBe(14);
expect(distMap.get(vertex5)).toBe(70);
expect(distMap.get(vertex6)).toBe(Infinity);
expect(distMap.get(vertex7)).toBe(61);
expect(distMap.get(vertex8)).toBe(Infinity);
expect(distMap.get(vertex9)).toBe(19);
expect(preMap).toBeInstanceOf(Map);
expect(preMap.size).toBe(0);
expect(paths).toBeInstanceOf(Array);
expect(paths.length).toBe(0);
expect(min).toBe(Infinity);
expect(minPath).toBeInstanceOf(Array);
const floydResult = myGraph.floyd();
expect(floydResult).toBeTruthy();
if (floydResult) {
const {costs, predecessor} = floydResult;
expect(costs).toBeInstanceOf(Array);
expect(costs.length).toBe(9);
expect(costs[0]).toEqual([32, 12, 35, 14, 70, Infinity, 61, Infinity, 19]);
expect(costs[1]).toEqual([20, 32, 23, 34, 58, Infinity, 81, Infinity, 39]);
expect(costs[2]).toEqual([3, 15, 38, 17, 35, Infinity, 64, Infinity, 22]);
expect(costs[3]).toEqual([123, 135, 120, 137, 155, Infinity, 47, Infinity, 126]);
expect(costs[4]).toEqual([133, 145, 130, 147, 165, Infinity, 57, Infinity, 136]);
expect(costs[5]).toEqual([Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity]);
expect(costs[6]).toEqual([76, 88, 73, 90, 108, Infinity, 137, Infinity, 79]);
expect(costs[7]).toEqual([Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity]);
expect(costs[8]).toEqual([173, 185, 170, 187, 205, Infinity, 97, Infinity, 176]);
expect(predecessor).toBeInstanceOf(Array);
expect(predecessor.length).toBe(9);
expect(predecessor[0]).toEqual([vertex2, null, vertex2, null, vertex3, null, vertex4, null, null]);
expect(predecessor[1]).toEqual([null, vertex1, null, vertex1, vertex3, null, vertex4, null, vertex1]);
expect(predecessor[5]).toEqual([null, null, null, null, null, null, null, null, null]);
expect(predecessor[7]).toEqual([null, null, null, null, null, null, null, null, null]);
expect(predecessor[8]).toEqual([vertex7, vertex7, vertex7, vertex7, vertex7, null, null, null, vertex7]);
}
const dijkstraRes12tt = myGraph.dijkstra(1, 2, true, true);
expect(dijkstraRes12tt).toBeTruthy();
if (dijkstraRes12tt) {
const {distMap, minDist, minPath, paths, preMap, seen} = dijkstraRes12tt;
expect(distMap).toBeInstanceOf(Map);
expect(distMap.size).toBe(9);
expect(distMap.get(vertex1)).toBe(0);
expect(distMap.get(vertex2)).toBe(12);
expect(distMap.get(vertex3)).toBe(Infinity);
expect(distMap.get(vertex4)).toBe(14);
expect(distMap.get(vertex5)).toBe(Infinity);
expect(distMap.get(vertex6)).toBe(Infinity);
expect(distMap.get(vertex7)).toBe(Infinity);
expect(distMap.get(vertex8)).toBe(Infinity);
expect(distMap.get(vertex9)).toBe(19);
expect(minDist).toBe(12);
expect(minPath).toBeInstanceOf(Array);
expect(minPath.length).toBe(2);
expect(minPath[0]).toBe(vertex1);
expect(minPath[1]).toBe(vertex2);
expect(paths).toBeInstanceOf(Array);
expect(paths.length).toBe(9);
expect(paths[0]).toBeInstanceOf(Array);
expect(paths[0][0]).toBe(vertex1);
expect(paths[1]).toBeInstanceOf(Array);
expect(paths[1][0]).toBe(vertex1);
expect(paths[1][1]).toBe(vertex2);
expect(paths[2]).toBeInstanceOf(Array);
expect(paths[2][0]).toBe(vertex3);
expect(paths[3]).toBeInstanceOf(Array);
expect(paths[3][0]).toBe(vertex1);
expect(paths[3][1]).toBe(vertex4);
expect(paths[4]).toBeInstanceOf(Array);
expect(paths[4][0]).toBe(vertex5);
expect(paths[5]).toBeInstanceOf(Array);
expect(paths[5][0]).toBe(vertex6);
expect(paths[6]).toBeInstanceOf(Array);
expect(paths[6][0]).toBe(vertex7);
expect(paths[7]).toBeInstanceOf(Array);
expect(paths[7][0]).toBe(vertex8);
expect(paths[8]).toBeInstanceOf(Array);
expect(paths[8][0]).toBe(vertex1);
expect(paths[8][1]).toBe(vertex9);
}
});
});
API docs
Why
Complexities
performance of Big O
Big O Notation | Type | Computations for 10 elements | Computations for 100 elements | Computations for 1000 elements |
---|---|---|---|---|
O(1) | Constant | 1 | 1 | 1 |
O(log N) | Logarithmic | 3 | 6 | 9 |
O(N) | Linear | 10 | 100 | 1000 |
O(N log N) | n log(n) | 30 | 600 | 9000 |
O(N^2) | Quadratic | 100 | 10000 | 1000000 |
O(2^N) | Exponential | 1024 | 1.26e+29 | 1.07e+301 |
O(N!) | Factorial | 3628800 | 9.3e+157 | 4.02e+2567 |
Data Structure Complexity
Data Structure | Access | Search | Insertion | Deletion | Comments |
---|---|---|---|---|---|
Array | 1 | n | n | n | |
Stack | n | n | 1 | 1 | |
Queue | n | n | 1 | 1 | |
Linked List | n | n | 1 | n | |
Hash Table | - | n | n | n | In case of perfect hash function costs would be O(1) |
Binary Search Tree | n | n | n | n | In case of balanced tree costs would be O(log(n)) |
B-Tree | log(n) | log(n) | log(n) | log(n) | |
Red-Black Tree | log(n) | log(n) | log(n) | log(n) | |
AVL Tree | log(n) | log(n) | log(n) | log(n) | |
Bloom Filter | - | 1 | 1 | - | False positives are possible while searching |
Sorting Complexity
Name | Best | Average | Worst | Memory | Stable | Comments |
---|---|---|---|---|---|---|
Bubble sort | n | n2 | n2 | 1 | Yes | |
Insertion sort | n | n2 | n2 | 1 | Yes | |
Selection sort | n2 | n2 | n2 | 1 | No | |
Heap sort | n log(n) | n log(n) | n log(n) | 1 | No | |
Merge sort | n log(n) | n log(n) | n log(n) | n | Yes | |
Quick sort | n log(n) | n log(n) | n2 | log(n) | No | Quicksort is usually done in-place with O(log(n)) stack space |
Shell sort | n log(n) | depends on gap sequence | n (log(n))2 | 1 | No | |
Counting sort | n + r | n + r | n + r | n + r | Yes | r - biggest number in array |
Radix sort | n * k | n * k | n * k | n + k | Yes | k - length of longest key |