diff --git a/CHANGELOG.md b/CHANGELOG.md index 87cbf8e..fd554bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,38 +8,28 @@ All notable changes to this project will be documented in this file. - [Semantic Versioning](https://semver.org/spec/v2.0.0.html) - [`auto-changelog`](https://github.com/CookPete/auto-changelog) -## [v1.47.6](https://github.com/zrwusa/data-structure-typed/compare/v1.35.0...main) (upcoming) +## [v1.47.7](https://github.com/zrwusa/data-structure-typed/compare/v1.35.0...main) (upcoming) ### Changes - Rbtree [`#31`](https://github.com/zrwusa/data-structure-typed/pull/31) - [graph test] edge cases enriched [`#30`](https://github.com/zrwusa/data-structure-typed/pull/30) -- [graph] Modify the data structure design of the graph to change the - g… [`#29`](https://github.com/zrwusa/data-structure-typed/pull/29) +- [graph] Modify the data structure design of the graph to change the g… [`#29`](https://github.com/zrwusa/data-structure-typed/pull/29) - Optimization [`#23`](https://github.com/zrwusa/data-structure-typed/pull/23) - Optimization [`#20`](https://github.com/zrwusa/data-structure-typed/pull/20) -- [binary-tree, graph] Replace all code that uses Arrays as makeshift - Q… [`#18`](https://github.com/zrwusa/data-structure-typed/pull/18) -- - 1. No need for dfsIterative; integrate it directly into the dfs - metho… [`#17`](https://github.com/zrwusa/data-structure-typed/pull/17) -- [heap] fibonacci heap implemented. [test] big O estimate. [project] - n… [`#15`](https://github.com/zrwusa/data-structure-typed/pull/15) +- [binary-tree, graph] Replace all code that uses Arrays as makeshift Q… [`#18`](https://github.com/zrwusa/data-structure-typed/pull/18) +- 1. No need for dfsIterative; integrate it directly into the dfs metho… [`#17`](https://github.com/zrwusa/data-structure-typed/pull/17) +- [heap] fibonacci heap implemented. [test] big O estimate. [project] n… [`#15`](https://github.com/zrwusa/data-structure-typed/pull/15) - [rbtree] implemented, but with bugs [`#13`](https://github.com/zrwusa/data-structure-typed/pull/13) -- [trie] renamed ambiguous methods and add comments to all - methods. [`#12`](https://github.com/zrwusa/data-structure-typed/pull/12) -- [binarytree] modified the getDepth method to adhere to the proper - def… [`#11`](https://github.com/zrwusa/data-structure-typed/pull/11) +- [trie] renamed ambiguous methods and add comments to all methods. [`#12`](https://github.com/zrwusa/data-structure-typed/pull/12) +- [binarytree] modified the getDepth method to adhere to the proper def… [`#11`](https://github.com/zrwusa/data-structure-typed/pull/11) - Trie [`#10`](https://github.com/zrwusa/data-structure-typed/pull/10) - [tree] getHeight returns faulty height bug fixed [`#9`](https://github.com/zrwusa/data-structure-typed/pull/9) - [trie] support casesensitivity. getWords bug fixed [`#8`](https://github.com/zrwusa/data-structure-typed/pull/8) -- [binary-tree, graph] In order to optimize the design of Binary - Trees,… [`#7`](https://github.com/zrwusa/data-structure-typed/pull/7) -- [BinaryTree, Heap] In abstract classes, only retain abstract - methods.… [`#6`](https://github.com/zrwusa/data-structure-typed/pull/6) +- [binary-tree, graph] In order to optimize the design of Binary Trees,… [`#7`](https://github.com/zrwusa/data-structure-typed/pull/7) +- [BinaryTree, Heap] In abstract classes, only retain abstract methods.… [`#6`](https://github.com/zrwusa/data-structure-typed/pull/6) - [heap] test [`#5`](https://github.com/zrwusa/data-structure-typed/pull/5) -- [heap, priority queue] Heap improved. References #123: - redesigned [`#4`](https://github.com/zrwusa/data-structure-typed/pull/4) +- [heap, priority queue] Heap improved. References #123: redesigned [`#4`](https://github.com/zrwusa/data-structure-typed/pull/4) - test [`#3`](https://github.com/zrwusa/data-structure-typed/pull/3) ## [v1.35.0](https://github.com/zrwusa/data-structure-typed/compare/v1.34.1...v1.35.0) (11 October 2023) diff --git a/src/data-structures/graph/abstract-graph.ts b/src/data-structures/graph/abstract-graph.ts index 3b0be52..70a03bb 100644 --- a/src/data-structures/graph/abstract-graph.ts +++ b/src/data-structures/graph/abstract-graph.ts @@ -89,9 +89,9 @@ export abstract class AbstractGraph< */ abstract createEdge(srcOrV1: VertexKey, destOrV2: VertexKey, weight?: number, value?: E): EO; - abstract deleteEdge(edge: EO): EO | null; + abstract deleteEdge(edge: EO): EO | undefined; - abstract getEdge(srcOrKey: VO | VertexKey, destOrKey: VO | VertexKey): EO | null; + abstract getEdge(srcOrKey: VO | VertexKey, destOrKey: VO | VertexKey): EO | undefined; abstract degreeOf(vertexOrKey: VO | VertexKey): number; @@ -101,7 +101,7 @@ export abstract class AbstractGraph< abstract getNeighbors(vertexOrKey: VO | VertexKey): VO[]; - abstract getEndsOfEdge(edge: EO): [VO, VO] | null; + abstract getEndsOfEdge(edge: EO): [VO, VO] | undefined; /** * Time Complexity: O(1) - Constant time for Map lookup. @@ -112,14 +112,14 @@ export abstract class AbstractGraph< * Time Complexity: O(1) - Constant time for Map lookup. * Space Complexity: O(1) - Constant space, as it creates only a few variables. * - * The function "getVertex" returns the vertex with the specified ID or null if it doesn't exist. + * The function "getVertex" returns the vertex with the specified ID or undefined if it doesn't exist. * @param {VertexKey} vertexKey - The `vertexKey` parameter is the identifier of the vertex that you want to retrieve from * the `_vertices` map. * @returns The method `getVertex` returns the vertex with the specified `vertexKey` if it exists in the `_vertices` - * map. If the vertex does not exist, it returns `null`. + * map. If the vertex does not exist, it returns `undefined`. */ - getVertex(vertexKey: VertexKey): VO | null { - return this._vertices.get(vertexKey) || null; + getVertex(vertexKey: VertexKey): VO | undefined { + return this._vertices.get(vertexKey) || undefined; } /** @@ -365,7 +365,7 @@ export abstract class AbstractGraph< * vertices. If `isWeight` is `false` or not provided, it uses a breadth-first search (BFS) algorithm to calculate the * minimum number of */ - getMinCostBetween(v1: VO | VertexKey, v2: VO | VertexKey, isWeight?: boolean): number | null { + getMinCostBetween(v1: VO | VertexKey, v2: VO | VertexKey, isWeight?: boolean): number | undefined { if (isWeight === undefined) isWeight = false; if (isWeight) { @@ -380,7 +380,7 @@ export abstract class AbstractGraph< const vertex2 = this._getVertex(v2); const vertex1 = this._getVertex(v1); if (!(vertex1 && vertex2)) { - return null; + return undefined; } const visited: Map = new Map(); @@ -406,7 +406,7 @@ export abstract class AbstractGraph< } cost++; } - return null; + return undefined; } } @@ -432,9 +432,9 @@ export abstract class AbstractGraph< * followed by iterative computation of the shortest path. This approach may result in exponential time complexity, * so the default method is to use the Dijkstra algorithm to obtain the shortest weighted path. * @returns The function `getMinPathBetween` returns an array of vertices (`VO[]`) representing the minimum path between - * two vertices (`v1` and `v2`). If there is no path between the vertices, it returns `null`. + * two vertices (`v1` and `v2`). If there is no path between the vertices, it returns `undefined`. */ - getMinPathBetween(v1: VO | VertexKey, v2: VO | VertexKey, isWeight?: boolean, isDFS = false): VO[] | null { + getMinPathBetween(v1: VO | VertexKey, v2: VO | VertexKey, isWeight?: boolean, isDFS = false): VO[] | undefined { if (isWeight === undefined) isWeight = false; if (isWeight) { @@ -451,7 +451,7 @@ export abstract class AbstractGraph< } index++; } - return allPaths[minIndex] || null; + return allPaths[minIndex] || undefined; } else { return this.dijkstra(v1, v2, true, true)?.minPath ?? []; } @@ -503,9 +503,9 @@ export abstract class AbstractGraph< * a graph without using a heap data structure. * @param {VO | VertexKey} src - The source vertex from which to start the Dijkstra's algorithm. It can be either a * vertex object or a vertex ID. - * @param {VO | VertexKey | null} [dest] - The `dest` parameter in the `dijkstraWithoutHeap` function is an optional + * @param {VO | VertexKey | undefined} [dest] - The `dest` parameter in the `dijkstraWithoutHeap` function is an optional * parameter that specifies the destination vertex for the Dijkstra algorithm. It can be either a vertex object or its - * identifier. If no destination is provided, the value is set to `null`. + * identifier. If no destination is provided, the value is set to `undefined`. * @param {boolean} [getMinDist] - The `getMinDist` parameter is a boolean flag that determines whether the minimum * distance from the source vertex to the destination vertex should be calculated and returned in the result. If * `getMinDist` is set to `true`, the `minDist` property in the result will contain the minimum distance @@ -516,29 +516,29 @@ export abstract class AbstractGraph< */ dijkstraWithoutHeap( src: VO | VertexKey, - dest?: VO | VertexKey | null, + dest?: VO | VertexKey | undefined, getMinDist?: boolean, genPaths?: boolean ): DijkstraResult { if (getMinDist === undefined) getMinDist = false; if (genPaths === undefined) genPaths = false; - if (dest === undefined) dest = null; + if (dest === undefined) dest = undefined; let minDist = Infinity; - let minDest: VO | null = null; + let minDest: VO | undefined = undefined; let minPath: VO[] = []; const paths: VO[][] = []; const vertices = this._vertices; const distMap: Map = new Map(); const seen: Set = new Set(); - const preMap: Map = new Map(); // predecessor + const preMap: Map = new Map(); // predecessor const srcVertex = this._getVertex(src); - const destVertex = dest ? this._getVertex(dest) : null; + const destVertex = dest ? this._getVertex(dest) : undefined; if (!srcVertex) { - return null; + return undefined; } for (const vertex of vertices) { @@ -546,11 +546,11 @@ export abstract class AbstractGraph< if (vertexOrKey instanceof AbstractVertex) distMap.set(vertexOrKey, Infinity); } distMap.set(srcVertex, 0); - preMap.set(srcVertex, null); + preMap.set(srcVertex, undefined); const getMinOfNoSeen = () => { let min = Infinity; - let minV: VO | null = null; + let minV: VO | undefined = undefined; for (const [key, value] of distMap) { if (!seen.has(key)) { if (value < min) { @@ -562,7 +562,7 @@ export abstract class AbstractGraph< return minV; }; - const getPaths = (minV: VO | null) => { + const getPaths = (minV: VO | undefined) => { for (const vertex of vertices) { const vertexOrKey = vertex[1]; @@ -600,7 +600,7 @@ export abstract class AbstractGraph< if (edge) { const curFromMap = distMap.get(cur); const neighborFromMap = distMap.get(neighbor); - // TODO after no-non-null-assertion not ensure the logic + // TODO after no-non-undefined-assertion not ensure the logic if (curFromMap !== undefined && neighborFromMap !== undefined) { if (edge.weight + curFromMap < neighborFromMap) { distMap.set(neighbor, edge.weight + curFromMap); @@ -651,7 +651,7 @@ export abstract class AbstractGraph< * optional destination vertex, and optionally returns the minimum distance, the paths, and other information. * @param {VO | VertexKey} src - The `src` parameter represents the source vertex from which the Dijkstra algorithm will * start. It can be either a vertex object or a vertex ID. - * @param {VO | VertexKey | null} [dest] - The `dest` parameter is the destination vertex or vertex ID. It specifies the + * @param {VO | VertexKey | undefined} [dest] - The `dest` parameter is the destination vertex or vertex ID. It specifies the * vertex to which the shortest path is calculated from the source vertex. If no destination is provided, the algorithm * will calculate the shortest paths to all other vertices from the source vertex. * @param {boolean} [getMinDist] - The `getMinDist` parameter is a boolean flag that determines whether the minimum @@ -664,27 +664,27 @@ export abstract class AbstractGraph< */ dijkstra( src: VO | VertexKey, - dest?: VO | VertexKey | null, + dest?: VO | VertexKey | undefined, getMinDist?: boolean, genPaths?: boolean ): DijkstraResult { if (getMinDist === undefined) getMinDist = false; if (genPaths === undefined) genPaths = false; - if (dest === undefined) dest = null; + if (dest === undefined) dest = undefined; let minDist = Infinity; - let minDest: VO | null = null; + let minDest: VO | undefined = undefined; let minPath: VO[] = []; const paths: VO[][] = []; const vertices = this._vertices; const distMap: Map = new Map(); const seen: Set = new Set(); - const preMap: Map = new Map(); // predecessor + const preMap: Map = new Map(); // predecessor const srcVertex = this._getVertex(src); - const destVertex = dest ? this._getVertex(dest) : null; + const destVertex = dest ? this._getVertex(dest) : undefined; - if (!srcVertex) return null; + if (!srcVertex) return undefined; for (const vertex of vertices) { const vertexOrKey = vertex[1]; @@ -695,14 +695,14 @@ export abstract class AbstractGraph< heap.add({ key: 0, value: srcVertex }); distMap.set(srcVertex, 0); - preMap.set(srcVertex, null); + preMap.set(srcVertex, undefined); /** * The function `getPaths` retrieves all paths from vertices to a specified minimum vertex. - * @param {VO | null} minV - The parameter `minV` is of type `VO | null`. It represents the minimum vertex value or - * null. + * @param {VO | undefined} minV - The parameter `minV` is of type `VO | undefined`. It represents the minimum vertex value or + * undefined. */ - const getPaths = (minV: VO | null) => { + const getPaths = (minV: VO | undefined) => { for (const vertex of vertices) { const vertexOrKey = vertex[1]; if (vertexOrKey instanceof AbstractVertex) { @@ -841,7 +841,7 @@ export abstract class AbstractGraph< } } - let minDest: VO | null = null; + let minDest: VO | undefined = undefined; if (getMin) { distMap.forEach((d, v) => { if (v !== srcVertex) { @@ -920,22 +920,22 @@ export abstract class AbstractGraph< * graph. * @returns The function `floydWarshall()` returns an object with two properties: `costs` and `predecessor`. The `costs` * property is a 2D array of numbers representing the shortest path costs between vertices in a graph. The - * `predecessor` property is a 2D array of vertices (or `null`) representing the predecessor vertices in the shortest + * `predecessor` property is a 2D array of vertices (or `undefined`) representing the predecessor vertices in the shortest * path between vertices in the */ - floydWarshall(): { costs: number[][]; predecessor: (VO | null)[][] } { + floydWarshall(): { costs: number[][]; predecessor: (VO | undefined)[][] } { const idAndVertices = [...this._vertices]; const n = idAndVertices.length; const costs: number[][] = []; - const predecessor: (VO | null)[][] = []; + const predecessor: (VO | undefined)[][] = []; // successors for (let i = 0; i < n; i++) { costs[i] = []; predecessor[i] = []; for (let j = 0; j < n; j++) { - predecessor[i][j] = null; + predecessor[i][j] = undefined; } } @@ -1021,7 +1021,7 @@ export abstract class AbstractGraph< const cutVertexes: VO[] = []; const bridges: EO[] = []; let dfn = 0; - const dfs = (cur: VO, parent: VO | null) => { + const dfs = (cur: VO, parent: VO | undefined) => { dfn++; dfnMap.set(cur, dfn); lowMap.set(cur, dfn); @@ -1036,7 +1036,7 @@ export abstract class AbstractGraph< } const childLow = lowMap.get(neighbor); const curLow = lowMap.get(cur); - // TODO after no-non-null-assertion not ensure the logic + // TODO after no-non-undefined-assertion not ensure the logic if (curLow !== undefined && childLow !== undefined) { lowMap.set(cur, Math.min(curLow, childLow)); } @@ -1062,7 +1062,7 @@ export abstract class AbstractGraph< } }; - dfs(root, null); + dfs(root, undefined); let SCCs: Map = new Map(); @@ -1170,9 +1170,9 @@ export abstract class AbstractGraph< return true; } - protected _getVertex(vertexOrKey: VertexKey | VO): VO | null { + protected _getVertex(vertexOrKey: VertexKey | VO): VO | undefined { const vertexKey = this._getVertexKey(vertexOrKey); - return this._vertices.get(vertexKey) || null; + return this._vertices.get(vertexKey) || undefined; } protected _getVertexKey(vertexOrKey: VO | VertexKey): VertexKey { diff --git a/src/data-structures/graph/directed-graph.ts b/src/data-structures/graph/directed-graph.ts index dd63391..3266732 100644 --- a/src/data-structures/graph/directed-graph.ts +++ b/src/data-structures/graph/directed-graph.ts @@ -119,18 +119,18 @@ export class DirectedGraph< * Space Complexity: O(1) * * The `getEdge` function retrieves an edge between two vertices based on their source and destination IDs. - * @param {VO | VertexKey | null} srcOrKey - The source vertex or its ID. It can be either a vertex object or a vertex ID. - * @param {VO | VertexKey | null} destOrKey - The `destOrKey` parameter in the `getEdge` function represents the - * destination vertex of the edge. It can be either a vertex object (`VO`), a vertex ID (`VertexKey`), or `null` if the + * @param {VO | VertexKey | undefined} srcOrKey - The source vertex or its ID. It can be either a vertex object or a vertex ID. + * @param {VO | VertexKey | undefined} destOrKey - The `destOrKey` parameter in the `getEdge` function represents the + * destination vertex of the edge. It can be either a vertex object (`VO`), a vertex ID (`VertexKey`), or `undefined` if the * destination is not specified. - * @returns the first edge found between the source and destination vertices, or null if no such edge is found. + * @returns the first edge found between the source and destination vertices, or undefined if no such edge is found. */ - getEdge(srcOrKey: VO | VertexKey | null, destOrKey: VO | VertexKey | null): EO | null { + getEdge(srcOrKey: VO | VertexKey | undefined, destOrKey: VO | VertexKey | undefined): EO | undefined { let edges: EO[] = []; - if (srcOrKey !== null && destOrKey !== null) { - const src: VO | null = this._getVertex(srcOrKey); - const dest: VO | null = this._getVertex(destOrKey); + if (srcOrKey !== undefined && destOrKey !== undefined) { + const src: VO | undefined = this._getVertex(srcOrKey); + const dest: VO | undefined = this._getVertex(destOrKey); if (src && dest) { const srcOutEdges = this._outEdgeMap.get(src); @@ -140,7 +140,7 @@ export class DirectedGraph< } } - return edges[0] || null; + return edges[0] || undefined; } /** @@ -155,14 +155,14 @@ export class DirectedGraph< * The function removes an edge between two vertices in a graph and returns the removed edge. * @param {VO | VertexKey} srcOrKey - The source vertex or its ID. * @param {VO | VertexKey} destOrKey - The `destOrKey` parameter represents the destination vertex or its ID. - * @returns the removed edge (EO) if it exists, or null if either the source or destination vertex does not exist. + * @returns the removed edge (EO) if it exists, or undefined if either the source or destination vertex does not exist. */ - deleteEdgeSrcToDest(srcOrKey: VO | VertexKey, destOrKey: VO | VertexKey): EO | null { - const src: VO | null = this._getVertex(srcOrKey); - const dest: VO | null = this._getVertex(destOrKey); - let removed: EO | null = null; + deleteEdgeSrcToDest(srcOrKey: VO | VertexKey, destOrKey: VO | VertexKey): EO | undefined { + const src: VO | undefined = this._getVertex(srcOrKey); + const dest: VO | undefined = this._getVertex(destOrKey); + let removed: EO | undefined = undefined; if (!src || !dest) { - return null; + return undefined; } const srcOutEdges = this._outEdgeMap.get(src); @@ -172,7 +172,7 @@ export class DirectedGraph< const destInEdges = this._inEdgeMap.get(dest); if (destInEdges) { - removed = arrayRemove(destInEdges, (edge: EO) => edge.src === src.key)[0] || null; + removed = arrayRemove(destInEdges, (edge: EO) => edge.src === src.key)[0] || undefined; } return removed; } @@ -186,13 +186,13 @@ export class DirectedGraph< * Time Complexity: O(|E|) where |E| is the number of edges * Space Complexity: O(1) * - * The function removes an edge from a graph and returns the removed edge, or null if the edge was not found. + * The function removes an edge from a graph and returns the removed edge, or undefined if the edge was not found. * @param {EO} edge - The `edge` parameter is an object that represents an edge in a graph. It has two properties: `src` * and `dest`, which represent the source and destination vertices of the edge, respectively. - * @returns The method `deleteEdge` returns the removed edge (`EO`) if it exists, or `null` if the edge does not exist. + * @returns The method `deleteEdge` returns the removed edge (`EO`) if it exists, or `undefined` if the edge does not exist. */ - deleteEdge(edge: EO): EO | null { - let removed: EO | null = null; + deleteEdge(edge: EO): EO | undefined { + let removed: EO | undefined = undefined; const src = this._getVertex(edge.src); const dest = this._getVertex(edge.dest); if (src && dest) { @@ -361,11 +361,11 @@ export class DirectedGraph< * Time Complexity: O(1) * Space Complexity: O(1) * - * The function "getEdgeSrc" returns the source vertex of an edge, or null if the edge does not exist. + * The function "getEdgeSrc" returns the source vertex of an edge, or undefined if the edge does not exist. * @param {EO} e - The parameter "e" is of type EO, which represents an edge in a graph. - * @returns either a vertex object (VO) or null. + * @returns either a vertex object (VO) or undefined. */ - getEdgeSrc(e: EO): VO | null { + getEdgeSrc(e: EO): VO | undefined { return this._getVertex(e.src); } @@ -380,9 +380,9 @@ export class DirectedGraph< * * The function "getEdgeDest" returns the destination vertex of an edge. * @param {EO} e - The parameter "e" is of type "EO", which represents an edge in a graph. - * @returns either a vertex object of type VO or null. + * @returns either a vertex object of type VO or undefined. */ - getEdgeDest(e: EO): VO | null { + getEdgeDest(e: EO): VO | undefined { return this._getVertex(e.dest); } @@ -396,12 +396,12 @@ export class DirectedGraph< * Space Complexity: O(1) * * The function `getDestinations` returns an array of destination vertices connected to a given vertex. - * @param {VO | VertexKey | null} vertex - The `vertex` parameter represents the starting vertex from which we want to - * find the destinations. It can be either a `VO` object, a `VertexKey` value, or `null`. + * @param {VO | VertexKey | undefined} vertex - The `vertex` parameter represents the starting vertex from which we want to + * find the destinations. It can be either a `VO` object, a `VertexKey` value, or `undefined`. * @returns an array of vertices (VO[]). */ - getDestinations(vertex: VO | VertexKey | null): VO[] { - if (vertex === null) { + getDestinations(vertex: VO | VertexKey | undefined): VO[] { + if (vertex === undefined) { return []; } const destinations: VO[] = []; @@ -425,13 +425,13 @@ export class DirectedGraph< * Space Complexity: O(|V|) * * The `topologicalSort` function performs a topological sort on a graph and returns an array of vertices or vertex IDs - * in the sorted order, or null if the graph contains a cycle. + * in the sorted order, or undefined if the graph contains a cycle. * @param {'vertex' | 'key'} [propertyName] - The `propertyName` parameter is an optional parameter that specifies the * property to use for sorting the vertices. It can have two possible values: 'vertex' or 'key'. If 'vertex' is * specified, the vertices themselves will be used for sorting. If 'key' is specified, the ids of - * @returns an array of vertices or vertex IDs in topological order. If there is a cycle in the graph, it returns null. + * @returns an array of vertices or vertex IDs in topological order. If there is a cycle in the graph, it returns undefined. */ - topologicalSort(propertyName?: 'vertex' | 'key'): Array | null { + topologicalSort(propertyName?: 'vertex' | 'key'): Array | undefined { propertyName = propertyName ?? 'key'; // When judging whether there is a cycle in the undirected graph, all nodes with degree of **<= 1** are enqueued // When judging whether there is a cycle in the directed graph, all nodes with **in degree = 0** are enqueued @@ -463,7 +463,7 @@ export class DirectedGraph< } } - if (hasCycle) return null; + if (hasCycle) return undefined; if (propertyName === 'key') sorted = sorted.map(vertex => (vertex instanceof DirectedVertex ? vertex.key : vertex)); return sorted.reverse(); @@ -510,7 +510,7 @@ export class DirectedGraph< const outEdges = this.outgoingEdgesOf(vertex); for (const outEdge of outEdges) { const neighbor = this._getVertex(outEdge.dest); - // TODO after no-non-null-assertion not ensure the logic + // TODO after no-non-undefined-assertion not ensure the logic if (neighbor) { neighbors.push(neighbor); } @@ -529,21 +529,21 @@ export class DirectedGraph< * Space Complexity: O(1) * * The function "getEndsOfEdge" returns the source and destination vertices of an edge if it exists in the graph, - * otherwise it returns null. + * otherwise it returns undefined. * @param {EO} edge - The parameter `edge` is of type `EO`, which represents an edge in a graph. * @returns The function `getEndsOfEdge` returns an array containing two vertices `[VO, VO]` if the edge exists in the - * graph. If the edge does not exist, it returns `null`. + * graph. If the edge does not exist, it returns `undefined`. */ - getEndsOfEdge(edge: EO): [VO, VO] | null { + getEndsOfEdge(edge: EO): [VO, VO] | undefined { if (!this.hasEdge(edge.src, edge.dest)) { - return null; + return undefined; } const v1 = this._getVertex(edge.src); const v2 = this._getVertex(edge.dest); if (v1 && v2) { return [v1, v2]; } else { - return null; + return undefined; } } @@ -570,7 +570,7 @@ export class DirectedGraph< const srcVertex = this._getVertex(edge.src); const destVertex = this._getVertex(edge.dest); - // TODO after no-non-null-assertion not ensure the logic + // TODO after no-non-undefined-assertion not ensure the logic if (srcVertex && destVertex) { const srcOutEdges = this._outEdgeMap.get(srcVertex); if (srcOutEdges) { diff --git a/src/data-structures/graph/undirected-graph.ts b/src/data-structures/graph/undirected-graph.ts index 8f77120..b11665b 100644 --- a/src/data-structures/graph/undirected-graph.ts +++ b/src/data-structures/graph/undirected-graph.ts @@ -100,26 +100,26 @@ export class UndirectedGraph< * Time Complexity: O(|E|), where |E| is the number of edges incident to the given vertex. * Space Complexity: O(1) * - * The function `getEdge` returns the first edge that connects two vertices, or null if no such edge exists. - * @param {VO | VertexKey | null} v1 - The parameter `v1` represents a vertex or vertex ID. It can be of type `VO` (vertex - * object), `null`, or `VertexKey` (a string or number representing the ID of a vertex). - * @param {VO | VertexKey | null} v2 - The parameter `v2` represents a vertex or vertex ID. It can be of type `VO` (vertex - * object), `null`, or `VertexKey` (vertex ID). - * @returns an edge (EO) or null. + * The function `getEdge` returns the first edge that connects two vertices, or undefined if no such edge exists. + * @param {VO | VertexKey | undefined} v1 - The parameter `v1` represents a vertex or vertex ID. It can be of type `VO` (vertex + * object), `undefined`, or `VertexKey` (a string or number representing the ID of a vertex). + * @param {VO | VertexKey | undefined} v2 - The parameter `v2` represents a vertex or vertex ID. It can be of type `VO` (vertex + * object), `undefined`, or `VertexKey` (vertex ID). + * @returns an edge (EO) or undefined. */ - getEdge(v1: VO | VertexKey | null, v2: VO | VertexKey | null): EO | null { + getEdge(v1: VO | VertexKey | undefined, v2: VO | VertexKey | undefined): EO | undefined { let edges: EO[] | undefined = []; - if (v1 !== null && v2 !== null) { - const vertex1: VO | null = this._getVertex(v1); - const vertex2: VO | null = this._getVertex(v2); + if (v1 !== undefined && v2 !== undefined) { + const vertex1: VO | undefined = this._getVertex(v1); + const vertex2: VO | undefined = this._getVertex(v2); if (vertex1 && vertex2) { edges = this._edges.get(vertex1)?.filter(e => e.vertices.includes(vertex2.key)); } } - return edges ? edges[0] || null : null; + return edges ? edges[0] || undefined : undefined; } /** @@ -135,20 +135,20 @@ export class UndirectedGraph< * @param {VO | VertexKey} v1 - The parameter `v1` represents either a vertex object (`VO`) or a vertex ID (`VertexKey`). * @param {VO | VertexKey} v2 - VO | VertexKey - This parameter can be either a vertex object (VO) or a vertex ID * (VertexKey). It represents the second vertex of the edge that needs to be removed. - * @returns the removed edge (EO) if it exists, or null if either of the vertices (VO) does not exist. + * @returns the removed edge (EO) if it exists, or undefined if either of the vertices (VO) does not exist. */ - deleteEdgeBetween(v1: VO | VertexKey, v2: VO | VertexKey): EO | null { - const vertex1: VO | null = this._getVertex(v1); - const vertex2: VO | null = this._getVertex(v2); + deleteEdgeBetween(v1: VO | VertexKey, v2: VO | VertexKey): EO | undefined { + const vertex1: VO | undefined = this._getVertex(v1); + const vertex2: VO | undefined = this._getVertex(v2); if (!vertex1 || !vertex2) { - return null; + return undefined; } const v1Edges = this._edges.get(vertex1); - let removed: EO | null = null; + let removed: EO | undefined = undefined; if (v1Edges) { - removed = arrayRemove(v1Edges, (e: EO) => e.vertices.includes(vertex2.key))[0] || null; + removed = arrayRemove(v1Edges, (e: EO) => e.vertices.includes(vertex2.key))[0] || undefined; } const v2Edges = this._edges.get(vertex2); if (v2Edges) { @@ -168,9 +168,9 @@ export class UndirectedGraph< * * The deleteEdge function removes an edge between two vertices in a graph. * @param {EO} edge - The parameter "edge" is of type EO, which represents an edge in a graph. - * @returns The method is returning either the removed edge (of type EO) or null if the edge was not found. + * @returns The method is returning either the removed edge (of type EO) or undefined if the edge was not found. */ - deleteEdge(edge: EO): EO | null { + deleteEdge(edge: EO): EO | undefined { return this.deleteEdgeBetween(edge.vertices[0], edge.vertices[1]); } @@ -282,21 +282,21 @@ export class UndirectedGraph< * Space Complexity: O(1) * * The function "getEndsOfEdge" returns the vertices at the ends of an edge if the edge exists in the graph, otherwise - * it returns null. + * it returns undefined. * @param {EO} edge - The parameter "edge" is of type EO, which represents an edge in a graph. * @returns The function `getEndsOfEdge` returns an array containing two vertices `[VO, VO]` if the edge exists in the - * graph. If the edge does not exist, it returns `null`. + * graph. If the edge does not exist, it returns `undefined`. */ - getEndsOfEdge(edge: EO): [VO, VO] | null { + getEndsOfEdge(edge: EO): [VO, VO] | undefined { if (!this.hasEdge(edge.vertices[0], edge.vertices[1])) { - return null; + return undefined; } const v1 = this._getVertex(edge.vertices[0]); const v2 = this._getVertex(edge.vertices[1]); if (v1 && v2) { return [v1, v2]; } else { - return null; + return undefined; } } @@ -316,7 +316,7 @@ export class UndirectedGraph< protected _addEdgeOnly(edge: EO): boolean { for (const end of edge.vertices) { const endVertex = this._getVertex(end); - if (endVertex === null) return false; + if (endVertex === undefined) return false; if (endVertex) { const edges = this._edges.get(endVertex); if (edges) { diff --git a/src/types/data-structures/graph/abstract-graph.ts b/src/types/data-structures/graph/abstract-graph.ts index bd90c43..4d930e5 100644 --- a/src/types/data-structures/graph/abstract-graph.ts +++ b/src/types/data-structures/graph/abstract-graph.ts @@ -3,9 +3,9 @@ export type VertexKey = string | number; export type DijkstraResult = { distMap: Map; distPaths?: Map; - preMap: Map; + preMap: Map; seen: Set; paths: V[][]; minDist: number; minPath: V[]; -} | null; +} | undefined; diff --git a/test/integration/index.html b/test/integration/index.html index eedb362..79b8b5f 100644 --- a/test/integration/index.html +++ b/test/integration/index.html @@ -4,8 +4,8 @@ CDN Test - - + + @@ -215,25 +215,25 @@ } catch (e) { console.error(e); } - + try { - const { + const { AVLTree, - BinaryTree, - BST, - Deque, - DoublyLinkedList, - HashMap, - Heap, - MaxPriorityQueue, - MinHeap, - MinPriorityQueue, - Queue, - RedBlackTree, - SinglyLinkedList, - Stack, - TreeMultimap, - Trie + BinaryTree, + BST, + Deque, + DoublyLinkedList, + HashMap, + Heap, + MaxPriorityQueue, + MinHeap, + MinPriorityQueue, + Queue, + RedBlackTree, + SinglyLinkedList, + Stack, + TreeMultimap, + Trie } = dataStructureTyped; const orgArr = [6, 1, 2, 7, 5, 3, 4, 9, 8]; const orgStrArr = ["trie", "trial", "trick", "trip", "tree", "trend", "triangle", "track", "trace", "transmit"]; @@ -299,7 +299,7 @@ const entries2 = dq2.map((el, i) => [i, el]); const avl2 = new AVLTree(entries2); avl2.print(); - } catch (e) { + } catch (e) { console.error(e); } diff --git a/test/unit/data-structures/graph/directed-graph.test.ts b/test/unit/data-structures/graph/directed-graph.test.ts index 844e33c..44e63b9 100644 --- a/test/unit/data-structures/graph/directed-graph.test.ts +++ b/test/unit/data-structures/graph/directed-graph.test.ts @@ -196,7 +196,7 @@ describe('Inherit from DirectedGraph and perform operations', () => { expect(edge1).toBeInstanceOf(MyEdge); expect(edge1.src).toBe(1); expect(edge1).toEqual(edge2); - expect(edge3).toBeNull(); + expect(edge3).toBe(undefined); } }); @@ -217,7 +217,7 @@ describe('Inherit from DirectedGraph and perform operations', () => { removedEdge && expect(removedEdge.value).toBe('edge-data1-2'); removedEdge && expect(removedEdge.src).toBe(1); } - expect(edgeAfterRemoval).toBeNull(); + expect(edgeAfterRemoval).toBe(undefined); }); it('Topological sort', () => { @@ -303,7 +303,7 @@ describe('Inherit from DirectedGraph and perform operations test2.', () => { myGraph.addEdge(new MyEdge(7, 3, 73, 'edge-data7-3')); const topologicalSorted = myGraph.topologicalSort(); - expect(topologicalSorted).toBeNull(); + expect(topologicalSorted).toBe(undefined); const minPath1to7 = myGraph.getMinPathBetween(1, 7); @@ -378,11 +378,11 @@ describe('Inherit from DirectedGraph and perform operations test2.', () => { 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]); + expect(predecessor[0]).toEqual([vertex2, undefined, vertex2, undefined, vertex3, undefined, vertex4, undefined, undefined]); + expect(predecessor[1]).toEqual([undefined, vertex1, undefined, vertex1, vertex3, undefined, vertex4, undefined, vertex1]); + expect(predecessor[5]).toEqual([undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined]); + expect(predecessor[7]).toEqual([undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined]); + expect(predecessor[8]).toEqual([vertex7, vertex7, vertex7, vertex7, vertex7, undefined, undefined, undefined, vertex7]); } const dijkstraRes12tt = myGraph.dijkstra(1, 2, true, true); @@ -436,7 +436,7 @@ describe('Inherit from DirectedGraph and perform operations test2.', () => { expect(paths[8][1]).toBe(vertex9); } - const dijkstraRes1ntt = myGraph.dijkstra(1, null, true, true); + const dijkstraRes1ntt = myGraph.dijkstra(1, undefined, true, true); expect(dijkstraRes1ntt).toBeTruthy(); if (dijkstraRes1ntt) { @@ -499,7 +499,7 @@ describe('Inherit from DirectedGraph and perform operations test2.', () => { expect(paths[8][1]).toBe(vertex9); } - const dijkstraWithoutHeapRes1ntt = myGraph.dijkstraWithoutHeap(1, null, true, true); + const dijkstraWithoutHeapRes1ntt = myGraph.dijkstraWithoutHeap(1, undefined, true, true); expect(dijkstraWithoutHeapRes1ntt).toBeTruthy(); if (dijkstraWithoutHeapRes1ntt) { const { distMap, minDist, minPath, paths } = dijkstraWithoutHeapRes1ntt; diff --git a/test/unit/data-structures/graph/undirected-graph.test.ts b/test/unit/data-structures/graph/undirected-graph.test.ts index 20c9128..0d966f1 100644 --- a/test/unit/data-structures/graph/undirected-graph.test.ts +++ b/test/unit/data-structures/graph/undirected-graph.test.ts @@ -10,11 +10,11 @@ describe('UndirectedGraph Operation Test', () => { }); it('should edge cases', () => { - expect(graph.deleteEdge(new UndirectedEdge('c', 'd'))).toBe(null); - expect(graph.deleteEdgeBetween('c', 'd')).toBe(null); + expect(graph.deleteEdge(new UndirectedEdge('c', 'd'))).toBe(undefined); + expect(graph.deleteEdgeBetween('c', 'd')).toBe(undefined); expect(graph.degreeOf('c')).toBe(0); expect(graph.edgesOf('c').length).toBe(0); - expect(graph.getEndsOfEdge(new UndirectedEdge('c', 'd'))).toBe(null); + expect(graph.getEndsOfEdge(new UndirectedEdge('c', 'd'))).toBe(undefined); }); it('should add vertices', () => {