mirror of
https://github.com/zrwusa/data-structure-typed.git
synced 2024-11-23 12:54:04 +00:00
Modify all methods of BinaryTreeNode to make the val parameter optional.
This commit is contained in:
parent
0b330aeadd
commit
363c66490a
|
@ -31,7 +31,7 @@ export abstract class AbstractBinaryTreeNode<T = any, FAMILY extends AbstractBin
|
|||
* @param {number} [count] - The `count` parameter is an optional parameter that represents the number of times the
|
||||
* value `val` appears in the binary tree node. If the `count` parameter is not provided, it defaults to 1.
|
||||
*/
|
||||
constructor(val: T, id: BinaryTreeNodeId, count?: number) {
|
||||
constructor(id: BinaryTreeNodeId, val?: T, count?: number) {
|
||||
this._id = id;
|
||||
this._val = val;
|
||||
this._count = count ?? 1;
|
||||
|
@ -47,13 +47,13 @@ export abstract class AbstractBinaryTreeNode<T = any, FAMILY extends AbstractBin
|
|||
this._id = v;
|
||||
}
|
||||
|
||||
private _val: T;
|
||||
private _val: T | undefined;
|
||||
|
||||
get val(): T {
|
||||
get val(): T | undefined {
|
||||
return this._val;
|
||||
}
|
||||
|
||||
set val(value: T) {
|
||||
set val(value: T | undefined) {
|
||||
this._val = value;
|
||||
}
|
||||
|
||||
|
@ -141,7 +141,7 @@ export abstract class AbstractBinaryTreeNode<T = any, FAMILY extends AbstractBin
|
|||
}
|
||||
}
|
||||
|
||||
abstract createNode(val: T, id: BinaryTreeNodeId, count?: number): FAMILY
|
||||
abstract createNode(id: BinaryTreeNodeId, val?: T, count?: number): FAMILY
|
||||
|
||||
/**
|
||||
* The function swaps the location of two nodes in a binary tree.
|
||||
|
@ -150,7 +150,7 @@ export abstract class AbstractBinaryTreeNode<T = any, FAMILY extends AbstractBin
|
|||
*/
|
||||
swapLocation(destNode: FAMILY): FAMILY {
|
||||
const {val, count, height, id} = destNode;
|
||||
const tempNode = this.createNode(val, id, count);
|
||||
const tempNode = this.createNode(id, val, count);
|
||||
tempNode.height = height;
|
||||
|
||||
if (tempNode instanceof AbstractBinaryTreeNode) {
|
||||
|
@ -176,7 +176,7 @@ export abstract class AbstractBinaryTreeNode<T = any, FAMILY extends AbstractBin
|
|||
* `count` values as the current instance.
|
||||
*/
|
||||
clone(): FAMILY | null {
|
||||
return this.createNode(this.val, this.id, this.count);
|
||||
return this.createNode(this.id, this.val, this.count);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -271,7 +271,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
|
|||
return this._count;
|
||||
}
|
||||
|
||||
abstract createNode(val: N['val'], id: BinaryTreeNodeId, count?: number): N | null ;
|
||||
abstract createNode(id: BinaryTreeNodeId, val?: N['val'], count?: number): N | null ;
|
||||
|
||||
/**
|
||||
* The clear function resets the state of an object by setting its properties to their initial values.
|
||||
|
@ -302,7 +302,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
|
|||
* @returns The function `add` returns a `N` object if a new node is inserted, or `null` if no new node
|
||||
* is inserted, or `undefined` if the insertion fails.
|
||||
*/
|
||||
add(val: N['val'], id: BinaryTreeNodeId, count?: number): N | null | undefined {
|
||||
add(id: BinaryTreeNodeId, val?: N['val'], count?: number): N | null | undefined {
|
||||
count = count ?? 1;
|
||||
|
||||
const _bfs = (root: N, newNode: N | null): N | undefined | null => {
|
||||
|
@ -320,7 +320,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
|
|||
};
|
||||
|
||||
let inserted: N | null | undefined;
|
||||
const needInsert = val !== null ? this.createNode(val, id, count) : null;
|
||||
const needInsert = val !== null ? this.createNode(id, val, count) : null;
|
||||
const existNode = val !== null ? this.get(id, 'id') : null;
|
||||
if (this.root) {
|
||||
if (existNode) {
|
||||
|
@ -334,7 +334,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
|
|||
inserted = _bfs(this.root, needInsert);
|
||||
}
|
||||
} else {
|
||||
this._setRoot(val !== null ? this.createNode(val, id, count) : null);
|
||||
this._setRoot(val !== null ? this.createNode(id, val, count) : null);
|
||||
if (needInsert !== null) {
|
||||
this._setSize(1);
|
||||
this._setCount(count);
|
||||
|
@ -397,50 +397,50 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
|
|||
const map: Map<N | N['val'], number> = new Map();
|
||||
|
||||
if (this.isMergeDuplicatedVal) {
|
||||
for (const nodeOrVal of data) map.set(nodeOrVal, (map.get(nodeOrVal) ?? 0) + 1);
|
||||
for (const nodeOrId of data) map.set(nodeOrId, (map.get(nodeOrId) ?? 0) + 1);
|
||||
}
|
||||
|
||||
for (const nodeOrVal of data) {
|
||||
for (const nodeOrId of data) {
|
||||
|
||||
if (nodeOrVal instanceof AbstractBinaryTreeNode) {
|
||||
inserted.push(this.add(nodeOrVal.val, nodeOrVal.id, nodeOrVal.count));
|
||||
if (nodeOrId instanceof AbstractBinaryTreeNode) {
|
||||
inserted.push(this.add(nodeOrId.id, nodeOrId.val, nodeOrId.count));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nodeOrVal === null) {
|
||||
inserted.push(this.add(null, NaN, 0));
|
||||
if (nodeOrId === null) {
|
||||
inserted.push(this.add(NaN, null, 0));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// TODO will this cause an issue?
|
||||
const count = this.isMergeDuplicatedVal ? map.get(nodeOrVal) : 1;
|
||||
const count = this.isMergeDuplicatedVal ? map.get(nodeOrId) : 1;
|
||||
let newId: BinaryTreeNodeId;
|
||||
if (typeof nodeOrVal === 'number') {
|
||||
newId = this.autoIncrementId ? this.maxId + 1 : nodeOrVal;
|
||||
} else if (nodeOrVal instanceof Object) {
|
||||
if (typeof nodeOrId === 'number') {
|
||||
newId = this.autoIncrementId ? this.maxId + 1 : nodeOrId;
|
||||
} else if (nodeOrId instanceof Object) {
|
||||
if (this.autoIncrementId) {
|
||||
newId = this.maxId + 1;
|
||||
} else {
|
||||
if (Object.keys(nodeOrVal).includes('id')) {
|
||||
newId = (nodeOrVal as ObjectWithNumberId).id;
|
||||
if (Object.keys(nodeOrId).includes('id')) {
|
||||
newId = (nodeOrId as ObjectWithNumberId).id;
|
||||
} else {
|
||||
console.warn(nodeOrVal, 'Object value must has an id property when the autoIncrementId is false');
|
||||
console.warn(nodeOrId, 'Object value must has an id property when the autoIncrementId is false');
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.warn(nodeOrVal, ` is not added`);
|
||||
console.warn(nodeOrId, ` is not added`);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (this.isMergeDuplicatedVal) {
|
||||
if (map.has(nodeOrVal)) {
|
||||
inserted.push(this.add(nodeOrVal, newId, count));
|
||||
map.delete(nodeOrVal);
|
||||
if (map.has(nodeOrId)) {
|
||||
inserted.push(this.add(newId, nodeOrId, count));
|
||||
map.delete(nodeOrId);
|
||||
}
|
||||
} else {
|
||||
inserted.push(this.add(nodeOrVal, newId, 1));
|
||||
inserted.push(this.add(newId, nodeOrId, 1));
|
||||
}
|
||||
|
||||
this._setMaxId(newId);
|
||||
|
|
|
@ -10,8 +10,8 @@ import type {AVLTreeNodeNested, AVLTreeOptions, BinaryTreeDeletedResult, BinaryT
|
|||
import {IAVLTree, IAVLTreeNode} from '../interfaces';
|
||||
|
||||
export class AVLTreeNode<T = any, FAMILY extends AVLTreeNode<T, FAMILY> = AVLTreeNodeNested<T>> extends BSTNode<T, FAMILY> implements IAVLTreeNode<T, FAMILY> {
|
||||
override createNode(val: T, id: BinaryTreeNodeId, count?: number): FAMILY {
|
||||
return new AVLTreeNode(val, id, count) as FAMILY;
|
||||
override createNode(id: BinaryTreeNodeId, val?: T, count?: number): FAMILY {
|
||||
return new AVLTreeNode(id, val, count) as FAMILY;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,8 +20,8 @@ export class AVLTree<N extends AVLTreeNode<N['val'], N> = AVLTreeNode> extends B
|
|||
super(options);
|
||||
}
|
||||
|
||||
override createNode(val: N['val'], id: BinaryTreeNodeId, count?: number): N {
|
||||
return new AVLTreeNode<N['val'], N>(val, id, count) as N;
|
||||
override createNode(id: BinaryTreeNodeId, val?: N['val'], count?: number): N {
|
||||
return new AVLTreeNode<N['val'], N>(id, val, count) as N;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -36,8 +36,8 @@ export class AVLTree<N extends AVLTreeNode<N['val'], N> = AVLTreeNode> extends B
|
|||
* to `1`, indicating that the value should be inserted once.
|
||||
* @returns The method is returning either an N object or null.
|
||||
*/
|
||||
override add(val: N['val'], id: BinaryTreeNodeId, count?: number): N | null {
|
||||
const inserted = super.add(val, id, count);
|
||||
override add(id: BinaryTreeNodeId, val?: N['val'], count?: number): N | null {
|
||||
const inserted = super.add(id, val, count);
|
||||
if (inserted) this.balancePath(inserted);
|
||||
return inserted;
|
||||
}
|
||||
|
|
|
@ -23,8 +23,8 @@ export class BinaryTreeNode<T = any, FAMILY extends BinaryTreeNode<T, FAMILY> =
|
|||
* appears in the binary tree node.
|
||||
* @returns a new instance of the BinaryTreeNode class, casted as the FAMILY type.
|
||||
*/
|
||||
createNode(val: T, id: BinaryTreeNodeId, count?: number): FAMILY {
|
||||
return new BinaryTreeNode<T, FAMILY>(val, id, count) as FAMILY;
|
||||
createNode(id: BinaryTreeNodeId, val?: T, count?: number): FAMILY {
|
||||
return new BinaryTreeNode<T, FAMILY>(id, val, count) as FAMILY;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -52,8 +52,8 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
|
|||
* of occurrences of the value in the binary tree node. If not provided, the default value is `undefined`.
|
||||
* @returns a BinaryTreeNode object if the value is not null, otherwise it returns null.
|
||||
*/
|
||||
createNode(val: N['val'], id: BinaryTreeNodeId, count?: number): N {
|
||||
return new BinaryTreeNode<N['val'], N>(val, id, count) as N;
|
||||
createNode(id: BinaryTreeNodeId, val?: N['val'], count?: number): N {
|
||||
return new BinaryTreeNode<N['val'], N>(id, val, count) as N;
|
||||
}
|
||||
|
||||
}
|
|
@ -21,8 +21,8 @@ export class BSTNode<T = any, FAMILY extends BSTNode<T, FAMILY> = BSTNodeNested<
|
|||
* search tree node. It is an optional parameter, so it can be omitted when calling the `createNode` method.
|
||||
* @returns The method is returning a new instance of the BSTNode class, casted as the FAMILY type.
|
||||
*/
|
||||
override createNode(val: T, id: BinaryTreeNodeId, count?: number): FAMILY {
|
||||
return new BSTNode<T, FAMILY>(val, id, count) as FAMILY;
|
||||
override createNode(id: BinaryTreeNodeId, val?: T, count?: number): FAMILY {
|
||||
return new BSTNode<T, FAMILY>(id, val, count) as FAMILY;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,8 +51,8 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
|
|||
* of a particular value in the binary search tree node.
|
||||
* @returns a new instance of the BSTNode class, casted as type N.
|
||||
*/
|
||||
override createNode(val: N['val'], id: BinaryTreeNodeId, count?: number): N {
|
||||
return new BSTNode<N['val'], N>(val, id, count) as N;
|
||||
override createNode(id: BinaryTreeNodeId, val?: N['val'], count?: number): N {
|
||||
return new BSTNode<N['val'], N>(id, val, count) as N;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -67,9 +67,9 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
|
|||
* inserted once.
|
||||
* @returns The method `add` returns a `N` object or `null`.
|
||||
*/
|
||||
override add(val: N['val'], id: BinaryTreeNodeId, count: number = 1): N | null {
|
||||
override add(id: BinaryTreeNodeId, val?: N['val'], count: number = 1): N | null {
|
||||
let inserted: N | null = null;
|
||||
const newNode = this.createNode(val, id, count);
|
||||
const newNode = this.createNode(id, val, count);
|
||||
if (this.root === null) {
|
||||
this._setRoot(newNode);
|
||||
this._setSize(this.size + 1);
|
||||
|
@ -364,7 +364,7 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
|
|||
if (l > r) return;
|
||||
const m = l + Math.floor((r - l) / 2);
|
||||
const midNode = sorted[m];
|
||||
this.add(midNode.val, midNode.id, midNode.count);
|
||||
this.add(midNode.id, midNode.val, midNode.count);
|
||||
buildBalanceBST(l, m - 1);
|
||||
buildBalanceBST(m + 1, r);
|
||||
};
|
||||
|
@ -380,7 +380,7 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
|
|||
if (l <= r) {
|
||||
const m = l + Math.floor((r - l) / 2);
|
||||
const midNode = sorted[m];
|
||||
this.add(midNode.val, midNode.id, midNode.count);
|
||||
this.add(midNode.id, midNode.val, midNode.count);
|
||||
stack.push([m + 1, r]);
|
||||
stack.push([l, m - 1]);
|
||||
}
|
||||
|
|
|
@ -4,8 +4,8 @@ import {BST, BSTNode} from './bst';
|
|||
|
||||
|
||||
export class RBTreeNode<T = any, FAMILY extends RBTreeNode<T, FAMILY> = RBTreeNodeNested<T>> extends BSTNode<T, FAMILY> implements IRBTreeNode<T, FAMILY> {
|
||||
constructor(val: T, id: BinaryTreeNodeId, count?: number) {
|
||||
super(val, id, count);
|
||||
constructor(id: BinaryTreeNodeId, val?: T, count?: number) {
|
||||
super(id, val, count);
|
||||
}
|
||||
|
||||
private _color: RBColor = RBColor.RED;
|
||||
|
@ -28,8 +28,8 @@ export class RBTreeNode<T = any, FAMILY extends RBTreeNode<T, FAMILY> = RBTreeNo
|
|||
* node.
|
||||
* @returns The method is returning a new instance of the RBTreeNode class, casted as a FAMILY type.
|
||||
*/
|
||||
override createNode(val: T, id: BinaryTreeNodeId, count?: number): FAMILY {
|
||||
return new RBTreeNode(val, id, count) as FAMILY;
|
||||
override createNode(id: BinaryTreeNodeId, val?: T, count?: number): FAMILY {
|
||||
return new RBTreeNode(id, val, count) as FAMILY;
|
||||
}
|
||||
|
||||
// private override _parent: RBNode<T> | null;
|
||||
|
@ -71,8 +71,8 @@ export class RBTree<N extends RBTreeNode<N['val'], N> = RBTreeNode> extends BST<
|
|||
super(options);
|
||||
}
|
||||
|
||||
override createNode(val: N['val'], id: BinaryTreeNodeId, count?: number): N {
|
||||
return new RBTreeNode(val, id, count) as N;
|
||||
override createNode(id: BinaryTreeNodeId, val?: N['val'], count?: number): N {
|
||||
return new RBTreeNode(id, val, count) as N;
|
||||
}
|
||||
|
||||
// private override _root: BinaryTreeNode<N> | null = null;
|
||||
|
@ -81,7 +81,7 @@ export class RBTree<N extends RBTreeNode<N['val'], N> = RBTreeNode> extends BST<
|
|||
// return this._root;
|
||||
// }
|
||||
|
||||
insert(id: number, val: N | null) {
|
||||
insert(id: number, val?: N | null) {
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -20,8 +20,8 @@ export class TreeMultiSetNode<T = any, FAMILY extends TreeMultiSetNode<T, FAMILY
|
|||
* node. It is an optional parameter, so it can be omitted when calling the `createNode` method.
|
||||
* @returns The method is returning a new instance of the TreeMultiSetNode class, casted as the FAMILY type.
|
||||
*/
|
||||
override createNode(val: T, id: BinaryTreeNodeId, count?: number): FAMILY {
|
||||
return new TreeMultiSetNode(val, id, count) as FAMILY;
|
||||
override createNode(id: BinaryTreeNodeId, val?: T, count?: number): FAMILY {
|
||||
return new TreeMultiSetNode(id, val, count) as FAMILY;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ export class TreeMultiSet<N extends TreeMultiSetNode<N['val'], N> = TreeMultiSet
|
|||
* occurrences of the value in the binary search tree node. If not provided, the count will default to 1.
|
||||
* @returns A new instance of the BSTNode class with the specified id, value, and count (if provided).
|
||||
*/
|
||||
override createNode(val: N['val'], id: BinaryTreeNodeId, count?: number): N {
|
||||
return new TreeMultiSetNode(val, id, count) as N;
|
||||
override createNode(id: BinaryTreeNodeId, val?: N['val'], count?: number): N {
|
||||
return new TreeMultiSetNode(id, val, count) as N;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -140,7 +140,7 @@ export abstract class AbstractGraph<V extends AbstractVertex<any>, E extends Abs
|
|||
abstract getEdge(srcOrId: V | VertexId, destOrId: V | VertexId): E | null;
|
||||
|
||||
addVertex(vertex: V): boolean
|
||||
addVertex(id: VertexId , val?: V['val']): boolean
|
||||
addVertex(id: VertexId, val?: V['val']): boolean
|
||||
addVertex(idOrVertex: VertexId | V, val?: V['val']): boolean {
|
||||
if (idOrVertex instanceof AbstractVertex) {
|
||||
return this._addVertexOnly(idOrVertex);
|
||||
|
@ -151,15 +151,6 @@ export abstract class AbstractGraph<V extends AbstractVertex<any>, E extends Abs
|
|||
}
|
||||
}
|
||||
|
||||
protected _addVertexOnly(newVertex: V): boolean {
|
||||
if (this.hasVertex(newVertex)) {
|
||||
return false;
|
||||
// throw (new Error('Duplicated vertex id is not allowed'));
|
||||
}
|
||||
this._vertices.set(newVertex.id, newVertex);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* The `removeVertex` function removes a vertex from a graph by its ID or by the vertex object itself.
|
||||
* @param {V | VertexId} vertexOrId - The parameter `vertexOrId` can be either a vertex object (`V`) or a vertex ID
|
||||
|
@ -207,7 +198,9 @@ export abstract class AbstractGraph<V extends AbstractVertex<any>, E extends Abs
|
|||
}
|
||||
|
||||
addEdge(edge: E): boolean
|
||||
|
||||
addEdge(src: V | VertexId, dest: V | VertexId, weight: number, val?: E['val']): boolean
|
||||
|
||||
addEdge(srcOrEdge: V | VertexId | E, dest?: V | VertexId, weight?: number, val?: E['val']): boolean {
|
||||
if (srcOrEdge instanceof AbstractEdge) {
|
||||
return this._addEdgeOnly(srcOrEdge);
|
||||
|
@ -224,8 +217,6 @@ export abstract class AbstractGraph<V extends AbstractVertex<any>, E extends Abs
|
|||
}
|
||||
}
|
||||
|
||||
protected abstract _addEdgeOnly(edge: E): boolean;
|
||||
|
||||
/**
|
||||
* The function sets the weight of an edge between two vertices in a graph.
|
||||
* @param {VertexId | V} srcOrId - The `srcOrId` parameter can be either a `VertexId` or a `V` object. It represents
|
||||
|
@ -786,12 +777,6 @@ export abstract class AbstractGraph<V extends AbstractVertex<any>, E extends Abs
|
|||
return {hasNegativeCycle, distMap, preMap, paths, min, minPath};
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* 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(V^3), where V is the number of nodes. For dense graphs, Floyd-Warshall might become slower.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Floyd algorithm time: O(V^3) space: O(V^2), not support graph with negative weight cycle
|
||||
* all pairs
|
||||
|
@ -963,6 +948,23 @@ export abstract class AbstractGraph<V extends AbstractVertex<any>, E extends Abs
|
|||
return {dfnMap, lowMap, bridges, articulationPoints, SCCs, cycles};
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* 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(V^3), where V is the number of nodes. For dense graphs, Floyd-Warshall might become slower.
|
||||
*/
|
||||
|
||||
protected _addVertexOnly(newVertex: V): boolean {
|
||||
if (this.hasVertex(newVertex)) {
|
||||
return false;
|
||||
// throw (new Error('Duplicated vertex id is not allowed'));
|
||||
}
|
||||
this._vertices.set(newVertex.id, newVertex);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected abstract _addEdgeOnly(edge: E): boolean;
|
||||
|
||||
/**
|
||||
* BellmanFord time:O(VE) space:O(V)
|
||||
* one to rest pairs
|
||||
|
|
|
@ -140,42 +140,6 @@ export class DirectedGraph<V extends DirectedVertex<any> = DirectedVertex, E ext
|
|||
return edges[0] || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The `_addEdgeOnly` function adds a directed edge to a graph if the source and destination vertices exist.
|
||||
* @param edge - The parameter `edge` is of type `E`, which represents a directed edge in a graph. It
|
||||
* contains two properties:
|
||||
* @returns The method `_addEdgeOnly` returns a boolean value. It returns `true` if the edge was successfully added to the
|
||||
* graph, and `false` if either the source or destination vertex of the edge is not present in the graph.
|
||||
*/
|
||||
protected _addEdgeOnly(edge: E): boolean {
|
||||
if (!(this.hasVertex(edge.src) && this.hasVertex(edge.dest))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const srcVertex = this._getVertex(edge.src);
|
||||
const destVertex = this._getVertex(edge.dest);
|
||||
|
||||
// TODO after no-non-null-assertion not ensure the logic
|
||||
if (srcVertex && destVertex) {
|
||||
const srcOutEdges = this._outEdgeMap.get(srcVertex);
|
||||
if (srcOutEdges) {
|
||||
srcOutEdges.push(edge);
|
||||
} else {
|
||||
this._outEdgeMap.set(srcVertex, [edge]);
|
||||
}
|
||||
|
||||
const destInEdges = this._inEdgeMap.get(destVertex);
|
||||
if (destInEdges) {
|
||||
destInEdges.push(edge);
|
||||
} else {
|
||||
this._inEdgeMap.set(destVertex, [edge]);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The `removeEdgeBetween` function removes an edge between two vertices in a directed graph and returns the removed
|
||||
* edge, or null if the edge was not found.
|
||||
|
@ -420,8 +384,6 @@ export class DirectedGraph<V extends DirectedVertex<any> = DirectedVertex, E ext
|
|||
return edges;
|
||||
}
|
||||
|
||||
/**--- start find cycles --- */
|
||||
|
||||
/**
|
||||
* The function `getNeighbors` returns an array of neighboring vertices of a given vertex in a directed graph.
|
||||
* @param {V | VertexId} vertexOrId - The parameter `vertexOrId` can be either a `V`
|
||||
|
@ -444,7 +406,7 @@ export class DirectedGraph<V extends DirectedVertex<any> = DirectedVertex, E ext
|
|||
return neighbors;
|
||||
}
|
||||
|
||||
/**--- end find cycles --- */
|
||||
/**--- start find cycles --- */
|
||||
|
||||
/**
|
||||
* The function "getEndsOfEdge" returns the source and destination vertices of a directed edge if it exists in the
|
||||
|
@ -466,6 +428,44 @@ export class DirectedGraph<V extends DirectedVertex<any> = DirectedVertex, E ext
|
|||
}
|
||||
}
|
||||
|
||||
/**--- end find cycles --- */
|
||||
|
||||
/**
|
||||
* The `_addEdgeOnly` function adds a directed edge to a graph if the source and destination vertices exist.
|
||||
* @param edge - The parameter `edge` is of type `E`, which represents a directed edge in a graph. It
|
||||
* contains two properties:
|
||||
* @returns The method `_addEdgeOnly` returns a boolean value. It returns `true` if the edge was successfully added to the
|
||||
* graph, and `false` if either the source or destination vertex of the edge is not present in the graph.
|
||||
*/
|
||||
protected _addEdgeOnly(edge: E): boolean {
|
||||
if (!(this.hasVertex(edge.src) && this.hasVertex(edge.dest))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const srcVertex = this._getVertex(edge.src);
|
||||
const destVertex = this._getVertex(edge.dest);
|
||||
|
||||
// TODO after no-non-null-assertion not ensure the logic
|
||||
if (srcVertex && destVertex) {
|
||||
const srcOutEdges = this._outEdgeMap.get(srcVertex);
|
||||
if (srcOutEdges) {
|
||||
srcOutEdges.push(edge);
|
||||
} else {
|
||||
this._outEdgeMap.set(srcVertex, [edge]);
|
||||
}
|
||||
|
||||
const destInEdges = this._inEdgeMap.get(destVertex);
|
||||
if (destInEdges) {
|
||||
destInEdges.push(edge);
|
||||
} else {
|
||||
this._inEdgeMap.set(destVertex, [edge]);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected _setOutEdgeMap(value: Map<V, E[]>) {
|
||||
this._outEdgeMap = value;
|
||||
}
|
||||
|
|
|
@ -114,28 +114,6 @@ export class UndirectedGraph<V extends UndirectedVertex<any> = UndirectedVertex,
|
|||
return edges ? edges[0] || null : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The function adds an undirected edge to a graph by updating the adjacency list.
|
||||
* @param edge - An object representing an undirected edge in a graph. It has a property called "vertices" which is an
|
||||
* array of two vertices connected by the edge.
|
||||
* @returns a boolean value.
|
||||
*/
|
||||
protected _addEdgeOnly(edge: E): boolean {
|
||||
for (const end of edge.vertices) {
|
||||
const endVertex = this._getVertex(end);
|
||||
if (endVertex === null) return false;
|
||||
if (endVertex) {
|
||||
const edges = this._edges.get(endVertex);
|
||||
if (edges) {
|
||||
edges.push(edge);
|
||||
} else {
|
||||
this._edges.set(endVertex, [edge]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* The function removes an edge between two vertices in an undirected graph.
|
||||
* @param {V | VertexId} v1 - The parameter `v1` represents either an `V` object or
|
||||
|
@ -222,7 +200,6 @@ export class UndirectedGraph<V extends UndirectedVertex<any> = UndirectedVertex,
|
|||
return [...edgeSet];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The function `getNeighbors` returns an array of neighboring vertices of a given vertex in an undirected graph.
|
||||
* @param {V | VertexId} vertexOrId - The `vertexOrId` parameter can be either an
|
||||
|
@ -265,6 +242,28 @@ export class UndirectedGraph<V extends UndirectedVertex<any> = UndirectedVertex,
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The function adds an undirected edge to a graph by updating the adjacency list.
|
||||
* @param edge - An object representing an undirected edge in a graph. It has a property called "vertices" which is an
|
||||
* array of two vertices connected by the edge.
|
||||
* @returns a boolean value.
|
||||
*/
|
||||
protected _addEdgeOnly(edge: E): boolean {
|
||||
for (const end of edge.vertices) {
|
||||
const endVertex = this._getVertex(end);
|
||||
if (endVertex === null) return false;
|
||||
if (endVertex) {
|
||||
const edges = this._edges.get(endVertex);
|
||||
if (edges) {
|
||||
edges.push(edge);
|
||||
} else {
|
||||
this._edges.set(endVertex, [edge]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected _setEdges(v: Map<V, E[]>) {
|
||||
this._edges = v;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ import {AbstractBinaryTreeNode} from '../binary-tree';
|
|||
|
||||
export interface IAbstractBinaryTreeNode<T, FAMILY extends IAbstractBinaryTreeNode<T, FAMILY>> {
|
||||
|
||||
createNode(val: T, id: BinaryTreeNodeId, count?: number): FAMILY;
|
||||
createNode(id: BinaryTreeNodeId, val?: T, count?: number): FAMILY;
|
||||
|
||||
get id(): BinaryTreeNodeId
|
||||
|
||||
|
@ -51,7 +51,7 @@ export interface IAbstractBinaryTreeNode<T, FAMILY extends IAbstractBinaryTreeNo
|
|||
}
|
||||
|
||||
export interface IAbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val'], N>> {
|
||||
createNode(val: N['val'], id: BinaryTreeNodeId, count?: number): N | null
|
||||
createNode(id: BinaryTreeNodeId, val?: N['val'], count?: number): N | null
|
||||
|
||||
get loopType(): LoopType
|
||||
|
||||
|
@ -81,7 +81,7 @@ export interface IAbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val'],
|
|||
|
||||
isEmpty(): boolean
|
||||
|
||||
add(val: N['val'], id: BinaryTreeNodeId, count?: number): N | null | undefined
|
||||
add(id: BinaryTreeNodeId, val?: N['val'], count?: number): N | null | undefined
|
||||
|
||||
addTo(newNode: N | null, parent: N): N | null | undefined
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ export interface IAVLTreeNode<T, FAMILY extends IAVLTreeNode<T, FAMILY>> extends
|
|||
|
||||
export interface IAVLTree<N extends AVLTreeNode<N['val'], N>> extends IBST<N> {
|
||||
|
||||
add(id: BinaryTreeNodeId, val: N['val'] | null, count?: number): N | null
|
||||
add(id: BinaryTreeNodeId, val?: N['val'] | null, count?: number): N | null
|
||||
|
||||
remove(id: BinaryTreeNodeId, isUpdateAllLeftSum?: boolean): BinaryTreeDeletedResult<N>[]
|
||||
|
||||
|
|
|
@ -3,13 +3,13 @@ import {IBinaryTree, IBinaryTreeNode} from './binary-tree';
|
|||
import {BinaryTreeDeletedResult, BinaryTreeNodeId, BinaryTreeNodePropertyName} from '../types';
|
||||
|
||||
export interface IBSTNode<T, FAMILY extends IBSTNode<T, FAMILY>> extends IBinaryTreeNode<T, FAMILY> {
|
||||
createNode(val: T, id: BinaryTreeNodeId, count?: number): FAMILY
|
||||
createNode(id: BinaryTreeNodeId, val?: T, count?: number): FAMILY
|
||||
}
|
||||
|
||||
export interface IBST<N extends BSTNode<N['val'], N>> extends IBinaryTree<N> {
|
||||
createNode(val: N['val'], id: BinaryTreeNodeId, count?: number): N
|
||||
createNode(id: BinaryTreeNodeId, val?: N['val'], count?: number): N
|
||||
|
||||
add(id: BinaryTreeNodeId, val: N['val'] | null, count: number): N | null
|
||||
add(id: BinaryTreeNodeId, val?: N['val'] | null, count?: number): N | null
|
||||
|
||||
get(nodeProperty: BinaryTreeNodeId | N, propertyName ?: BinaryTreeNodePropertyName): N | null
|
||||
|
||||
|
|
|
@ -3,10 +3,10 @@ import {IBST, IBSTNode} from './bst';
|
|||
import {BinaryTreeNodeId} from '../types';
|
||||
|
||||
export interface IRBTreeNode<T, FAMILY extends IRBTreeNode<T, FAMILY>> extends IBSTNode<T, FAMILY> {
|
||||
createNode(val: T, id: BinaryTreeNodeId, count?: number): FAMILY
|
||||
createNode(id: BinaryTreeNodeId, val?: T, count?: number): FAMILY
|
||||
}
|
||||
|
||||
export interface IRBTree<N extends RBTreeNode<N['val'], N>> extends IBST<N> {
|
||||
|
||||
createNode(val: N['val'], id: BinaryTreeNodeId, count?: number): N
|
||||
createNode(id: BinaryTreeNodeId, val?: N['val'], count?: number): N
|
||||
}
|
Loading…
Reference in a new issue