mirror of
https://github.com/zrwusa/data-structure-typed.git
synced 2024-11-23 12:54:04 +00:00
refactor: renamed variables
This commit is contained in:
parent
ce99f7988e
commit
f56542a07a
|
@ -71,10 +71,10 @@ export abstract class AbstractGraph<
|
|||
super();
|
||||
}
|
||||
|
||||
protected _vertices: Map<VertexKey, VO> = new Map<VertexKey, VO>();
|
||||
protected _vertexMap: Map<VertexKey, VO> = new Map<VertexKey, VO>();
|
||||
|
||||
get vertices(): Map<VertexKey, VO> {
|
||||
return this._vertices;
|
||||
get vertexMap(): Map<VertexKey, VO> {
|
||||
return this._vertexMap;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -120,12 +120,12 @@ export abstract class AbstractGraph<
|
|||
*
|
||||
* 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`
|
||||
* the `_vertexMap` map.
|
||||
* @returns The method `getVertex` returns the vertex with the specified `vertexKey` if it exists in the `_vertexMap`
|
||||
* map. If the vertex does not exist, it returns `undefined`.
|
||||
*/
|
||||
getVertex(vertexKey: VertexKey): VO | undefined {
|
||||
return this._vertices.get(vertexKey) || undefined;
|
||||
return this._vertexMap.get(vertexKey) || undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -143,7 +143,7 @@ export abstract class AbstractGraph<
|
|||
* @returns a boolean value.
|
||||
*/
|
||||
hasVertex(vertexOrKey: VO | VertexKey): boolean {
|
||||
return this._vertices.has(this._getVertexKey(vertexOrKey));
|
||||
return this._vertexMap.has(this._getVertexKey(vertexOrKey));
|
||||
}
|
||||
|
||||
addVertex(vertex: VO): boolean;
|
||||
|
@ -185,27 +185,27 @@ export abstract class AbstractGraph<
|
|||
*/
|
||||
deleteVertex(vertexOrKey: VO | VertexKey): boolean {
|
||||
const vertexKey = this._getVertexKey(vertexOrKey);
|
||||
return this._vertices.delete(vertexKey);
|
||||
return this._vertexMap.delete(vertexKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(K), where K is the number of vertices to be removed.
|
||||
* Time Complexity: O(K), where K is the number of vertexMap to be removed.
|
||||
* Space Complexity: O(1) - Constant space, as it creates only a few variables.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time Complexity: O(K), where K is the number of vertices to be removed.
|
||||
* Time Complexity: O(K), where K is the number of vertexMap to be removed.
|
||||
* Space Complexity: O(1) - Constant space, as it creates only a few variables.
|
||||
*
|
||||
* The function removes all vertices from a graph and returns a boolean indicating if any vertices were removed.
|
||||
* @param {VO[] | VertexKey[]} vertices - The `vertices` parameter can be either an array of vertices (`VO[]`) or an array
|
||||
* The function removes all vertexMap from a graph and returns a boolean indicating if any vertexMap were removed.
|
||||
* @param {VO[] | VertexKey[]} vertexMap - The `vertexMap` parameter can be either an array of vertexMap (`VO[]`) or an array
|
||||
* of vertex IDs (`VertexKey[]`).
|
||||
* @returns a boolean value. It returns true if at least one vertex was successfully removed, and false if no vertices
|
||||
* @returns a boolean value. It returns true if at least one vertex was successfully removed, and false if no vertexMap
|
||||
* were removed.
|
||||
*/
|
||||
removeManyVertices(vertices: VO[] | VertexKey[]): boolean {
|
||||
removeManyVertices(vertexMap: VO[] | VertexKey[]): boolean {
|
||||
const removed: boolean[] = [];
|
||||
for (const v of vertices) {
|
||||
for (const v of vertexMap) {
|
||||
removed.push(this.deleteVertex(v));
|
||||
}
|
||||
return removed.length > 0;
|
||||
|
@ -220,7 +220,7 @@ export abstract class AbstractGraph<
|
|||
* Time Complexity: O(1) - Depends on the implementation in the concrete class.
|
||||
* Space Complexity: O(1) - Depends on the implementation in the concrete class.
|
||||
*
|
||||
* The function checks if there is an edge between two vertices and returns a boolean value indicating the result.
|
||||
* The function checks if there is an edge between two vertexMap and returns a boolean value indicating the result.
|
||||
* @param {VertexKey | VO} v1 - The parameter v1 can be either a VertexKey or a VO. A VertexKey represents the unique
|
||||
* identifier of a vertex in a graph, while VO represents the type of the vertex object itself.
|
||||
* @param {VertexKey | VO} v2 - The parameter `v2` represents the second vertex in the edge. It can be either a
|
||||
|
@ -266,14 +266,14 @@ export abstract class AbstractGraph<
|
|||
* Time Complexity: O(1) - Constant time for Map and Edge operations.
|
||||
* Space Complexity: O(1) - Constant space, as it creates only a few variables.
|
||||
*
|
||||
* The function sets the weight of an edge between two vertices in a graph.
|
||||
* The function sets the weight of an edge between two vertexMap in a graph.
|
||||
* @param {VertexKey | VO} srcOrKey - The `srcOrKey` parameter can be either a `VertexKey` or a `VO` object. It represents
|
||||
* the source vertex of the edge.
|
||||
* @param {VertexKey | VO} destOrKey - The `destOrKey` parameter represents the destination vertex of the edge. It can be
|
||||
* either a `VertexKey` or a vertex object `VO`.
|
||||
* @param {number} weight - The weight parameter represents the weight of the edge between the source vertex (srcOrKey)
|
||||
* and the destination vertex (destOrKey).
|
||||
* @returns a boolean value. If the edge exists between the source and destination vertices, the function will update
|
||||
* @returns a boolean value. If the edge exists between the source and destination vertexMap, the function will update
|
||||
* the weight of the edge and return true. If the edge does not exist, the function will return false.
|
||||
*/
|
||||
setEdgeWeight(srcOrKey: VertexKey | VO, destOrKey: VertexKey | VO, weight: number): boolean {
|
||||
|
@ -295,12 +295,12 @@ export abstract class AbstractGraph<
|
|||
* Time Complexity: O(P), where P is the number of paths found (in the worst case, exploring all paths).
|
||||
* Space Complexity: O(P) - Linear space, where P is the number of paths found.
|
||||
*
|
||||
* The function `getAllPathsBetween` finds all paths between two vertices in a graph using depth-first search.
|
||||
* The function `getAllPathsBetween` finds all paths between two vertexMap in a graph using depth-first search.
|
||||
* @param {VO | VertexKey} v1 - The parameter `v1` represents either a vertex object (`VO`) or a vertex ID (`VertexKey`).
|
||||
* It is the starting vertex for finding paths.
|
||||
* @param {VO | VertexKey} v2 - The parameter `v2` represents either a vertex object (`VO`) or a vertex ID (`VertexKey`).
|
||||
* @param limit - The count of limitation of result array.
|
||||
* @returns The function `getAllPathsBetween` returns an array of arrays of vertices (`VO[][]`).
|
||||
* @returns The function `getAllPathsBetween` returns an array of arrays of vertexMap (`VO[][]`).
|
||||
*/
|
||||
getAllPathsBetween(v1: VO | VertexKey, v2: VO | VertexKey, limit = 1000): VO[][] {
|
||||
const paths: VO[][] = [];
|
||||
|
@ -343,8 +343,8 @@ export abstract class AbstractGraph<
|
|||
* Space Complexity: O(1) - Constant space.
|
||||
*
|
||||
* The function calculates the sum of weights along a given path.
|
||||
* @param {VO[]} path - An array of vertices (VO) representing a path in a graph.
|
||||
* @returns The function `getPathSumWeight` returns the sum of the weights of the edges in the given path.
|
||||
* @param {VO[]} path - An array of vertexMap (VO) representing a path in a graph.
|
||||
* @returns The function `getPathSumWeight` returns the sum of the weights of the edgeMap in the given path.
|
||||
*/
|
||||
getPathSumWeight(path: VO[]): number {
|
||||
let sum = 0;
|
||||
|
@ -363,17 +363,17 @@ export abstract class AbstractGraph<
|
|||
* Time Complexity: O(V + E) - Depends on the implementation (Dijkstra's algorithm).
|
||||
* Space Complexity: O(V + E) - Depends on the implementation (Dijkstra's algorithm).
|
||||
*
|
||||
* The function `getMinCostBetween` calculates the minimum cost between two vertices in a graph, either based on edge
|
||||
* The function `getMinCostBetween` calculates the minimum cost between two vertexMap in a graph, either based on edge
|
||||
* weights or using a breadth-first search algorithm.
|
||||
* @param {VO | VertexKey} v1 - The parameter `v1` represents the starting vertex or its ID.
|
||||
* @param {VO | VertexKey} v2 - The parameter `v2` represents the destination vertex or its ID. It is the vertex to which
|
||||
* you want to find the minimum cost or weight from the source vertex `v1`.
|
||||
* @param {boolean} [isWeight] - isWeight is an optional parameter that indicates whether the graph edges have weights.
|
||||
* @param {boolean} [isWeight] - isWeight is an optional parameter that indicates whether the graph edgeMap have weights.
|
||||
* If isWeight is set to true, the function will calculate the minimum cost between v1 and v2 based on the weights of
|
||||
* the edges. If isWeight is set to false or not provided, the function will calculate the
|
||||
* @returns The function `getMinCostBetween` returns a number representing the minimum cost between two vertices (`v1`
|
||||
* the edgeMap. If isWeight is set to false or not provided, the function will calculate the
|
||||
* @returns The function `getMinCostBetween` returns a number representing the minimum cost between two vertexMap (`v1`
|
||||
* and `v2`). If the `isWeight` parameter is `true`, it calculates the minimum weight among all paths between the
|
||||
* vertices. If `isWeight` is `false` or not provided, it uses a breadth-first search (BFS) algorithm to calculate the
|
||||
* vertexMap. 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 | undefined {
|
||||
|
@ -430,20 +430,20 @@ export abstract class AbstractGraph<
|
|||
* Time Complexity: O(V + E) - Depends on the implementation (Dijkstra's algorithm or DFS).
|
||||
* Space Complexity: O(V + E) - Depends on the implementation (Dijkstra's algorithm or DFS).
|
||||
*
|
||||
* The function `getMinPathBetween` returns the minimum path between two vertices in a graph, either based on weight or
|
||||
* The function `getMinPathBetween` returns the minimum path between two vertexMap in a graph, either based on weight or
|
||||
* using a breadth-first search algorithm.
|
||||
* @param {VO | VertexKey} v1 - The parameter `v1` represents the starting vertex of the path. It can be either a vertex
|
||||
* object (`VO`) or a vertex ID (`VertexKey`).
|
||||
* @param {VO | VertexKey} v2 - VO | VertexKey - The second vertex or vertex ID between which we want to find the minimum
|
||||
* path.
|
||||
* @param {boolean} [isWeight] - A boolean flag indicating whether to consider the weight of edges in finding the
|
||||
* @param {boolean} [isWeight] - A boolean flag indicating whether to consider the weight of edgeMap in finding the
|
||||
* minimum path. If set to true, the function will use Dijkstra's algorithm to find the minimum weighted path. If set
|
||||
* to false, the function will use breadth-first search (BFS) to find the minimum path.
|
||||
* @param isDFS - If set to true, it enforces the use of getAllPathsBetween to first obtain all possible paths,
|
||||
* 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 `undefined`.
|
||||
* @returns The function `getMinPathBetween` returns an array of vertexMap (`VO[]`) representing the minimum path between
|
||||
* two vertexMap (`v1` and `v2`). If there is no path between the vertexMap, it returns `undefined`.
|
||||
*/
|
||||
getMinPathBetween(v1: VO | VertexKey, v2: VO | VertexKey, isWeight?: boolean, isDFS = false): VO[] | undefined {
|
||||
if (isWeight === undefined) isWeight = false;
|
||||
|
@ -510,7 +510,7 @@ export abstract class AbstractGraph<
|
|||
* Time Complexity: O(V^2 + E) - Quadratic time in the worst case (no heap optimization).
|
||||
* Space Complexity: O(V + E) - Depends on the implementation (Dijkstra's algorithm).
|
||||
*
|
||||
* The function `dijkstraWithoutHeap` implements Dijkstra's algorithm to find the shortest path between two vertices in
|
||||
* The function `dijkstraWithoutHeap` implements Dijkstra's algorithm to find the shortest path between two vertexMap in
|
||||
* 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.
|
||||
|
@ -522,7 +522,7 @@ export abstract class AbstractGraph<
|
|||
* `getMinDist` is set to `true`, the `minDist` property in the result will contain the minimum distance
|
||||
* @param {boolean} [genPaths] - The `genPaths` parameter is a boolean flag that determines whether or not to generate
|
||||
* paths in the Dijkstra algorithm. If `genPaths` is set to `true`, the algorithm will calculate and return the
|
||||
* shortest paths from the source vertex to all other vertices in the graph. If `genPaths
|
||||
* shortest paths from the source vertex to all other vertexMap in the graph. If `genPaths
|
||||
* @returns The function `dijkstraWithoutHeap` returns an object of type `DijkstraResult<VO>`.
|
||||
*/
|
||||
dijkstraWithoutHeap(
|
||||
|
@ -540,7 +540,7 @@ export abstract class AbstractGraph<
|
|||
let minPath: VO[] = [];
|
||||
const paths: VO[][] = [];
|
||||
|
||||
const vertices = this._vertices;
|
||||
const vertexMap = this._vertexMap;
|
||||
const distMap: Map<VO, number> = new Map();
|
||||
const seen: Set<VO> = new Set();
|
||||
const preMap: Map<VO, VO | undefined> = new Map(); // predecessor
|
||||
|
@ -552,7 +552,7 @@ export abstract class AbstractGraph<
|
|||
return undefined;
|
||||
}
|
||||
|
||||
for (const vertex of vertices) {
|
||||
for (const vertex of vertexMap) {
|
||||
const vertexOrKey = vertex[1];
|
||||
if (vertexOrKey instanceof AbstractVertex) distMap.set(vertexOrKey, Infinity);
|
||||
}
|
||||
|
@ -574,7 +574,7 @@ export abstract class AbstractGraph<
|
|||
};
|
||||
|
||||
const getPaths = (minV: VO | undefined) => {
|
||||
for (const vertex of vertices) {
|
||||
for (const vertex of vertexMap) {
|
||||
const vertexOrKey = vertex[1];
|
||||
|
||||
if (vertexOrKey instanceof AbstractVertex) {
|
||||
|
@ -591,7 +591,7 @@ export abstract class AbstractGraph<
|
|||
}
|
||||
};
|
||||
|
||||
for (let i = 1; i < vertices.size; i++) {
|
||||
for (let i = 1; i < vertexMap.size; i++) {
|
||||
const cur = getMinOfNoSeen();
|
||||
if (cur) {
|
||||
seen.add(cur);
|
||||
|
@ -643,7 +643,7 @@ export abstract class AbstractGraph<
|
|||
* Dijkstra algorithm time: O(logVE) space: O(VO + EO)
|
||||
*
|
||||
* Dijkstra's algorithm only solves the single-source shortest path problem, while the Bellman-Ford algorithm and Floyd-Warshall algorithm can address shortest paths between all pairs of nodes.
|
||||
* Dijkstra's algorithm is suitable for graphs with non-negative edge weights, whereas the Bellman-Ford algorithm and Floyd-Warshall algorithm can handle negative-weight edges.
|
||||
* Dijkstra's algorithm is suitable for graphs with non-negative edge weights, whereas the Bellman-Ford algorithm and Floyd-Warshall algorithm can handle negative-weight edgeMap.
|
||||
* The time complexity of Dijkstra's algorithm and the Bellman-Ford algorithm depends on the size of the graph, while the time complexity of the Floyd-Warshall algorithm is O(VO^3), where VO is the number of nodes. For dense graphs, Floyd-Warshall might become slower.
|
||||
*
|
||||
* /
|
||||
|
@ -664,13 +664,13 @@ export abstract class AbstractGraph<
|
|||
* start. It can be either a vertex object or a vertex ID.
|
||||
* @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.
|
||||
* will calculate the shortest paths to all other vertexMap from the source vertex.
|
||||
* @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
|
||||
* @param {boolean} [genPaths] - The `genPaths` parameter is a boolean flag that determines whether or not to generate
|
||||
* paths in the Dijkstra algorithm. If `genPaths` is set to `true`, the algorithm will calculate and return the
|
||||
* shortest paths from the source vertex to all other vertices in the graph. If `genPaths
|
||||
* shortest paths from the source vertex to all other vertexMap in the graph. If `genPaths
|
||||
* @returns The function `dijkstra` returns an object of type `DijkstraResult<VO>`.
|
||||
*/
|
||||
dijkstra(
|
||||
|
@ -687,7 +687,7 @@ export abstract class AbstractGraph<
|
|||
let minDest: VO | undefined = undefined;
|
||||
let minPath: VO[] = [];
|
||||
const paths: VO[][] = [];
|
||||
const vertices = this._vertices;
|
||||
const vertexMap = this._vertexMap;
|
||||
const distMap: Map<VO, number> = new Map();
|
||||
const seen: Set<VO> = new Set();
|
||||
const preMap: Map<VO, VO | undefined> = new Map(); // predecessor
|
||||
|
@ -697,7 +697,7 @@ export abstract class AbstractGraph<
|
|||
|
||||
if (!srcVertex) return undefined;
|
||||
|
||||
for (const vertex of vertices) {
|
||||
for (const vertex of vertexMap) {
|
||||
const vertexOrKey = vertex[1];
|
||||
if (vertexOrKey instanceof AbstractVertex) distMap.set(vertexOrKey, Infinity);
|
||||
}
|
||||
|
@ -709,12 +709,12 @@ export abstract class AbstractGraph<
|
|||
preMap.set(srcVertex, undefined);
|
||||
|
||||
/**
|
||||
* The function `getPaths` retrieves all paths from vertices to a specified minimum vertex.
|
||||
* The function `getPaths` retrieves all paths from vertexMap to a specified minimum vertex.
|
||||
* @param {VO | undefined} minV - The parameter `minV` is of type `VO | undefined`. It represents the minimum vertex value or
|
||||
* undefined.
|
||||
*/
|
||||
const getPaths = (minV: VO | undefined) => {
|
||||
for (const vertex of vertices) {
|
||||
for (const vertex of vertexMap) {
|
||||
const vertexOrKey = vertex[1];
|
||||
if (vertexOrKey instanceof AbstractVertex) {
|
||||
const path: VO[] = [vertexOrKey];
|
||||
|
@ -795,16 +795,16 @@ export abstract class AbstractGraph<
|
|||
* Space Complexity: O(V + E) - Depends on the implementation (Bellman-Ford algorithm).
|
||||
*
|
||||
* one to rest pairs
|
||||
* The Bellman-Ford algorithm is also used to find the shortest paths from a source node to all other nodes in a graph. Unlike Dijkstra's algorithm, it can handle edge weights that are negative. Its basic idea involves iterative relaxation of all edges for several rounds to gradually approximate the shortest paths. Due to its ability to handle negative-weight edges, the Bellman-Ford algorithm is more flexible in some scenarios.
|
||||
* The Bellman-Ford algorithm is also used to find the shortest paths from a source node to all other nodes in a graph. Unlike Dijkstra's algorithm, it can handle edge weights that are negative. Its basic idea involves iterative relaxation of all edgeMap for several rounds to gradually approximate the shortest paths. Due to its ability to handle negative-weight edgeMap, the Bellman-Ford algorithm is more flexible in some scenarios.
|
||||
* The `bellmanFord` function implements the Bellman-Ford algorithm to find the shortest path from a source vertex to
|
||||
* all other vertices in a graph, and optionally detects negative cycles and generates the minimum path.
|
||||
* all other vertexMap in a graph, and optionally detects negative cycles and generates the minimum path.
|
||||
* @param {VO | VertexKey} src - The `src` parameter is the source vertex from which the Bellman-Ford algorithm will
|
||||
* start calculating the shortest paths. It can be either a vertex object or a vertex ID.
|
||||
* @param {boolean} [scanNegativeCycle] - A boolean flag indicating whether to scan for negative cycles in the graph.
|
||||
* @param {boolean} [getMin] - The `getMin` parameter is a boolean flag that determines whether the algorithm should
|
||||
* calculate the minimum distance from the source vertex to all other vertices in the graph. If `getMin` is set to
|
||||
* calculate the minimum distance from the source vertex to all other vertexMap in the graph. If `getMin` is set to
|
||||
* `true`, the algorithm will find the minimum distance and update the `min` variable with the minimum
|
||||
* @param {boolean} [genPath] - A boolean flag indicating whether to generate paths for all vertices from the source
|
||||
* @param {boolean} [genPath] - A boolean flag indicating whether to generate paths for all vertexMap from the source
|
||||
* vertex.
|
||||
* @returns The function `bellmanFord` returns an object with the following properties:
|
||||
*/
|
||||
|
@ -823,12 +823,12 @@ export abstract class AbstractGraph<
|
|||
if (scanNegativeCycle) hasNegativeCycle = false;
|
||||
if (!srcVertex) return { hasNegativeCycle, distMap, preMap, paths, min, minPath };
|
||||
|
||||
const vertices = this._vertices;
|
||||
const numOfVertices = vertices.size;
|
||||
const edges = this.edgeSet();
|
||||
const numOfEdges = edges.length;
|
||||
const vertexMap = this._vertexMap;
|
||||
const numOfVertices = vertexMap.size;
|
||||
const edgeMap = this.edgeSet();
|
||||
const numOfEdges = edgeMap.length;
|
||||
|
||||
this._vertices.forEach(vertex => {
|
||||
this._vertexMap.forEach(vertex => {
|
||||
distMap.set(vertex, Infinity);
|
||||
});
|
||||
|
||||
|
@ -836,10 +836,10 @@ export abstract class AbstractGraph<
|
|||
|
||||
for (let i = 1; i < numOfVertices; ++i) {
|
||||
for (let j = 0; j < numOfEdges; ++j) {
|
||||
const ends = this.getEndsOfEdge(edges[j]);
|
||||
const ends = this.getEndsOfEdge(edgeMap[j]);
|
||||
if (ends) {
|
||||
const [s, d] = ends;
|
||||
const weight = edges[j].weight;
|
||||
const weight = edgeMap[j].weight;
|
||||
const sWeight = distMap.get(s);
|
||||
const dWeight = distMap.get(d);
|
||||
if (sWeight !== undefined && dWeight !== undefined) {
|
||||
|
@ -865,7 +865,7 @@ export abstract class AbstractGraph<
|
|||
}
|
||||
|
||||
if (genPath) {
|
||||
for (const vertex of vertices) {
|
||||
for (const vertex of vertexMap) {
|
||||
const vertexOrKey = vertex[1];
|
||||
if (vertexOrKey instanceof AbstractVertex) {
|
||||
const path: VO[] = [vertexOrKey];
|
||||
|
@ -882,10 +882,10 @@ export abstract class AbstractGraph<
|
|||
}
|
||||
|
||||
for (let j = 0; j < numOfEdges; ++j) {
|
||||
const ends = this.getEndsOfEdge(edges[j]);
|
||||
const ends = this.getEndsOfEdge(edgeMap[j]);
|
||||
if (ends) {
|
||||
const [s] = ends;
|
||||
const weight = edges[j].weight;
|
||||
const weight = edgeMap[j].weight;
|
||||
const sWeight = distMap.get(s);
|
||||
if (sWeight) {
|
||||
if (sWeight !== Infinity && sWeight + weight < sWeight) hasNegativeCycle = true;
|
||||
|
@ -908,7 +908,7 @@ export abstract class AbstractGraph<
|
|||
/**
|
||||
* BellmanFord time:O(VE) space:O(VO)
|
||||
* one to rest pairs
|
||||
* The Bellman-Ford algorithm is also used to find the shortest paths from a source node to all other nodes in a graph. Unlike Dijkstra's algorithm, it can handle edge weights that are negative. Its basic idea involves iterative relaxation of all edges for several rounds to gradually approximate the shortest paths. Due to its ability to handle negative-weight edges, the Bellman-Ford algorithm is more flexible in some scenarios.
|
||||
* The Bellman-Ford algorithm is also used to find the shortest paths from a source node to all other nodes in a graph. Unlike Dijkstra's algorithm, it can handle edge weights that are negative. Its basic idea involves iterative relaxation of all edgeMap for several rounds to gradually approximate the shortest paths. Due to its ability to handle negative-weight edgeMap, the Bellman-Ford algorithm is more flexible in some scenarios.
|
||||
* The `bellmanFord` function implements the Bellman-Ford algorithm to find the shortest path from a source vertex to
|
||||
*/
|
||||
|
||||
|
@ -917,7 +917,7 @@ export abstract class AbstractGraph<
|
|||
* Space Complexity: O(V^2) - Quadratic space (Floyd-Warshall algorithm).
|
||||
* Not support graph with negative weight cycle
|
||||
* all pairs
|
||||
* The Floyd-Warshall algorithm is used to find the shortest paths between all pairs of nodes in a graph. It employs dynamic programming to compute the shortest paths from any node to any other node. The Floyd-Warshall algorithm's advantage lies in its ability to handle graphs with negative-weight edges, and it can simultaneously compute shortest paths between any two nodes.
|
||||
* The Floyd-Warshall algorithm is used to find the shortest paths between all pairs of nodes in a graph. It employs dynamic programming to compute the shortest paths from any node to any other node. The Floyd-Warshall algorithm's advantage lies in its ability to handle graphs with negative-weight edgeMap, and it can simultaneously compute shortest paths between any two nodes.
|
||||
* /
|
||||
|
||||
/**
|
||||
|
@ -926,16 +926,16 @@ export abstract class AbstractGraph<
|
|||
*
|
||||
* Not support graph with negative weight cycle
|
||||
* all pairs
|
||||
* The Floyd-Warshall algorithm is used to find the shortest paths between all pairs of nodes in a graph. It employs dynamic programming to compute the shortest paths from any node to any other node. The Floyd-Warshall algorithm's advantage lies in its ability to handle graphs with negative-weight edges, and it can simultaneously compute shortest paths between any two nodes.
|
||||
* The function implements the Floyd-Warshall algorithm to find the shortest path between all pairs of vertices in a
|
||||
* The Floyd-Warshall algorithm is used to find the shortest paths between all pairs of nodes in a graph. It employs dynamic programming to compute the shortest paths from any node to any other node. The Floyd-Warshall algorithm's advantage lies in its ability to handle graphs with negative-weight edgeMap, and it can simultaneously compute shortest paths between any two nodes.
|
||||
* The function implements the Floyd-Warshall algorithm to find the shortest path between all pairs of vertexMap in a
|
||||
* 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 `undefined`) representing the predecessor vertices in the shortest
|
||||
* path between vertices in the
|
||||
* property is a 2D array of numbers representing the shortest path costs between vertexMap in a graph. The
|
||||
* `predecessor` property is a 2D array of vertexMap (or `undefined`) representing the predecessor vertexMap in the shortest
|
||||
* path between vertexMap in the
|
||||
*/
|
||||
floydWarshall(): { costs: number[][]; predecessor: (VO | undefined)[][] } {
|
||||
const idAndVertices = [...this._vertices];
|
||||
const idAndVertices = [...this._vertexMap];
|
||||
const n = idAndVertices.length;
|
||||
|
||||
const costs: number[][] = [];
|
||||
|
@ -974,7 +974,7 @@ export abstract class AbstractGraph<
|
|||
* Space Complexity: O(V) - Linear space (Tarjan's algorithm).
|
||||
* Tarjan is an algorithm based on dfs,which is used to solve the connectivity problem of graphs.
|
||||
* Tarjan can find cycles in directed or undirected graph
|
||||
* Tarjan can find the articulation points and bridges(critical edges) of undirected graphs in linear time,
|
||||
* Tarjan can find the articulation points and bridges(critical edgeMap) of undirected graphs in linear time,
|
||||
* Tarjan solve the bi-connected components of undirected graphs;
|
||||
* Tarjan can find the SSC(strongly connected components), articulation points, and bridges of directed graphs.
|
||||
* /
|
||||
|
@ -985,22 +985,22 @@ export abstract class AbstractGraph<
|
|||
*
|
||||
* Tarjan is an algorithm based on dfs,which is used to solve the connectivity problem of graphs.
|
||||
* Tarjan can find cycles in directed or undirected graph
|
||||
* Tarjan can find the articulation points and bridges(critical edges) of undirected graphs in linear time,
|
||||
* Tarjan can find the articulation points and bridges(critical edgeMap) of undirected graphs in linear time,
|
||||
* Tarjan solve the bi-connected components of undirected graphs;
|
||||
* Tarjan can find the SSC(strongly connected components), articulation points, and bridges of directed graphs.
|
||||
* The `tarjan` function is used to perform various graph analysis tasks such as finding articulation points, bridges,
|
||||
* strongly connected components (SCCs), and cycles in a graph.
|
||||
* @param {boolean} [needCutVertexes] - A boolean value indicating whether or not to calculate and return the
|
||||
* articulation points in the graph. Articulation points are the vertices in a graph whose removal would increase the
|
||||
* articulation points in the graph. Articulation points are the vertexMap in a graph whose removal would increase the
|
||||
* number of connected components in the graph.
|
||||
* @param {boolean} [needBridges] - A boolean flag indicating whether the algorithm should find and return the bridges
|
||||
* (edges whose removal would increase the number of connected components in the graph).
|
||||
* (edgeMap whose removal would increase the number of connected components in the graph).
|
||||
* @param {boolean} [needSCCs] - A boolean value indicating whether the Strongly Connected Components (SCCs) of the
|
||||
* graph are needed. If set to true, the function will calculate and return the SCCs of the graph. If set to false, the
|
||||
* SCCs will not be calculated or returned.
|
||||
* @param {boolean} [needCycles] - A boolean flag indicating whether the algorithm should find cycles in the graph. If
|
||||
* set to true, the algorithm will return a map of cycles, where the keys are the low values of the SCCs and the values
|
||||
* are arrays of vertices that form cycles within the SCCs.
|
||||
* are arrays of vertexMap that form cycles within the SCCs.
|
||||
* @returns The function `tarjan` returns an object with the following properties:
|
||||
*/
|
||||
tarjan(
|
||||
|
@ -1021,13 +1021,13 @@ export abstract class AbstractGraph<
|
|||
|
||||
const dfnMap: Map<VO, number> = new Map();
|
||||
const lowMap: Map<VO, number> = new Map();
|
||||
const vertices = this._vertices;
|
||||
vertices.forEach(v => {
|
||||
const vertexMap = this._vertexMap;
|
||||
vertexMap.forEach(v => {
|
||||
dfnMap.set(v, -1);
|
||||
lowMap.set(v, Infinity);
|
||||
});
|
||||
|
||||
const [root] = vertices.values();
|
||||
const [root] = vertexMap.values();
|
||||
|
||||
const cutVertexes: VO[] = [];
|
||||
const bridges: EO[] = [];
|
||||
|
@ -1232,7 +1232,7 @@ export abstract class AbstractGraph<
|
|||
}
|
||||
|
||||
protected* _getIterator(): IterableIterator<[VertexKey, V | undefined]> {
|
||||
for (const vertex of this._vertices.values()) {
|
||||
for (const vertex of this._vertexMap.values()) {
|
||||
yield [vertex.key, vertex.value];
|
||||
}
|
||||
}
|
||||
|
@ -1244,13 +1244,13 @@ export abstract class AbstractGraph<
|
|||
return false;
|
||||
// throw (new Error('Duplicated vertex key is not allowed'));
|
||||
}
|
||||
this._vertices.set(newVertex.key, newVertex);
|
||||
this._vertexMap.set(newVertex.key, newVertex);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected _getVertex(vertexOrKey: VertexKey | VO): VO | undefined {
|
||||
const vertexKey = this._getVertexKey(vertexOrKey);
|
||||
return this._vertices.get(vertexKey) || undefined;
|
||||
return this._vertexMap.get(vertexKey) || undefined;
|
||||
}
|
||||
|
||||
protected _getVertexKey(vertexOrKey: VO | VertexKey): VertexKey {
|
||||
|
|
|
@ -28,7 +28,7 @@ export class DirectedEdge<E = any> extends AbstractEdge<E> {
|
|||
dest: VertexKey;
|
||||
|
||||
/**
|
||||
* The constructor function initializes the source and destination vertices of an edge, along with an optional weight
|
||||
* The constructor function initializes the source and destination vertexMap of an edge, along with an optional weight
|
||||
* and value.
|
||||
* @param {VertexKey} src - The `src` parameter is the source vertex ID. It represents the starting point of an edge in
|
||||
* a graph.
|
||||
|
@ -80,7 +80,7 @@ export class DirectedGraph<
|
|||
/**
|
||||
* The function creates a new vertex with an optional value and returns it.
|
||||
* @param {VertexKey} key - The `key` parameter is the unique identifier for the vertex. It is of type `VertexKey`, which
|
||||
* could be a number or a string depending on how you want to identify your vertices.
|
||||
* could be a number or a string depending on how you want to identify your vertexMap.
|
||||
* @param [value] - The 'value' parameter is an optional value that can be assigned to the vertex. If a value is provided,
|
||||
* it will be assigned to the 'value' property of the vertex. If no value is provided, the 'value' property will be
|
||||
* assigned the same value as the 'key' parameter
|
||||
|
@ -96,7 +96,7 @@ export class DirectedGraph<
|
|||
*/
|
||||
|
||||
/**
|
||||
* The function creates a directed edge between two vertices with an optional weight and value.
|
||||
* The function creates a directed edge between two vertexMap with an optional weight and value.
|
||||
* @param {VertexKey} src - The source vertex ID of the edge. It represents the starting point of the edge.
|
||||
* @param {VertexKey} dest - The `dest` parameter is the identifier of the destination vertex for the edge.
|
||||
* @param {number} [weight] - The weight parameter is an optional number that represents the weight of the edge. If no
|
||||
|
@ -110,23 +110,23 @@ export class DirectedGraph<
|
|||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(|V|) where |V| is the number of vertices
|
||||
* Time Complexity: O(|V|) where |V| is the number of vertexMap
|
||||
* Space Complexity: O(1)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time Complexity: O(|V|) where |V| is the number of vertices
|
||||
* Time Complexity: O(|V|) where |V| is the number of vertexMap
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The `getEdge` function retrieves an edge between two vertices based on their source and destination IDs.
|
||||
* The `getEdge` function retrieves an edge between two vertexMap based on their source and destination IDs.
|
||||
* @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 undefined if no such edge is found.
|
||||
* @returns the first edge found between the source and destination vertexMap, or undefined if no such edge is found.
|
||||
*/
|
||||
getEdge(srcOrKey: VO | VertexKey | undefined, destOrKey: VO | VertexKey | undefined): EO | undefined {
|
||||
let edges: EO[] = [];
|
||||
let edgeMap: EO[] = [];
|
||||
|
||||
if (srcOrKey !== undefined && destOrKey !== undefined) {
|
||||
const src: VO | undefined = this._getVertex(srcOrKey);
|
||||
|
@ -135,24 +135,24 @@ export class DirectedGraph<
|
|||
if (src && dest) {
|
||||
const srcOutEdges = this._outEdgeMap.get(src);
|
||||
if (srcOutEdges) {
|
||||
edges = srcOutEdges.filter(edge => edge.dest === dest.key);
|
||||
edgeMap = srcOutEdges.filter(edge => edge.dest === dest.key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return edges[0] || undefined;
|
||||
return edgeMap[0] || undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(|E|) where |E| is the number of edges
|
||||
* Time Complexity: O(|E|) where |E| is the number of edgeMap
|
||||
* Space Complexity: O(1)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time Complexity: O(|E|) where |E| is the number of edges
|
||||
* Time Complexity: O(|E|) where |E| is the number of edgeMap
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The function removes an edge between two vertices in a graph and returns the removed edge.
|
||||
* The function removes an edge between two vertexMap 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 undefined if either the source or destination vertex does not exist.
|
||||
|
@ -178,13 +178,13 @@ export class DirectedGraph<
|
|||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(E) where E is the number of edges
|
||||
* Time Complexity: O(E) where E is the number of edgeMap
|
||||
* Space Complexity: O(1)
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Time Complexity: O(E) where E is the number of edges
|
||||
* Time Complexity: O(E) where E is the number of edgeMap
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The `deleteEdge` function removes an edge from a graph and returns the removed edge.
|
||||
|
@ -256,24 +256,24 @@ export class DirectedGraph<
|
|||
this._inEdgeMap.delete(vertex)
|
||||
}
|
||||
|
||||
return this._vertices.delete(vertexKey);
|
||||
return this._vertexMap.delete(vertexKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(|E|) where |E| is the number of edges
|
||||
* Time Complexity: O(|E|) where |E| is the number of edgeMap
|
||||
* Space Complexity: O(1)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time Complexity: O(|E|) where |E| is the number of edges
|
||||
* Time Complexity: O(|E|) where |E| is the number of edgeMap
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The function removes edges between two vertices and returns the removed edges.
|
||||
* The function removes edgeMap between two vertexMap and returns the removed edgeMap.
|
||||
* @param {VertexKey | VO} v1 - The parameter `v1` can be either a `VertexKey` or a `VO`. A `VertexKey` represents the
|
||||
* unique identifier of a vertex in a graph, while `VO` represents the actual vertex object.
|
||||
* @param {VertexKey | VO} v2 - The parameter `v2` represents either a `VertexKey` or a `VO` object. It is used to specify
|
||||
* the second vertex in the edge that needs to be removed.
|
||||
* @returns an array of removed edges (EO[]).
|
||||
* @returns an array of removed edgeMap (EO[]).
|
||||
*/
|
||||
deleteEdgesBetween(v1: VertexKey | VO, v2: VertexKey | VO): EO[] {
|
||||
const removed: EO[] = [];
|
||||
|
@ -298,10 +298,10 @@ export class DirectedGraph<
|
|||
* Time Complexity: O(1)
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The function `incomingEdgesOf` returns an array of incoming edges for a given vertex or vertex ID.
|
||||
* The function `incomingEdgesOf` returns an array of incoming edgeMap for a given vertex or vertex ID.
|
||||
* @param {VO | VertexKey} vertexOrKey - The parameter `vertexOrKey` can be either a vertex object (`VO`) or a vertex ID
|
||||
* (`VertexKey`).
|
||||
* @returns The method `incomingEdgesOf` returns an array of edges (`EO[]`).
|
||||
* @returns The method `incomingEdgesOf` returns an array of edgeMap (`EO[]`).
|
||||
*/
|
||||
incomingEdgesOf(vertexOrKey: VO | VertexKey): EO[] {
|
||||
const target = this._getVertex(vertexOrKey);
|
||||
|
@ -320,10 +320,10 @@ export class DirectedGraph<
|
|||
* Time Complexity: O(1)
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The function `outgoingEdgesOf` returns an array of outgoing edges from a given vertex or vertex ID.
|
||||
* The function `outgoingEdgesOf` returns an array of outgoing edgeMap from a given vertex or vertex ID.
|
||||
* @param {VO | VertexKey} vertexOrKey - The parameter `vertexOrKey` can accept either a vertex object (`VO`) or a vertex ID
|
||||
* (`VertexKey`).
|
||||
* @returns The method `outgoingEdgesOf` returns an array of edges (`EO[]`).
|
||||
* @returns The method `outgoingEdgesOf` returns an array of edgeMap (`EO[]`).
|
||||
*/
|
||||
outgoingEdgesOf(vertexOrKey: VO | VertexKey): EO[] {
|
||||
const target = this._getVertex(vertexOrKey);
|
||||
|
@ -359,9 +359,9 @@ export class DirectedGraph<
|
|||
* Time Complexity: O(1)
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The function "inDegreeOf" returns the number of incoming edges for a given vertex.
|
||||
* The function "inDegreeOf" returns the number of incoming edgeMap for a given vertex.
|
||||
* @param {VertexKey | VO} vertexOrKey - The parameter `vertexOrKey` can be either a `VertexKey` or a `VO`.
|
||||
* @returns The number of incoming edges of the specified vertex or vertex ID.
|
||||
* @returns The number of incoming edgeMap of the specified vertex or vertex ID.
|
||||
*/
|
||||
inDegreeOf(vertexOrKey: VertexKey | VO): number {
|
||||
return this.incomingEdgesOf(vertexOrKey).length;
|
||||
|
@ -376,9 +376,9 @@ export class DirectedGraph<
|
|||
* Time Complexity: O(1)
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The function `outDegreeOf` returns the number of outgoing edges from a given vertex.
|
||||
* The function `outDegreeOf` returns the number of outgoing edgeMap from a given vertex.
|
||||
* @param {VertexKey | VO} vertexOrKey - The parameter `vertexOrKey` can be either a `VertexKey` or a `VO`.
|
||||
* @returns The number of outgoing edges from the specified vertex or vertex ID.
|
||||
* @returns The number of outgoing edgeMap from the specified vertex or vertex ID.
|
||||
*/
|
||||
outDegreeOf(vertexOrKey: VertexKey | VO): number {
|
||||
return this.outgoingEdgesOf(vertexOrKey).length;
|
||||
|
@ -393,9 +393,9 @@ export class DirectedGraph<
|
|||
* Time Complexity: O(1)
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The function "edgesOf" returns an array of both outgoing and incoming edges of a given vertex or vertex ID.
|
||||
* The function "edgesOf" returns an array of both outgoing and incoming edgeMap of a given vertex or vertex ID.
|
||||
* @param {VertexKey | VO} vertexOrKey - The parameter `vertexOrKey` can be either a `VertexKey` or a `VO`.
|
||||
* @returns The function `edgesOf` returns an array of edges.
|
||||
* @returns The function `edgesOf` returns an array of edgeMap.
|
||||
*/
|
||||
edgesOf(vertexOrKey: VertexKey | VO): EO[] {
|
||||
return [...this.outgoingEdgesOf(vertexOrKey), ...this.incomingEdgesOf(vertexOrKey)];
|
||||
|
@ -436,18 +436,18 @@ export class DirectedGraph<
|
|||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(|E|) where |E| is the number of edges
|
||||
* Time Complexity: O(|E|) where |E| is the number of edgeMap
|
||||
* Space Complexity: O(1)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time Complexity: O(|E|) where |E| is the number of edges
|
||||
* Time Complexity: O(|E|) where |E| is the number of edgeMap
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The function `getDestinations` returns an array of destination vertices connected to a given vertex.
|
||||
* The function `getDestinations` returns an array of destination vertexMap connected to a given vertex.
|
||||
* @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[]).
|
||||
* @returns an array of vertexMap (VO[]).
|
||||
*/
|
||||
getDestinations(vertex: VO | VertexKey | undefined): VO[] {
|
||||
if (vertex === undefined) {
|
||||
|
@ -465,27 +465,27 @@ export class DirectedGraph<
|
|||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(|V| + |E|) where |V| is the number of vertices and |E| is the number of edges
|
||||
* Time Complexity: O(|V| + |E|) where |V| is the number of vertexMap and |E| is the number of edgeMap
|
||||
* Space Complexity: O(|V|)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time Complexity: O(|V| + |E|) where |V| is the number of vertices and |E| is the number of edges
|
||||
* Time Complexity: O(|V| + |E|) where |V| is the number of vertexMap and |E| is the number of edgeMap
|
||||
* Space Complexity: O(|V|)
|
||||
*
|
||||
* The `topologicalSort` function performs a topological sort on a graph and returns an array of vertices or vertex IDs
|
||||
* The `topologicalSort` function performs a topological sort on a graph and returns an array of vertexMap or vertex IDs
|
||||
* 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 undefined.
|
||||
* property to use for sorting the vertexMap. It can have two possible values: 'vertex' or 'key'. If 'vertex' is
|
||||
* specified, the vertexMap themselves will be used for sorting. If 'key' is specified, the ids of
|
||||
* @returns an array of vertexMap or vertex IDs in topological order. If there is a cycle in the graph, it returns undefined.
|
||||
*/
|
||||
topologicalSort(propertyName?: 'vertex' | 'key'): Array<VO | VertexKey> | 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
|
||||
const statusMap: Map<VO | VertexKey, TopologicalStatus> = new Map<VO | VertexKey, TopologicalStatus>();
|
||||
for (const entry of this.vertices) {
|
||||
for (const entry of this.vertexMap) {
|
||||
statusMap.set(entry[1], 0);
|
||||
}
|
||||
|
||||
|
@ -506,7 +506,7 @@ export class DirectedGraph<
|
|||
sorted.push(cur);
|
||||
};
|
||||
|
||||
for (const entry of this.vertices) {
|
||||
for (const entry of this.vertexMap) {
|
||||
if (statusMap.get(entry[1]) === 0) {
|
||||
dfs(entry[1]);
|
||||
}
|
||||
|
@ -519,38 +519,38 @@ export class DirectedGraph<
|
|||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(|E|) where |E| is the number of edges
|
||||
* Time Complexity: O(|E|) where |E| is the number of edgeMap
|
||||
* Space Complexity: O(|E|)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time Complexity: O(|E|) where |E| is the number of edges
|
||||
* Time Complexity: O(|E|) where |E| is the number of edgeMap
|
||||
* Space Complexity: O(|E|)
|
||||
*
|
||||
* The `edgeSet` function returns an array of all the edges in the graph.
|
||||
* @returns The `edgeSet()` method returns an array of edges (`EO[]`).
|
||||
* The `edgeSet` function returns an array of all the edgeMap in the graph.
|
||||
* @returns The `edgeSet()` method returns an array of edgeMap (`EO[]`).
|
||||
*/
|
||||
edgeSet(): EO[] {
|
||||
let edges: EO[] = [];
|
||||
let edgeMap: EO[] = [];
|
||||
this._outEdgeMap.forEach(outEdges => {
|
||||
edges = [...edges, ...outEdges];
|
||||
edgeMap = [...edgeMap, ...outEdges];
|
||||
});
|
||||
return edges;
|
||||
return edgeMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(|E|) where |E| is the number of edges
|
||||
* Time Complexity: O(|E|) where |E| is the number of edgeMap
|
||||
* Space Complexity: O(1)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time Complexity: O(|E|) where |E| is the number of edges
|
||||
* Time Complexity: O(|E|) where |E| is the number of edgeMap
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The function `getNeighbors` returns an array of neighboring vertices of a given vertex or vertex ID in a graph.
|
||||
* The function `getNeighbors` returns an array of neighboring vertexMap of a given vertex or vertex ID in a graph.
|
||||
* @param {VO | VertexKey} vertexOrKey - The parameter `vertexOrKey` can be either a vertex object (`VO`) or a vertex ID
|
||||
* (`VertexKey`).
|
||||
* @returns an array of vertices (VO[]).
|
||||
* @returns an array of vertexMap (VO[]).
|
||||
*/
|
||||
getNeighbors(vertexOrKey: VO | VertexKey): VO[] {
|
||||
const neighbors: VO[] = [];
|
||||
|
@ -577,10 +577,10 @@ export class DirectedGraph<
|
|||
* Time Complexity: O(1)
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The function "getEndsOfEdge" returns the source and destination vertices of an edge if it exists in the graph,
|
||||
* The function "getEndsOfEdge" returns the source and destination vertexMap of an edge if it exists in the graph,
|
||||
* 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
|
||||
* @returns The function `getEndsOfEdge` returns an array containing two vertexMap `[VO, VO]` if the edge exists in the
|
||||
* graph. If the edge does not exist, it returns `undefined`.
|
||||
*/
|
||||
getEndsOfEdge(edge: EO): [VO, VO] | undefined {
|
||||
|
@ -605,7 +605,7 @@ export class DirectedGraph<
|
|||
* Time Complexity: O(1)
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The function `_addEdgeOnly` adds an edge to a graph if the source and destination vertices exist.
|
||||
* The function `_addEdgeOnly` adds an edge to a graph if the source and destination vertexMap exist.
|
||||
* @param {EO} edge - The parameter `edge` is of type `EO`, which represents an edge in a graph. It is the edge that
|
||||
* needs to be added to the graph.
|
||||
* @returns a boolean value. It returns true if the edge was successfully added to the graph, and false if either the
|
||||
|
|
|
@ -47,24 +47,24 @@ export class MapGraph<
|
|||
EO extends MapEdge<E> = MapEdge<E>
|
||||
> extends DirectedGraph<V, E, VO, EO> {
|
||||
/**
|
||||
* The constructor function initializes the origin and bottomRight properties of a MapGraphCoordinate object.
|
||||
* @param {MapGraphCoordinate} origin - The `origin` parameter is a `MapGraphCoordinate` object that represents the
|
||||
* The constructor function initializes the originCoord and bottomRight properties of a MapGraphCoordinate object.
|
||||
* @param {MapGraphCoordinate} originCoord - The `originCoord` parameter is a `MapGraphCoordinate` object that represents the
|
||||
* starting point or reference point of the map graph. It defines the coordinates of the top-left corner of the map
|
||||
* graph.
|
||||
* @param {MapGraphCoordinate} [bottomRight] - The `bottomRight` parameter is an optional parameter of type
|
||||
* `MapGraphCoordinate`. It represents the bottom right coordinate of a map graph. If this parameter is not provided,
|
||||
* it will default to `undefined`.
|
||||
*/
|
||||
constructor(origin: MapGraphCoordinate, bottomRight?: MapGraphCoordinate) {
|
||||
constructor(originCoord: MapGraphCoordinate, bottomRight?: MapGraphCoordinate) {
|
||||
super();
|
||||
this._origin = origin;
|
||||
this._originCoord = originCoord;
|
||||
this._bottomRight = bottomRight;
|
||||
}
|
||||
|
||||
protected _origin: MapGraphCoordinate = [0, 0];
|
||||
protected _originCoord: MapGraphCoordinate = [0, 0];
|
||||
|
||||
get origin(): MapGraphCoordinate {
|
||||
return this._origin;
|
||||
get originCoord(): MapGraphCoordinate {
|
||||
return this._originCoord;
|
||||
}
|
||||
|
||||
protected _bottomRight: MapGraphCoordinate | undefined;
|
||||
|
@ -84,7 +84,7 @@ export class MapGraph<
|
|||
* @param {number} long - The `long` parameter represents the longitude coordinate of the vertex.
|
||||
* @returns The method is returning a new instance of the `MapVertex` class, casted as type `VO`.
|
||||
*/
|
||||
override createVertex(key: VertexKey, value?: V, lat: number = this.origin[0], long: number = this.origin[1]): VO {
|
||||
override createVertex(key: VertexKey, value?: V, lat: number = this.originCoord[0], long: number = this.originCoord[1]): VO {
|
||||
return new MapVertex(key, value, lat, long) as VO;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ export class UndirectedVertex<V = any> extends AbstractVertex<V> {
|
|||
}
|
||||
|
||||
export class UndirectedEdge<E = number> extends AbstractEdge<E> {
|
||||
vertices: [VertexKey, VertexKey];
|
||||
vertexMap: [VertexKey, VertexKey];
|
||||
|
||||
/**
|
||||
* The constructor function creates an instance of a class with two vertex IDs, an optional weight, and an optional
|
||||
|
@ -38,7 +38,7 @@ export class UndirectedEdge<E = number> extends AbstractEdge<E> {
|
|||
*/
|
||||
constructor(v1: VertexKey, v2: VertexKey, weight?: number, value?: E) {
|
||||
super(weight, value);
|
||||
this.vertices = [v1, v2];
|
||||
this.vertexMap = [v1, v2];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,17 +51,17 @@ export class UndirectedGraph<
|
|||
extends AbstractGraph<V, E, VO, EO>
|
||||
implements IGraph<V, E, VO, EO> {
|
||||
/**
|
||||
* The constructor initializes a new Map object to store edges.
|
||||
* The constructor initializes a new Map object to store edgeMap.
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
this._edges = new Map<VO, EO[]>();
|
||||
this._edgeMap = new Map<VO, EO[]>();
|
||||
}
|
||||
|
||||
protected _edges: Map<VO, EO[]>;
|
||||
protected _edgeMap: Map<VO, EO[]>;
|
||||
|
||||
get edges(): Map<VO, EO[]> {
|
||||
return this._edges;
|
||||
get edgeMap(): Map<VO, EO[]> {
|
||||
return this._edgeMap;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -78,7 +78,7 @@ export class UndirectedGraph<
|
|||
}
|
||||
|
||||
/**
|
||||
* The function creates an undirected edge between two vertices with an optional weight and value.
|
||||
* The function creates an undirected edge between two vertexMap with an optional weight and value.
|
||||
* @param {VertexKey} v1 - The parameter `v1` represents the first vertex of the edge.
|
||||
* @param {VertexKey} v2 - The parameter `v2` represents the second vertex of the edge.
|
||||
* @param {number} [weight] - The `weight` parameter is an optional number that represents the weight of the edge. If
|
||||
|
@ -92,15 +92,15 @@ export class UndirectedGraph<
|
|||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(|E|), where |E| is the number of edges incident to the given vertex.
|
||||
* Time Complexity: O(|E|), where |E| is the number of edgeMap incident to the given vertex.
|
||||
* Space Complexity: O(1)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time Complexity: O(|E|), where |E| is the number of edges incident to the given vertex.
|
||||
* Time Complexity: O(|E|), where |E| is the number of edgeMap incident to the given vertex.
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The function `getEdge` returns the first edge that connects two vertices, or undefined if no such edge exists.
|
||||
* The function `getEdge` returns the first edge that connects two vertexMap, 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
|
||||
|
@ -108,34 +108,34 @@ export class UndirectedGraph<
|
|||
* @returns an edge (EO) or undefined.
|
||||
*/
|
||||
getEdge(v1: VO | VertexKey | undefined, v2: VO | VertexKey | undefined): EO | undefined {
|
||||
let edges: EO[] | undefined = [];
|
||||
let edgeMap: EO[] | undefined = [];
|
||||
|
||||
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));
|
||||
edgeMap = this._edgeMap.get(vertex1)?.filter(e => e.vertexMap.includes(vertex2.key));
|
||||
}
|
||||
}
|
||||
|
||||
return edges ? edges[0] || undefined : undefined;
|
||||
return edgeMap ? edgeMap[0] || undefined : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(|E|), where |E| is the number of edges incident to the given vertex.
|
||||
* Time Complexity: O(|E|), where |E| is the number of edgeMap incident to the given vertex.
|
||||
* Space Complexity: O(1)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time Complexity: O(|E|), where |E| is the number of edges incident to the given vertex.
|
||||
* Time Complexity: O(|E|), where |E| is the number of edgeMap incident to the given vertex.
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The function removes an edge between two vertices in a graph and returns the removed edge.
|
||||
* The function removes an edge between two vertexMap in a graph and returns the removed edge.
|
||||
* @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 undefined if either of the vertices (VO) does not exist.
|
||||
* @returns the removed edge (EO) if it exists, or undefined if either of the vertexMap (VO) does not exist.
|
||||
*/
|
||||
deleteEdgeBetween(v1: VO | VertexKey, v2: VO | VertexKey): EO | undefined {
|
||||
const vertex1: VO | undefined = this._getVertex(v1);
|
||||
|
@ -145,29 +145,29 @@ export class UndirectedGraph<
|
|||
return undefined;
|
||||
}
|
||||
|
||||
const v1Edges = this._edges.get(vertex1);
|
||||
const v1Edges = this._edgeMap.get(vertex1);
|
||||
let removed: EO | undefined = undefined;
|
||||
if (v1Edges) {
|
||||
removed = arrayRemove<EO>(v1Edges, (e: EO) => e.vertices.includes(vertex2.key))[0] || undefined;
|
||||
removed = arrayRemove<EO>(v1Edges, (e: EO) => e.vertexMap.includes(vertex2.key))[0] || undefined;
|
||||
}
|
||||
const v2Edges = this._edges.get(vertex2);
|
||||
const v2Edges = this._edgeMap.get(vertex2);
|
||||
if (v2Edges) {
|
||||
arrayRemove<EO>(v2Edges, (e: EO) => e.vertices.includes(vertex1.key));
|
||||
arrayRemove<EO>(v2Edges, (e: EO) => e.vertexMap.includes(vertex1.key));
|
||||
}
|
||||
return removed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(E), where E is the number of edges incident to the given vertex.
|
||||
* Time Complexity: O(E), where E is the number of edgeMap incident to the given vertex.
|
||||
* Space Complexity: O(1)
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Time Complexity: O(E), where E is the number of edges incident to the given vertex.
|
||||
* Time Complexity: O(E), where E is the number of edgeMap incident to the given vertex.
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The function `deleteEdge` deletes an edge between two vertices in a graph.
|
||||
* The function `deleteEdge` deletes an edge between two vertexMap in a graph.
|
||||
* @param {EO | VertexKey} edgeOrOneSideVertexKey - The parameter `edgeOrOneSideVertexKey` can be
|
||||
* either an edge object or a vertex key.
|
||||
* @param {VertexKey} [otherSideVertexKey] - The parameter `otherSideVertexKey` is an optional
|
||||
|
@ -186,8 +186,8 @@ export class UndirectedGraph<
|
|||
return;
|
||||
}
|
||||
} else {
|
||||
oneSide = this._getVertex(edgeOrOneSideVertexKey.vertices[0]);
|
||||
otherSide = this._getVertex(edgeOrOneSideVertexKey.vertices[1]);
|
||||
oneSide = this._getVertex(edgeOrOneSideVertexKey.vertexMap[0]);
|
||||
otherSide = this._getVertex(edgeOrOneSideVertexKey.vertexMap[1]);
|
||||
}
|
||||
|
||||
if (oneSide && otherSide) {
|
||||
|
@ -227,19 +227,19 @@ export class UndirectedGraph<
|
|||
|
||||
if (vertex) {
|
||||
neighbors.forEach(neighbor => {
|
||||
const neighborEdges = this._edges.get(neighbor);
|
||||
const neighborEdges = this._edgeMap.get(neighbor);
|
||||
if (neighborEdges) {
|
||||
const restEdges = neighborEdges.filter(edge => {
|
||||
return !edge.vertices.includes(vertexKey);
|
||||
return !edge.vertexMap.includes(vertexKey);
|
||||
});
|
||||
this._edges.set(neighbor, restEdges);
|
||||
this._edgeMap.set(neighbor, restEdges);
|
||||
}
|
||||
})
|
||||
this._edges.delete(vertex);
|
||||
this._edgeMap.delete(vertex);
|
||||
|
||||
}
|
||||
|
||||
return this._vertices.delete(vertexKey);
|
||||
return this._vertexMap.delete(vertexKey);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -251,16 +251,16 @@ export class UndirectedGraph<
|
|||
* Time Complexity: O(1)
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The function `degreeOf` returns the degree of a vertex in a graph, which is the number of edges connected to that
|
||||
* The function `degreeOf` returns the degree of a vertex in a graph, which is the number of edgeMap connected to that
|
||||
* vertex.
|
||||
* @param {VertexKey | VO} vertexOrKey - The parameter `vertexOrKey` can be either a `VertexKey` or a `VO`.
|
||||
* @returns The function `degreeOf` returns the degree of a vertex in a graph. The degree of a vertex is the number of
|
||||
* edges connected to that vertex.
|
||||
* edgeMap connected to that vertex.
|
||||
*/
|
||||
degreeOf(vertexOrKey: VertexKey | VO): number {
|
||||
const vertex = this._getVertex(vertexOrKey);
|
||||
if (vertex) {
|
||||
return this._edges.get(vertex)?.length || 0;
|
||||
return this._edgeMap.get(vertex)?.length || 0;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
@ -275,36 +275,36 @@ export class UndirectedGraph<
|
|||
* Time Complexity: O(1)
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The function returns the edges of a given vertex or vertex ID.
|
||||
* The function returns the edgeMap of a given vertex or vertex ID.
|
||||
* @param {VertexKey | VO} vertexOrKey - The parameter `vertexOrKey` can be either a `VertexKey` or a `VO`. A `VertexKey` is a
|
||||
* unique identifier for a vertex in a graph, while `VO` represents the type of the vertex.
|
||||
* @returns an array of edges.
|
||||
* @returns an array of edgeMap.
|
||||
*/
|
||||
edgesOf(vertexOrKey: VertexKey | VO): EO[] {
|
||||
const vertex = this._getVertex(vertexOrKey);
|
||||
if (vertex) {
|
||||
return this._edges.get(vertex) || [];
|
||||
return this._edgeMap.get(vertex) || [];
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(|V| + |E|), where |V| is the number of vertices and |E| is the number of edges.
|
||||
* Time Complexity: O(|V| + |E|), where |V| is the number of vertexMap and |E| is the number of edgeMap.
|
||||
* Space Complexity: O(|E|)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time Complexity: O(|V| + |E|), where |V| is the number of vertices and |E| is the number of edges.
|
||||
* Time Complexity: O(|V| + |E|), where |V| is the number of vertexMap and |E| is the number of edgeMap.
|
||||
* Space Complexity: O(|E|)
|
||||
*
|
||||
* The function "edgeSet" returns an array of unique edges from a set of edges.
|
||||
* The function "edgeSet" returns an array of unique edgeMap from a set of edgeMap.
|
||||
* @returns The method `edgeSet()` returns an array of type `EO[]`.
|
||||
*/
|
||||
edgeSet(): EO[] {
|
||||
const edgeSet: Set<EO> = new Set();
|
||||
this._edges.forEach(edges => {
|
||||
edges.forEach(edge => {
|
||||
this._edgeMap.forEach(edgeMap => {
|
||||
edgeMap.forEach(edge => {
|
||||
edgeSet.add(edge);
|
||||
});
|
||||
});
|
||||
|
@ -312,18 +312,18 @@ export class UndirectedGraph<
|
|||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(|V| + |E|), where |V| is the number of vertices and |E| is the number of edges.
|
||||
* Time Complexity: O(|V| + |E|), where |V| is the number of vertexMap and |E| is the number of edgeMap.
|
||||
* Space Complexity: O(|E|)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time Complexity: O(|V| + |E|), where |V| is the number of vertices and |E| is the number of edges.
|
||||
* Time Complexity: O(|V| + |E|), where |V| is the number of vertexMap and |E| is the number of edgeMap.
|
||||
* Space Complexity: O(|E|)
|
||||
*
|
||||
* The function "getNeighbors" returns an array of neighboring vertices for a given vertex or vertex ID.
|
||||
* The function "getNeighbors" returns an array of neighboring vertexMap for a given vertex or vertex ID.
|
||||
* @param {VO | VertexKey} vertexOrKey - The parameter `vertexOrKey` can be either a vertex object (`VO`) or a vertex ID
|
||||
* (`VertexKey`).
|
||||
* @returns an array of vertices (VO[]).
|
||||
* @returns an array of vertexMap (VO[]).
|
||||
*/
|
||||
getNeighbors(vertexOrKey: VO | VertexKey): VO[] {
|
||||
const neighbors: VO[] = [];
|
||||
|
@ -331,7 +331,7 @@ export class UndirectedGraph<
|
|||
if (vertex) {
|
||||
const neighborEdges = this.edgesOf(vertex);
|
||||
for (const edge of neighborEdges) {
|
||||
const neighbor = this._getVertex(edge.vertices.filter(e => e !== vertex.key)[0]);
|
||||
const neighbor = this._getVertex(edge.vertexMap.filter(e => e !== vertex.key)[0]);
|
||||
if (neighbor) {
|
||||
neighbors.push(neighbor);
|
||||
}
|
||||
|
@ -349,18 +349,18 @@ export class UndirectedGraph<
|
|||
* Time Complexity: O(1)
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The function "getEndsOfEdge" returns the vertices at the ends of an edge if the edge exists in the graph, otherwise
|
||||
* The function "getEndsOfEdge" returns the vertexMap at the ends of an edge if the edge exists in the graph, 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
|
||||
* @returns The function `getEndsOfEdge` returns an array containing two vertexMap `[VO, VO]` if the edge exists in the
|
||||
* graph. If the edge does not exist, it returns `undefined`.
|
||||
*/
|
||||
getEndsOfEdge(edge: EO): [VO, VO] | undefined {
|
||||
if (!this.hasEdge(edge.vertices[0], edge.vertices[1])) {
|
||||
if (!this.hasEdge(edge.vertexMap[0], edge.vertexMap[1])) {
|
||||
return undefined;
|
||||
}
|
||||
const v1 = this._getVertex(edge.vertices[0]);
|
||||
const v2 = this._getVertex(edge.vertices[1]);
|
||||
const v1 = this._getVertex(edge.vertexMap[0]);
|
||||
const v2 = this._getVertex(edge.vertexMap[1]);
|
||||
if (v1 && v2) {
|
||||
return [v1, v2];
|
||||
} else {
|
||||
|
@ -377,20 +377,20 @@ export class UndirectedGraph<
|
|||
* Time Complexity: O(1)
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The function adds an edge to the graph by updating the adjacency list with the vertices of the edge.
|
||||
* The function adds an edge to the graph by updating the adjacency list with the vertexMap of the edge.
|
||||
* @param {EO} edge - The parameter "edge" is of type EO, which represents an edge in a graph.
|
||||
* @returns a boolean value.
|
||||
*/
|
||||
protected _addEdgeOnly(edge: EO): boolean {
|
||||
for (const end of edge.vertices) {
|
||||
for (const end of edge.vertexMap) {
|
||||
const endVertex = this._getVertex(end);
|
||||
if (endVertex === undefined) return false;
|
||||
if (endVertex) {
|
||||
const edges = this._edges.get(endVertex);
|
||||
if (edges) {
|
||||
edges.push(edge);
|
||||
const edgeMap = this._edgeMap.get(endVertex);
|
||||
if (edgeMap) {
|
||||
edgeMap.push(edge);
|
||||
} else {
|
||||
this._edges.set(endVertex, [edge]);
|
||||
this._edgeMap.set(endVertex, [edge]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ describe('DirectedGraph Operation Test', () => {
|
|||
graph = new DirectedGraph();
|
||||
});
|
||||
|
||||
it('should add vertices', () => {
|
||||
it('should add vertexMap', () => {
|
||||
const vertex1 = new DirectedVertex('A');
|
||||
const vertex2 = new DirectedVertex('B');
|
||||
|
||||
|
@ -155,7 +155,7 @@ describe('Inherit from DirectedGraph and perform operations', () => {
|
|||
myGraph = new MyDirectedGraph();
|
||||
});
|
||||
|
||||
it('Add vertices', () => {
|
||||
it('Add vertexMap', () => {
|
||||
myGraph.addVertex(1, 'data1');
|
||||
myGraph.addVertex(2, 'data2');
|
||||
myGraph.addVertex(3, 'data3');
|
||||
|
@ -204,7 +204,7 @@ describe('Inherit from DirectedGraph and perform operations', () => {
|
|||
expect(true).toBeTruthy();
|
||||
});
|
||||
|
||||
it('Remove edge between vertices', () => {
|
||||
it('Remove edge between vertexMap', () => {
|
||||
myGraph.addVertex(1, 'data1');
|
||||
myGraph.addVertex(2, 'data2');
|
||||
myGraph.addEdge(1, 2, 10, 'edge-data1-2');
|
||||
|
@ -232,14 +232,14 @@ describe('Inherit from DirectedGraph and perform operations', () => {
|
|||
}
|
||||
});
|
||||
|
||||
it('Minimum path between vertices', () => {
|
||||
it('Minimum path between vertexMap', () => {
|
||||
myGraph.addVertex(new MyVertex(1, 'data1'));
|
||||
myGraph.addVertex(new MyVertex(2, 'data2'));
|
||||
myGraph.addEdge(new MyEdge(1, 2, 10, 'edge-data1-2'));
|
||||
});
|
||||
|
||||
it('All paths between vertices', () => {
|
||||
// Add vertices and edges as needed for this test
|
||||
it('All paths between vertexMap', () => {
|
||||
// Add vertexMap and edges as needed for this test
|
||||
myGraph.addVertex(new MyVertex(1, 'data1'));
|
||||
myGraph.addVertex(new MyVertex(2, 'data2'));
|
||||
myGraph.addEdge(new MyEdge(1, 2, 10, 'edge-data1-2'));
|
||||
|
@ -598,41 +598,41 @@ describe('cycles, strongly connected components, bridges, articular points in Di
|
|||
|
||||
describe('DirectedGraph iterative Methods', () => {
|
||||
let graph: DirectedGraph<string>;
|
||||
let vertices: string[];
|
||||
let vertexMap: string[];
|
||||
|
||||
beforeEach(() => {
|
||||
graph = new DirectedGraph();
|
||||
vertices = ['A', 'B', 'C', 'D'];
|
||||
vertices.forEach(vertex => graph.addVertex(vertex));
|
||||
vertexMap = ['A', 'B', 'C', 'D'];
|
||||
vertexMap.forEach(vertex => graph.addVertex(vertex));
|
||||
});
|
||||
|
||||
test('[Symbol.iterator] should iterate over all vertices', () => {
|
||||
test('[Symbol.iterator] should iterate over all vertexMap', () => {
|
||||
const iteratedVertices = [];
|
||||
for (const vertex of graph) {
|
||||
iteratedVertices.push(vertex[0]);
|
||||
}
|
||||
expect(iteratedVertices).toEqual(vertices);
|
||||
expect(iteratedVertices).toEqual(vertexMap);
|
||||
});
|
||||
|
||||
test('forEach should apply a function to each vertex', () => {
|
||||
const result: VertexKey[] = [];
|
||||
graph.forEach((value, key) => key && result.push(key));
|
||||
expect(result).toEqual(vertices);
|
||||
expect(result).toEqual(vertexMap);
|
||||
});
|
||||
|
||||
test('filter should return vertices that satisfy the condition', () => {
|
||||
test('filter should return vertexMap that satisfy the condition', () => {
|
||||
const filtered = graph.filter((value, vertex) => vertex === 'A' || vertex === 'B');
|
||||
expect(filtered).toEqual([["A", undefined], ["B", undefined]]);
|
||||
});
|
||||
|
||||
test('map should apply a function to each vertex and return a new array', () => {
|
||||
const mapped = graph.map((value, vertex) => vertex + '_mapped');
|
||||
expect(mapped).toEqual(vertices.map(v => v + '_mapped'));
|
||||
expect(mapped).toEqual(vertexMap.map(v => v + '_mapped'));
|
||||
});
|
||||
|
||||
test('reduce should accumulate a value based on each vertex', () => {
|
||||
const concatenated = graph.reduce((acc, value, key) => acc + key, '');
|
||||
expect(concatenated).toBe(vertices.join(''));
|
||||
expect(concatenated).toBe(vertexMap.join(''));
|
||||
});
|
||||
|
||||
test('Removing an edge of a DirectedGraph should not delete additional edges', () => {
|
||||
|
|
|
@ -52,8 +52,8 @@ describe('MapGraph', () => {
|
|||
mapGraph = new MapGraph<string, string>([0, 0], [100, 100]);
|
||||
});
|
||||
|
||||
// Test adding vertices to the graph
|
||||
it('should add vertices to the graph', () => {
|
||||
// Test adding vertexMap to the graph
|
||||
it('should add vertexMap to the graph', () => {
|
||||
const locationA = new MapVertex('A', 'Location A', 10, 20);
|
||||
const locationB = new MapVertex('B', 'Location B', 30, 40);
|
||||
|
||||
|
@ -88,7 +88,7 @@ describe('MapGraph', () => {
|
|||
const edgeAB = new MapEdge('A', 'B', 50, 'Edge from A to B');
|
||||
const edgeBC = new MapEdge('B', 'C', 60, 'Edge from B to C');
|
||||
|
||||
expect(mapGraph.origin).toEqual([0, 0]);
|
||||
expect(mapGraph.originCoord).toEqual([0, 0]);
|
||||
expect(mapGraph.bottomRight).toEqual([100, 100]);
|
||||
|
||||
mapGraph.addVertex(locationA);
|
||||
|
|
|
@ -17,7 +17,7 @@ describe('UndirectedGraph Operation Test', () => {
|
|||
expect(graph.getEndsOfEdge(new UndirectedEdge('c', 'd'))).toBe(undefined);
|
||||
});
|
||||
|
||||
it('should add vertices', () => {
|
||||
it('should add vertexMap', () => {
|
||||
const vertex1 = new UndirectedVertex('A');
|
||||
const vertex2 = new UndirectedVertex('B');
|
||||
|
||||
|
@ -76,8 +76,8 @@ describe('UndirectedGraph', () => {
|
|||
undirectedGraph = new UndirectedGraph<string, string>();
|
||||
});
|
||||
|
||||
// Test adding vertices to the graph
|
||||
it('should add vertices to the graph', () => {
|
||||
// Test adding vertexMap to the graph
|
||||
it('should add vertexMap to the graph', () => {
|
||||
const vertexA = new UndirectedVertex('A', 'Location A');
|
||||
const vertexB = new UndirectedVertex('B', 'Location B');
|
||||
|
||||
|
@ -130,8 +130,8 @@ describe('UndirectedGraph', () => {
|
|||
const edgeAB = new UndirectedEdge('A', 'B', 3, 'Edge between A and B');
|
||||
const edgeBC = new UndirectedEdge('B', 'C', 4, 'Edge between B and C');
|
||||
|
||||
edgeAB.vertices = edgeAB.vertices;
|
||||
expect(undirectedGraph.edges.size).toBe(0);
|
||||
edgeAB.vertexMap = edgeAB.vertexMap;
|
||||
expect(undirectedGraph.edgeMap.size).toBe(0);
|
||||
undirectedGraph.addVertex(vertexA);
|
||||
undirectedGraph.addVertex(vertexB);
|
||||
undirectedGraph.addVertex(vertexC);
|
||||
|
@ -181,10 +181,10 @@ describe('UndirectedGraph', () => {
|
|||
dg.addVertex('hey')
|
||||
dg.addEdge('hello', 'hi')
|
||||
dg.addEdge('hello', 'hey')
|
||||
expect(dg.getEdge('hello', 'hi')?.vertices[0]).toBe('hello')
|
||||
expect(dg.getEdge('hello', 'hi')?.vertices[1]).toBe('hi')
|
||||
expect(dg.getEdge('hello', 'hey')?.vertices[0]).toBe('hello')
|
||||
expect(dg.getEdge('hello', 'hey')?.vertices[1]).toBe('hey')
|
||||
expect(dg.getEdge('hello', 'hi')?.vertexMap[0]).toBe('hello')
|
||||
expect(dg.getEdge('hello', 'hi')?.vertexMap[1]).toBe('hi')
|
||||
expect(dg.getEdge('hello', 'hey')?.vertexMap[0]).toBe('hello')
|
||||
expect(dg.getEdge('hello', 'hey')?.vertexMap[1]).toBe('hey')
|
||||
dg.deleteEdge('hello', 'hi')
|
||||
expect(dg.getEdge('hello', 'hi')).toBe(undefined)
|
||||
expect(dg.getEdge('hello', 'hey')).toBeInstanceOf(UndirectedEdge)
|
||||
|
@ -200,13 +200,13 @@ describe('UndirectedGraph', () => {
|
|||
dg.addEdge('hello', 'earth')
|
||||
dg.addEdge('world', 'earth')
|
||||
|
||||
expect(dg.getEdge('hello', 'world')?.vertices[0]).toBe('hello');
|
||||
expect(dg.getEdge('hello', 'world')?.vertexMap[0]).toBe('hello');
|
||||
expect(dg.edgeSet().length).toBe(3)
|
||||
expect(dg.edgeSet()[0].vertices).toEqual(['hello', 'world'])
|
||||
expect(dg.edgeSet()[0].vertexMap).toEqual(['hello', 'world'])
|
||||
|
||||
dg.deleteVertex('hello')
|
||||
expect(dg.edgeSet().length).toBe(1)
|
||||
expect(dg.edgeSet()?.[0].vertices[0]).toBe('world')
|
||||
expect(dg.edgeSet()?.[0].vertexMap[0]).toBe('world')
|
||||
|
||||
expect(dg.getEdge('hello', 'world')).toBe(undefined);
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue