Organized all the interfaces. Implemented the removeEdgeSrcToDest method for the Graph class.

This commit is contained in:
Revone 2023-08-23 23:03:19 +08:00
parent e70d988ac9
commit 6bc894c5c1
23 changed files with 847 additions and 522 deletions

694
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -62,6 +62,6 @@
"jest": "^29.6.2",
"ts-jest": "^29.1.1",
"typedoc": "^0.24.8",
"typescript": "^5.1.6"
"typescript": "^5.1.5"
}
}

View file

@ -9,8 +9,8 @@
import {trampoline} from '../../utils';
import type {
AbstractRecursiveBinaryTreeNode,
AbstractResultByProperty,
AbstractResultsByProperty,
AbstractBinaryTreeNodeProperty,
AbstractBinaryTreeNodeProperties,
BinaryTreeDeletedResult,
BinaryTreeNodeId,
BinaryTreeNodePropertyName,
@ -19,10 +19,9 @@ import type {
NodeOrPropertyName
} from '../types';
import {AbstractBinaryTreeOptions, FamilyPosition, LoopType} from '../types';
import {IBinaryTree, IBinaryTreeNode} from '../interfaces';
import {IAbstractBinaryTree, IAbstractBinaryTreeNode} from '../interfaces';
export abstract class AbstractBinaryTreeNode<T, FAMILY extends AbstractBinaryTreeNode<T, FAMILY> = AbstractRecursiveBinaryTreeNode<T>> implements IBinaryTreeNode<T, FAMILY> {
export abstract class AbstractBinaryTreeNode<T, FAMILY extends AbstractBinaryTreeNode<T, FAMILY> = AbstractRecursiveBinaryTreeNode<T>> implements IAbstractBinaryTreeNode<T, FAMILY> {
constructor(id: BinaryTreeNodeId, val: T, count?: number) {
this._id = id;
@ -118,11 +117,11 @@ export abstract class AbstractBinaryTreeNode<T, FAMILY extends AbstractBinaryTre
this._height = v;
}
abstract _createNode(id: BinaryTreeNodeId, val: T | null, count?: number): FAMILY | null
abstract createNode(id: BinaryTreeNodeId, val: T | null, count?: number): FAMILY | null
swapLocation(swapNode: FAMILY): FAMILY {
const {val, count, height} = swapNode;
const tempNode = this._createNode(swapNode.id, val);
const tempNode = this.createNode(swapNode.id, val);
if (tempNode instanceof AbstractBinaryTreeNode) {
tempNode.val = val;
tempNode.count = count;
@ -142,12 +141,11 @@ export abstract class AbstractBinaryTreeNode<T, FAMILY extends AbstractBinaryTre
}
clone(): FAMILY | null {
return this._createNode(this.id, this.val, this.count);
return this.createNode(this.id, this.val, this.count);
}
}
export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val'], N> = AbstractBinaryTreeNode<number>> implements IBinaryTree<N> {
export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val'], N> = AbstractBinaryTreeNode<number>> implements IAbstractBinaryTree<N> {
/**
* The protected constructor initializes the options for an abstract binary tree.
@ -238,7 +236,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
return this._count;
}
abstract _createNode(id: BinaryTreeNodeId, val: N['val'] | null, count?: number): N | null ;
abstract createNode(id: BinaryTreeNodeId, val: N['val'] | null, count?: number): N | null ;
/**
* The clear function resets the state of an object by setting its properties to their initial values.
@ -287,7 +285,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
};
let inserted: N | null | undefined;
const needInsert = val !== null ? this._createNode(id, val ?? id, count) : null;
const needInsert = val !== null ? this.createNode(id, val ?? id, count) : null;
const existNode = val !== null ? this.get(id, 'id') : null;
if (this.root) {
if (existNode) {
@ -301,7 +299,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
inserted = _bfs(this.root, needInsert);
}
} else {
this._setRoot(val !== null ? this._createNode(id, val ?? id, count) : null);
this._setRoot(val !== null ? this.createNode(id, val ?? id, count) : null);
if (needInsert !== null) {
this._setSize(1);
this._setCount(count);
@ -319,7 +317,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
* will be inserted as a child.
* @returns The method returns the newly inserted node, either as the left child or the right child of the parent node.
*/
addTo(newNode: N | null, parent: N) {
addTo(newNode: N | null, parent: N): N | null | undefined {
if (parent) {
if (parent.left === undefined) {
if (newNode) {
@ -608,11 +606,11 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
* function will stop traversing the tree and return the first matching node. If `
* @returns The function `getNodes` returns an array of `N | null | undefined` objects.
*/
getNodes(nodeProperty: BinaryTreeNodeId | N, propertyName ?: BinaryTreeNodePropertyName, onlyOne ?: boolean) {
if (!this.root) return [] as null[];
getNodes(nodeProperty: BinaryTreeNodeId | N, propertyName ?: BinaryTreeNodePropertyName, onlyOne ?: boolean): N[] {
if (!this.root) return [];
propertyName = propertyName ?? 'id';
const result: (N | null | undefined)[] = [];
const result: N[] = [];
if (this._loopType === LoopType.RECURSIVE) {
const _traverse = (cur: N) => {
@ -951,9 +949,9 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
* represents either a node or a property name. If a node is provided, the breadth-first search algorithm will be
* performed starting from that node. If a property name is provided, the breadth-first search algorithm will be
* performed starting from the root node
* @returns an object of type `AbstractResultsByProperty<N>`.
* @returns an object of type `AbstractBinaryTreeNodeProperties<N>`.
*/
BFS(nodeOrPropertyName ?: NodeOrPropertyName): AbstractResultsByProperty<N> {
BFS(nodeOrPropertyName ?: NodeOrPropertyName): AbstractBinaryTreeNodeProperties<N> {
nodeOrPropertyName = nodeOrPropertyName ?? 'id';
this._resetResults();
const queue: Array<N | null | undefined> = [this.root];
@ -990,9 +988,9 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
* either the name of a property in the `BinaryTreeNode` object or the value of the `id` property in the
* `BinaryTreeNode` object. This parameter is used to accumulate the results based on the specified property name. If
* no value
* @returns an object of type `AbstractResultsByProperty<N>`.
* @returns an object of type `AbstractBinaryTreeNodeProperties<N>`.
*/
DFS(pattern ?: 'in' | 'pre' | 'post', nodeOrPropertyName ?: NodeOrPropertyName): AbstractResultsByProperty<N> {
DFS(pattern ?: 'in' | 'pre' | 'post', nodeOrPropertyName ?: NodeOrPropertyName): AbstractBinaryTreeNodeProperties<N> {
pattern = pattern ?? 'in';
nodeOrPropertyName = nodeOrPropertyName ?? 'id';
this._resetResults();
@ -1037,7 +1035,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
* @param nodeOrPropertyName
* @constructor
*/
DFSIterative(pattern ?: 'in' | 'pre' | 'post', nodeOrPropertyName ?: NodeOrPropertyName): AbstractResultsByProperty<N> {
DFSIterative(pattern ?: 'in' | 'pre' | 'post', nodeOrPropertyName ?: NodeOrPropertyName): AbstractBinaryTreeNodeProperties<N> {
pattern = pattern || 'in';
nodeOrPropertyName = nodeOrPropertyName || 'id';
this._resetResults();
@ -1099,9 +1097,9 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
* can be either a `BinaryTreeNode` property name or the string `'id'`. If a property name is provided, the function
* will accumulate results based on that property. If no property name is provided, the function will default to
* accumulating results
* @returns The function `levelIterative` returns an object of type `AbstractResultsByProperty<N>`.
* @returns The function `levelIterative` returns an object of type `AbstractBinaryTreeNodeProperties<N>`.
*/
levelIterative(node: N | null, nodeOrPropertyName ?: NodeOrPropertyName): AbstractResultsByProperty<N> {
levelIterative(node: N | null, nodeOrPropertyName ?: NodeOrPropertyName): AbstractBinaryTreeNodeProperties<N> {
nodeOrPropertyName = nodeOrPropertyName || 'id';
node = node || this.root;
if (!node) return [];
@ -1142,14 +1140,14 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
* @param {NodeOrPropertyName} [nodeOrPropertyName] - The `nodeOrPropertyName` parameter is an optional parameter that
* specifies the property of the `BinaryTreeNode` object to collect at each level. It can be one of the following
* values:
* @returns The function `listLevels` returns a 2D array of `AbstractResultByProperty<N>` objects.
* @returns The function `listLevels` returns a 2D array of `AbstractBinaryTreeNodeProperty<N>` objects.
*/
listLevels(node: N | null, nodeOrPropertyName?: NodeOrPropertyName): AbstractResultByProperty<N>[][] {
listLevels(node: N | null, nodeOrPropertyName?: NodeOrPropertyName): AbstractBinaryTreeNodeProperty<N>[][] {
nodeOrPropertyName = nodeOrPropertyName || 'id';
node = node || this.root;
if (!node) return [];
const levelsNodes: AbstractResultByProperty<N>[][] = [];
const levelsNodes: AbstractBinaryTreeNodeProperty<N>[][] = [];
const collectByProperty = (node: N, level: number) => {
switch (nodeOrPropertyName) {
@ -1236,9 +1234,9 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
* @param {NodeOrPropertyName} [nodeOrPropertyName] - The `nodeOrPropertyName` parameter is used to specify the
* property of the nodes that you want to retrieve in the results. It can be either the node itself or the name of the
* property. If not provided, it defaults to `'id'`.
* @returns The function `morris` returns an object of type `AbstractResultsByProperty<N>`.
* @returns The function `morris` returns an object of type `AbstractBinaryTreeNodeProperties<N>`.
*/
morris(pattern?: 'in' | 'pre' | 'post', nodeOrPropertyName?: NodeOrPropertyName): AbstractResultsByProperty<N> {
morris(pattern?: 'in' | 'pre' | 'post', nodeOrPropertyName?: NodeOrPropertyName): AbstractBinaryTreeNodeProperties<N> {
if (this.root === null) return [];
pattern = pattern || 'in';
@ -1467,9 +1465,9 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
* to 'id'.
* @param {NodeOrPropertyName} [nodeOrPropertyName] - The parameter `nodeOrPropertyName` is an optional parameter that
* can accept a value of type `NodeOrPropertyName`.
* @returns The method returns an object of type `AbstractResultsByProperty<T>`.
* @returns The method returns an object of type `AbstractBinaryTreeNodeProperties<T>`.
*/
protected _getResultByPropertyName(nodeOrPropertyName ?: NodeOrPropertyName): AbstractResultsByProperty<N> {
protected _getResultByPropertyName(nodeOrPropertyName ?: NodeOrPropertyName): AbstractBinaryTreeNodeProperties<N> {
nodeOrPropertyName = nodeOrPropertyName ?? 'id';
switch (nodeOrPropertyName) {

View file

@ -7,18 +7,18 @@
*/
import {BST, BSTNode} from './bst';
import type {AVLTreeOptions, BinaryTreeDeletedResult, BinaryTreeNodeId, RecursiveAVLTreeNode} from '../types';
import {IBinaryTreeNode} from '../interfaces';
import {IAVLTree, IAVLTreeNode} from '../interfaces';
export class AVLTreeNode<T, FAMILY extends AVLTreeNode<T, FAMILY> = RecursiveAVLTreeNode<T>> extends BSTNode<T, FAMILY> implements IBinaryTreeNode<T, FAMILY> {
export class AVLTreeNode<T, FAMILY extends AVLTreeNode<T, FAMILY> = RecursiveAVLTreeNode<T>> extends BSTNode<T, FAMILY> implements IAVLTreeNode<T, FAMILY> {
}
export class AVLTree<N extends AVLTreeNode<N['val'], N> = AVLTreeNode<number>> extends BST<N> {
export class AVLTree<N extends AVLTreeNode<N['val'], N> = AVLTreeNode<number>> extends BST<N> implements IAVLTree<N> {
constructor(options?: AVLTreeOptions) {
super(options);
}
override _createNode(id: BinaryTreeNodeId, val: N['val'], count?: number): N {
override createNode(id: BinaryTreeNodeId, val: N['val'], count?: number): N {
const node = new AVLTreeNode<N['val'], N>(id, val, count);
return node as N;
}

View file

@ -8,13 +8,13 @@
import type {BinaryTreeNodeId, RecursiveBinaryTreeNode} from '../types';
import {BinaryTreeOptions} from '../types';
import {IBinaryTree, IBinaryTreeNode} from '../interfaces';
import {IAbstractBinaryTree, IAbstractBinaryTreeNode} from '../interfaces';
import {AbstractBinaryTree, AbstractBinaryTreeNode} from './abstract-binary-tree';
import {IBinaryTree, IBinaryTreeNode} from '../interfaces/binary-tree';
export class BinaryTreeNode<T = number, FAMILY extends BinaryTreeNode<T, FAMILY> = RecursiveBinaryTreeNode<T>> extends AbstractBinaryTreeNode<T, FAMILY> implements IBinaryTreeNode<T, FAMILY> {
_createNode(id: BinaryTreeNodeId, val: T | null, count?: number): FAMILY | null {
createNode(id: BinaryTreeNodeId, val: T | null, count?: number): FAMILY | null {
return val !== null ? new BinaryTreeNode<T, FAMILY>(id, val, count) as FAMILY : null;
}
@ -43,7 +43,7 @@ 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(id: BinaryTreeNodeId, val: N['val'] | null, count?: number): N | null {
createNode(id: BinaryTreeNodeId, val: N['val'] | null, count?: number): N | null {
const node = new BinaryTreeNode<N['val'], N>(id, val, count);
return node as N | null;
}

View file

@ -8,13 +8,13 @@
import type {BinaryTreeNodeId, BinaryTreeNodePropertyName, BSTComparator, RecursiveBSTNode} from '../types';
import {BinaryTreeDeletedResult, BSTOptions, CP, FamilyPosition, LoopType} from '../types';
import {BinaryTree, BinaryTreeNode} from './binary-tree';
import {IBinaryTree, IBinaryTreeNode} from '../interfaces';
import {IAbstractBinaryTree, IAbstractBinaryTreeNode, IBST, IBSTNode} from '../interfaces';
export class BSTNode<T, FAMILY extends BSTNode<T, FAMILY> = RecursiveBSTNode<T>> extends BinaryTreeNode<T, FAMILY> implements IBinaryTreeNode<T, FAMILY> {
export class BSTNode<T, FAMILY extends BSTNode<T, FAMILY> = RecursiveBSTNode<T>> extends BinaryTreeNode<T, FAMILY> implements IBSTNode<T, FAMILY> {
}
export class BST<N extends BSTNode<N['val'], N> = BSTNode<number>> extends BinaryTree<N> implements IBinaryTree<N> {
export class BST<N extends BSTNode<N['val'], N> = BSTNode<number>> extends BinaryTree<N> implements IBST<N> {
/**
* The constructor function accepts an optional options object and sets the comparator property if provided.
* @param [options] - An optional object that can contain the following properties:
@ -29,7 +29,7 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode<number>> extends Binar
}
}
override _createNode(id: BinaryTreeNodeId, val: N['val'] | null, count?: number): N | null {
override createNode(id: BinaryTreeNodeId, val: N['val'] | null, count?: number): N | null {
const node = val !== null ? new BSTNode<N['val'], N>(id, val, count) : null;
return node as N;
}
@ -48,7 +48,7 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode<number>> extends Binar
*/
override add(id: BinaryTreeNodeId, val: N['val'] | null, count: number = 1): N | null {
let inserted: N | null = null;
const newNode = this._createNode(id, val, count);
const newNode = this.createNode(id, val, count);
if (this.root === null) {
this._setRoot(newNode);
this._setSize(this.size + 1);
@ -133,7 +133,7 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode<number>> extends Binar
* greater than, it returns the ID of the leftmost node. Otherwise, it also returns the ID of the rightmost node. If
* there are no nodes in
*/
lastKey() {
lastKey(): BinaryTreeNodeId {
if (this._compare(0, 1) === CP.lt) return this.getRightMost()?.id ?? 0;
else if (this._compare(0, 1) === CP.gt) return this.getLeftMost()?.id ?? 0;
else return this.getRightMost()?.id ?? 0;

View file

@ -1,9 +1,10 @@
import {BinaryTree, BinaryTreeNode} from './binary-tree';
import {IBinaryTree, IBinaryTreeNode} from '../interfaces';
import {BinaryTreeNode} from './binary-tree';
import {RBColor, RBTreeOptions} from '../types';
import {IRBTree, IRBTreeNode} from '../interfaces/rb-tree';
import {BST} from './bst';
class RBNode<T, FAMILY extends RBNode<T, FAMILY>> extends BinaryTreeNode<T, FAMILY> implements IBinaryTreeNode<T, FAMILY> {
export class RBTreeNode<T, FAMILY extends RBTreeNode<T, FAMILY>> extends BinaryTreeNode<T, FAMILY> implements IRBTreeNode<T, FAMILY> {
// override createNode(id: BinaryTreeNodeId, val: T | null, count?: number): RBNode<T> | null {
// return val !== null ? new RBNode<T>(id, val, count) : null;
// }
@ -58,12 +59,12 @@ class RBNode<T, FAMILY extends RBNode<T, FAMILY>> extends BinaryTreeNode<T, FAMI
// }
}
class RBTree<N extends RBNode<N['val'], N>> extends BinaryTree<N> implements IBinaryTree<N> {
export class RBTree<N extends RBTreeNode<N['val'], N>> extends BST<N> implements IRBTree<N> {
constructor(options?: RBTreeOptions) {
super(options);
}
// override _createNode(id: BinaryTreeNodeId, val: N | null, count?: number): RBNode<N> | null {
// override createNode(id: BinaryTreeNodeId, val: N | null, count?: number): RBNode<N> | null {
// return val !== null ? new RBNode<N>(id, val, count) : null;
// }

View file

@ -7,16 +7,16 @@
*/
import {BST, BSTNode} from './bst';
import type {BinaryTreeNodeId, RecursiveTreeMultiSetNode, TreeMultiSetOptions} from '../types';
import {IBinaryTree, IBinaryTreeNode} from '../interfaces';
import {IAbstractBinaryTree, IAbstractBinaryTreeNode, IBST, IBSTNode} from '../interfaces';
export class TreeMultiSetNode<T, FAMILY extends TreeMultiSetNode<T, FAMILY> = RecursiveTreeMultiSetNode<T>> extends BSTNode<T, FAMILY> implements IBinaryTreeNode<T, FAMILY> {
export class TreeMultiSetNode<T, FAMILY extends TreeMultiSetNode<T, FAMILY> = RecursiveTreeMultiSetNode<T>> extends BSTNode<T, FAMILY> implements IBSTNode<T, FAMILY> {
}
/**
* The only distinction between a TreeMultiSet and a BST lies in the ability of the former to store duplicate nodes through the utilization of counters.
*/
export class TreeMultiSet<N extends BSTNode<N['val'], N> = BSTNode<number>> extends BST<N> implements IBinaryTree<N> {
export class TreeMultiSet<N extends BSTNode<N['val'], N> = BSTNode<number>> extends BST<N> implements IBST<N> {
constructor(options?: TreeMultiSetOptions) {
super({...options, isDuplicatedVal: true});
}
@ -30,7 +30,7 @@ export class TreeMultiSet<N extends BSTNode<N['val'], N> = BSTNode<number>> exte
* 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(id: BinaryTreeNodeId, val: N['val'], count?: number): N {
override createNode(id: BinaryTreeNodeId, val: N['val'], count?: number): N {
const node = new TreeMultiSetNode<N['val'], N>(id, val, count);
return node as N;
}

View file

@ -8,7 +8,7 @@
import {arrayRemove, uuidV4} from '../../utils';
import {PriorityQueue} from '../priority-queue';
import type {DijkstraResult, VertexId} from '../types';
import {IGraph} from '../interfaces';
import {IAbstractGraph} from '../interfaces';
export abstract class AbstractVertex<T = number> {
@ -43,7 +43,7 @@ export abstract class AbstractVertex<T = number> {
// * @param id
// * @param val
// */
// abstract _createVertex(id: VertexId, val?: T): AbstractVertex<T>;
// abstract createVertex(id: VertexId, val?: T): AbstractVertex<T>;
}
export abstract class AbstractEdge<T = number> {
@ -88,7 +88,7 @@ export abstract class AbstractEdge<T = number> {
// * @param weight
// * @param val
// */
// abstract _createEdge(srcOrV1: VertexId | string, destOrV2: VertexId | string, weight?: number, val?: E): E;
// abstract createEdge(srcOrV1: VertexId | string, destOrV2: VertexId | string, weight?: number, val?: E): E;
protected _setHashCode(v: string) {
this._hashCode = v;
@ -96,7 +96,7 @@ export abstract class AbstractEdge<T = number> {
}
// Connected Component === Largest Connected Sub-Graph
export abstract class AbstractGraph<V extends AbstractVertex<any>, E extends AbstractEdge<any>> implements IGraph<V, E> {
export abstract class AbstractGraph<V extends AbstractVertex<any>, E extends AbstractEdge<any>> implements IAbstractGraph<V, E> {
private _vertices: Map<VertexId, V> = new Map<VertexId, V>();
get vertices(): Map<VertexId, V> {
@ -109,7 +109,7 @@ export abstract class AbstractGraph<V extends AbstractVertex<any>, E extends Abs
* @param id
* @param val
*/
abstract _createVertex(id: VertexId, val?: V): V;
abstract createVertex(id: VertexId, val?: V): V;
/**
* In TypeScript, a subclass inherits the interface implementation of its parent class, without needing to implement the same interface again in the subclass. This behavior differs from Java's approach. In Java, if a parent class implements an interface, the subclass needs to explicitly implement the same interface, even if the parent class has already implemented it.
@ -119,13 +119,11 @@ export abstract class AbstractGraph<V extends AbstractVertex<any>, E extends Abs
* @param weight
* @param val
*/
abstract _createEdge(srcOrV1: VertexId | string, destOrV2: VertexId | string, weight?: number, val?: E): E;
abstract removeEdgeBetween(srcOrId: V | VertexId, destOrId: V | VertexId): E | null;
abstract createEdge(srcOrV1: VertexId | string, destOrV2: VertexId | string, weight?: number, val?: E): E;
abstract removeEdge(edge: E): E | null;
_getVertex(vertexOrId: VertexId | V): V | null {
protected _getVertex(vertexOrId: VertexId | V): V | null {
const vertexId = this._getVertexId(vertexOrId);
return this._vertices.get(vertexId) || null;
}
@ -134,7 +132,7 @@ export abstract class AbstractGraph<V extends AbstractVertex<any>, E extends Abs
return this._vertices.get(vertexId) || null;
}
_getVertexId(vertexOrId: V | VertexId): VertexId {
protected _getVertexId(vertexOrId: V | VertexId): VertexId {
return vertexOrId instanceof AbstractVertex ? vertexOrId.id : vertexOrId;
}
@ -151,7 +149,7 @@ export abstract class AbstractGraph<V extends AbstractVertex<any>, E extends Abs
abstract getEdge(srcOrId: V | VertexId, destOrId: V | VertexId): E | null;
createAddVertex(id: VertexId, val?: V['val']): boolean {
const newVertex = this._createVertex(id, val);
const newVertex = this.createVertex(id, val);
return this.addVertex(newVertex);
}
@ -213,7 +211,7 @@ export abstract class AbstractGraph<V extends AbstractVertex<any>, E extends Abs
createAddEdge(src: V | VertexId, dest: V | VertexId, weight: number, val: E['val']): boolean {
if (src instanceof AbstractVertex) src = src.id;
if (dest instanceof AbstractVertex) dest = dest.id;
const newEdge = this._createEdge(src, dest, weight, val);
const newEdge = this.createEdge(src, dest, weight, val);
return this.addEdge(newEdge);
}

View file

@ -8,7 +8,7 @@
import {arrayRemove} from '../../utils';
import {AbstractEdge, AbstractGraph, AbstractVertex} from './abstract-graph';
import type {TopologicalStatus, VertexId} from '../types';
import {IDirectedGraph} from '../interfaces';
import {IDirectedGraph, IAbstractGraph} from '../interfaces';
export class DirectedVertex<T = number> extends AbstractVertex<T> {
/**
@ -22,7 +22,7 @@ export class DirectedVertex<T = number> extends AbstractVertex<T> {
super(id, val);
}
// _createVertex(id: VertexId, val?: T): DirectedVertex<T> {
// createVertex(id: VertexId, val?: T): DirectedVertex<T> {
// return new DirectedVertex<T>(id, val);
// }
}
@ -67,7 +67,7 @@ export class DirectedEdge<T = number> extends AbstractEdge<T> {
this._dest = v;
}
// _createEdge(src: VertexId, dest: VertexId, weight?: number, val?: T): DirectedEdge<T> {
// createEdge(src: VertexId, dest: VertexId, weight?: number, val?: T): DirectedEdge<T> {
// if (weight === undefined || weight === null) weight = 1;
// return new DirectedEdge(src, dest, weight, val);
// }
@ -98,7 +98,7 @@ export class DirectedGraph<V extends DirectedVertex<any> = DirectedVertex, E ext
* @param id
* @param val
*/
_createVertex(id: VertexId, val?: V['val']): V {
createVertex(id: VertexId, val?: V['val']): V {
return new DirectedVertex(id, val ?? id) as V;
}
@ -110,7 +110,7 @@ export class DirectedGraph<V extends DirectedVertex<any> = DirectedVertex, E ext
* @param weight
* @param val
*/
_createEdge(src: VertexId, dest: VertexId, weight?: number, val?: E['val']): E {
createEdge(src: VertexId, dest: VertexId, weight?: number, val?: E['val']): E {
return new DirectedEdge(src, dest, weight ?? 1, val) as E;
}
@ -186,7 +186,7 @@ export class DirectedGraph<V extends DirectedVertex<any> = DirectedVertex, E ext
* @returns The function `removeEdgeBetween` returns the removed edge (`E`) if it exists, or `null` if
* the edge does not exist.
*/
removeEdgeBetween(srcOrId: V | VertexId, destOrId: V | VertexId): E | null {
removeEdgeSrcToDest(srcOrId: V | VertexId, destOrId: V | VertexId): E | null {
const src: V | null = this._getVertex(srcOrId);
const dest: V | null = this._getVertex(destOrId);
@ -197,14 +197,6 @@ export class DirectedGraph<V extends DirectedVertex<any> = DirectedVertex, E ext
const srcOutEdges = this._outEdgeMap.get(src);
if (srcOutEdges) {
/**
* The removeEdge function removes an edge from a graph and returns the removed edge, or null if the edge was not
* found.
* @param {E} edge - The `edge` parameter represents the edge that you want to remove from the graph. It should be an
* object that has `src` and `dest` properties, which represent the source and destination vertices of the edge,
* respectively.
* @returns The method `removeEdge` returns the removed edge (`E`) if it exists, or `null` if the edge does not exist.
*/
arrayRemove<E>(srcOutEdges, (edge: E) => edge.dest === dest.id);
}
@ -244,14 +236,25 @@ export class DirectedGraph<V extends DirectedVertex<any> = DirectedVertex, E ext
}
/**
* The function removeAllEdges removes all edges between two vertices.
* @param {VertexId | V} src - The `src` parameter can be either a `VertexId` or a `V`.
* @param {VertexId | V} dest - The `dest` parameter represents the destination vertex of an edge. It
* can be either a `VertexId` or a `V`.
* @returns An empty array of DirectedEdge objects is being returned.
* The function removes all edges between two vertices and returns the removed edges.
* @param {VertexId | V} v1 - The parameter `v1` represents either a `VertexId` or a `V` object. It is used to identify
* the first vertex in the graph.
* @param {VertexId | V} v2 - The parameter `v2` represents either a `VertexId` or a `V`. It is used to identify the
* second vertex involved in the edges that need to be removed.
* @returns The function `removeEdgesBetween` returns an array of removed edges (`E[]`).
*/
removeAllEdges(src: VertexId | V, dest: VertexId | V): E[] {
return [];
removeEdgesBetween(v1: VertexId | V, v2: VertexId | V): E[] {
const removed: E[] = [];
if (v1 && v2) {
const v1ToV2 = this.removeEdgeSrcToDest(v1, v2);
const v2ToV1 = this.removeEdgeSrcToDest(v2, v1);
v1ToV2 && removed.push(v1ToV2);
v2ToV1 && removed.push(v2ToV1);
}
return removed;
}
/**

View file

@ -8,6 +8,7 @@
import {arrayRemove} from '../../utils';
import {AbstractEdge, AbstractGraph, AbstractVertex} from './abstract-graph';
import type {VertexId} from '../types';
import {IUNDirectedGraph} from '../interfaces';
export class UndirectedVertex<T = number> extends AbstractVertex<T> {
/**
@ -20,10 +21,6 @@ export class UndirectedVertex<T = number> extends AbstractVertex<T> {
constructor(id: VertexId, val?: T) {
super(id, val);
}
// _createVertex(id: VertexId, val?: T): T {
// return new T(id, val);
// }
}
export class UndirectedEdge<T = number> extends AbstractEdge<T> {
@ -51,14 +48,9 @@ export class UndirectedEdge<T = number> extends AbstractEdge<T> {
set vertices(v: [VertexId, VertexId]) {
this._vertices = v;
}
// _createEdge(src: VertexId, dest: VertexId, weight?: number, val?: T): T {
// if (weight === undefined || weight === null) weight = 1;
// return new UndirectedEdge(src, dest, weight, val);
// }
}
export class UndirectedGraph<V extends UndirectedVertex<any> = UndirectedVertex, E extends UndirectedEdge<any> = UndirectedEdge> extends AbstractGraph<V, E> {
export class UndirectedGraph<V extends UndirectedVertex<any> = UndirectedVertex, E extends UndirectedEdge<any> = UndirectedEdge> extends AbstractGraph<V, E> implements IUNDirectedGraph<V, E>{
constructor() {
super();
@ -77,13 +69,13 @@ export class UndirectedGraph<V extends UndirectedVertex<any> = UndirectedVertex,
* @param id
* @param val
*/
_createVertex(id: VertexId, val?: V['val']): V {
override createVertex(id: VertexId, val?: V['val']): V {
return new UndirectedVertex(id, val ?? id) as V;
}
/**
* The function _createEdge creates an undirected edge between two vertices with an optional weight and value.
* The function createEdge creates an undirected edge between two vertices with an optional weight and value.
* @param {VertexId} v1 - The parameter `v1` represents the first vertex of the edge. It is of type `VertexId`, which
* could be a unique identifier or label for the vertex.
* @param {VertexId} v2 - The parameter `v2` represents the second vertex of the edge. It is of type `VertexId`, which
@ -94,7 +86,7 @@ export class UndirectedGraph<V extends UndirectedVertex<any> = UndirectedVertex,
* is used to store additional information or data associated with the edge.
* @returns an instance of the UndirectedEdge class, casted as type E.
*/
_createEdge(v1: VertexId, v2: VertexId, weight?: number, val?: E['val']): E {
override createEdge(v1: VertexId, v2: VertexId, weight?: number, val?: E['val']): E {
return new UndirectedEdge(v1, v2, weight ?? 1, val) as E;
}
@ -230,19 +222,6 @@ export class UndirectedGraph<V extends UndirectedVertex<any> = UndirectedVertex,
return [...edgeSet];
}
/**
* The function "getEdgesOf" returns an array of undirected edges connected to a given vertex or vertex ID.
* @param {V | VertexId} vertexOrId - The parameter `vertexOrId` can be either an
* `V` object or a `VertexId`.
* @returns The function `getEdgesOf` returns an array of `E` objects.
*/
getEdgesOf(vertexOrId: V | VertexId): E[] {
const vertex = this._getVertex(vertexOrId);
if (!vertex) {
return [];
}
return this._edges.get(vertex) || [];
}
/**
* The function `getNeighbors` returns an array of neighboring vertices of a given vertex in an undirected graph.
@ -254,7 +233,7 @@ export class UndirectedGraph<V extends UndirectedVertex<any> = UndirectedVertex,
const neighbors: V[] = [];
const vertex = this._getVertex(vertexOrId);
if (vertex) {
const neighborEdges = this.getEdgesOf(vertex);
const neighborEdges = this.edgesOf(vertex);
for (const edge of neighborEdges) {
const neighbor = this._getVertex(edge.vertices.filter(e => e !== vertex.id)[0]);
if (neighbor) {

View file

@ -0,0 +1,238 @@
import {
AbstractBinaryTreeNodeProperty,
AbstractBinaryTreeNodeProperties,
BinaryTreeDeletedResult,
BinaryTreeNodeId,
BinaryTreeNodePropertyName,
DFSOrderPattern,
FamilyPosition,
LoopType,
NodeOrPropertyName
} from '../types';
import {AbstractBinaryTreeNode} from '../binary-tree';
export interface IAbstractBinaryTreeNode<T, FAMILY extends IAbstractBinaryTreeNode<T, FAMILY>> {
createNode(id: BinaryTreeNodeId, val: T | null, count?: number): FAMILY | null;
get id(): BinaryTreeNodeId
set id(v: BinaryTreeNodeId)
get val(): T
set val(v: T)
get left(): FAMILY | null | undefined
set left(v: FAMILY | null | undefined)
get right(): FAMILY | null | undefined
set right(v: FAMILY | null | undefined)
get parent(): FAMILY | null | undefined
set parent(v: FAMILY | null | undefined)
get familyPosition(): FamilyPosition
set familyPosition(v: FamilyPosition)
get count(): number
set count(v: number)
get height(): number
set height(v: number)
swapLocation(swapNode: FAMILY): FAMILY
clone(): FAMILY | null;
}
export interface IAbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val'], N>> {
createNode(id: BinaryTreeNodeId, val: N['val'] | null, count?: number): N | null
get loopType(): LoopType
get visitedId(): BinaryTreeNodeId[]
get visitedVal(): Array<N['val']>
get visitedNode(): N[]
get visitedCount(): number[]
get visitedLeftSum(): number[]
get autoIncrementId(): boolean
get maxId(): number
get isDuplicatedVal(): boolean
get root(): N | null
get size(): number
get count(): number
clear(): void
isEmpty(): boolean
add(id: BinaryTreeNodeId, val?: N['val'], count?: number): N | null | undefined
addTo(newNode: N | null, parent: N): N | null | undefined
addMany(data: N[] | Array<N['val']>): (N | null | undefined)[]
fill(data: N[] | Array<N['val']>): boolean
remove(id: BinaryTreeNodeId, ignoreCount?: boolean): BinaryTreeDeletedResult<N>[]
getDepth(node: N): number
getHeight(beginRoot?: N | null): number
getMinHeight(beginRoot?: N | null): number
isBalanced(beginRoot?: N | null): boolean
getNodes(nodeProperty: BinaryTreeNodeId | N, propertyName ?: BinaryTreeNodePropertyName, onlyOne ?: boolean): N[]
has(nodeProperty: BinaryTreeNodeId | N, propertyName ?: BinaryTreeNodePropertyName): boolean
get(nodeProperty: BinaryTreeNodeId | N, propertyName ?: BinaryTreeNodePropertyName): N | null
getPathToRoot(node: N): N[]
getLeftMost(): N | null;
getLeftMost(node: N): N;
getLeftMost(node?: N | null): N | null
getRightMost(): N | null;
getRightMost(node: N): N;
getRightMost(node?: N | null): N | null
isBST(node?: N | null): boolean
getSubTreeSizeAndCount(subTreeRoot: N | null | undefined): [number, number]
// --- start additional methods ---
subTreeSum(subTreeRoot: N, propertyName ?: BinaryTreeNodePropertyName): number
subTreeAdd(subTreeRoot: N, delta: number, propertyName ?: BinaryTreeNodePropertyName): boolean
BFS(): BinaryTreeNodeId[];
BFS(nodeOrPropertyName: 'id'): BinaryTreeNodeId[];
BFS(nodeOrPropertyName: 'val'): N['val'][];
BFS(nodeOrPropertyName: 'node'): N[];
BFS(nodeOrPropertyName: 'count'): number[];
BFS(nodeOrPropertyName ?: NodeOrPropertyName): AbstractBinaryTreeNodeProperties<N>
DFS(): BinaryTreeNodeId[];
DFS(pattern?: DFSOrderPattern, nodeOrPropertyName?: 'id'): BinaryTreeNodeId[];
DFS(pattern?: DFSOrderPattern, nodeOrPropertyName?: 'val'): N[];
DFS(pattern?: DFSOrderPattern, nodeOrPropertyName?: 'node'): N[];
DFS(pattern?: DFSOrderPattern, nodeOrPropertyName?: 'count'): number[];
DFS(pattern ?: 'in' | 'pre' | 'post', nodeOrPropertyName ?: NodeOrPropertyName): AbstractBinaryTreeNodeProperties<N>
DFSIterative(): BinaryTreeNodeId[];
DFSIterative(pattern?: DFSOrderPattern, nodeOrPropertyName?: 'id'): BinaryTreeNodeId[];
DFSIterative(pattern?: DFSOrderPattern, nodeOrPropertyName?: 'val'): N[];
DFSIterative(pattern?: DFSOrderPattern, nodeOrPropertyName?: 'node'): N[];
DFSIterative(pattern?: DFSOrderPattern, nodeOrPropertyName?: 'count'): number[];
DFSIterative(pattern ?: 'in' | 'pre' | 'post', nodeOrPropertyName ?: NodeOrPropertyName): AbstractBinaryTreeNodeProperties<N>
levelIterative(node: N | null): BinaryTreeNodeId[];
levelIterative(node: N | null, nodeOrPropertyName?: 'id'): BinaryTreeNodeId[];
levelIterative(node: N | null, nodeOrPropertyName?: 'val'): N['val'][];
levelIterative(node: N | null, nodeOrPropertyName?: 'node'): N[];
levelIterative(node: N | null, nodeOrPropertyName?: 'count'): number[];
levelIterative(node: N | null, nodeOrPropertyName ?: NodeOrPropertyName): AbstractBinaryTreeNodeProperties<N>
listLevels(node: N | null): BinaryTreeNodeId[][];
listLevels(node: N | null, nodeOrPropertyName?: 'id'): BinaryTreeNodeId[][];
listLevels(node: N | null, nodeOrPropertyName?: 'val'): N['val'][][];
listLevels(node: N | null, nodeOrPropertyName?: 'node'): N[][];
listLevels(node: N | null, nodeOrPropertyName?: 'count'): number[][];
listLevels(node: N | null, nodeOrPropertyName?: NodeOrPropertyName): AbstractBinaryTreeNodeProperty<N>[][]
getPredecessor(node: N): N
morris(): BinaryTreeNodeId[];
morris(pattern?: DFSOrderPattern, nodeOrPropertyName?: 'id'): BinaryTreeNodeId[];
morris(pattern?: DFSOrderPattern, nodeOrPropertyName?: 'val'): N[];
morris(pattern?: DFSOrderPattern, nodeOrPropertyName?: 'node'): N[];
morris(pattern?: DFSOrderPattern, nodeOrPropertyName?: 'count'): number[];
morris(pattern?: 'in' | 'pre' | 'post', nodeOrPropertyName?: NodeOrPropertyName): AbstractBinaryTreeNodeProperties<N>
// _setLoopType(value: LoopType): void
//
// _setVisitedId(value: BinaryTreeNodeId[]): void
//
// _setVisitedVal(value: Array<N>): void
//
// _setVisitedNode(value: N[]): void
//
// setVisitedCount(value: number[]): void
//
// _setVisitedLeftSum(value: number[]): void
//
// _setAutoIncrementId(value: boolean): void
//
// _setMaxId(value: number): void
//
// _setIsDuplicatedVal(value: boolean): void
//
// _setRoot(v: N | null): void
//
// _setSize(v: number): void
//
// _setCount(v: number): void
//
// _resetResults(): void
// _pushByPropertyNameStopOrNot(cur: N, result: (N | null | undefined)[], nodeProperty: BinaryTreeNodeId | N, propertyName ?: BinaryTreeNodePropertyName, onlyOne ?: boolean): void
//
// _accumulatedByPropertyName(node: N, nodeOrPropertyName ?: NodeOrPropertyName): void
//
// _getResultByPropertyName(nodeOrPropertyName ?: NodeOrPropertyName): AbstractBinaryTreeNodeProperties<N>
// --- end additional methods ---
}

View file

@ -1,12 +1,12 @@
import {VertexId} from '../types';
export interface IGraph<V, E> {
export interface IAbstractGraph<V, E> {
hasVertex(vertexOrId: V | VertexId): boolean;
_getVertex(vertexOrId: VertexId | V): V | null;
// _getVertex(vertexOrId: VertexId | V): V | null;
_getVertexId(vertexOrId: V | VertexId): VertexId;
// _getVertexId(vertexOrId: V | VertexId): VertexId;
createAddVertex(id: VertexId, val?: V): boolean;
@ -30,8 +30,6 @@ export interface IGraph<V, E> {
addEdge(edge: E): boolean;
removeEdgeBetween(src: V | VertexId, dest: V | VertexId): E | null;
removeEdge(edge: E): E | null;
setEdgeWeight(srcOrId: V | VertexId, destOrId: V | VertexId, weight: number): boolean;

View file

@ -1 +1,28 @@
export {}
import {AVLTreeNode} from '../binary-tree';
import {IBST, IBSTNode} from './bst';
import {BinaryTreeDeletedResult, BinaryTreeNodeId} from '../types';
export interface IAVLTreeNode<T, FAMILY extends IAVLTreeNode<T, FAMILY>> extends IBSTNode<T, FAMILY> {
}
export interface IAVLTree<N extends AVLTreeNode<N['val'], N>> extends IBST<N> {
add(id: BinaryTreeNodeId, val: N['val'] | null, count?: number): N | null
remove(id: BinaryTreeNodeId, isUpdateAllLeftSum?: boolean): BinaryTreeDeletedResult<N>[]
balanceFactor(node: N): number
updateHeight(node: N): void
balancePath(node: N): void
balanceLL(A: N): void
balanceLR(A: N): void
balanceRR(A: N): void
balanceRL(A: N): void
}

View file

@ -1,55 +1,8 @@
import {BinaryTreeNodeId, FamilyPosition} from '../types';
import {BinaryTreeNode} from '../binary-tree';
import {IAbstractBinaryTree, IAbstractBinaryTreeNode} from './abstract-binary-tree';
export interface IBinaryTreeNode<T, FAMILY extends IBinaryTreeNode<T, FAMILY>> {
_createNode(id: BinaryTreeNodeId, val: T | null, count?: number): FAMILY | null;
get id(): BinaryTreeNodeId
set id(v: BinaryTreeNodeId)
get val(): T
set val(v: T)
get left(): FAMILY | null | undefined
set left(v: FAMILY | null | undefined)
get right(): FAMILY | null | undefined
set right(v: FAMILY | null | undefined)
get parent(): FAMILY | null | undefined
set parent(v: FAMILY | null | undefined)
get familyPosition(): FamilyPosition
set familyPosition(v: FamilyPosition)
get count(): number
set count(v: number)
get height(): number
set height(v: number)
_createNode(id: BinaryTreeNodeId, val: T | null, count?: number): FAMILY | null
swapLocation(swapNode: FAMILY): FAMILY
clone(): FAMILY | null;
export interface IBinaryTreeNode<T, FAMILY extends IBinaryTreeNode<T, FAMILY>> extends IAbstractBinaryTreeNode<T, FAMILY> {
}
export interface IBinaryTree<N extends IBinaryTreeNode<N['val'], N>> {
_createNode(id: BinaryTreeNodeId, val: N['val'] | null, count?: number): N | null
export interface IBinaryTree<N extends BinaryTreeNode<N['val'], N>> extends IAbstractBinaryTree<N> {
}

View file

@ -1 +1,33 @@
export {}
import {BSTNode} from '../binary-tree';
import {IBinaryTree, IBinaryTreeNode} from './binary-tree';
import {BinaryTreeDeletedResult, BinaryTreeNodeId, BinaryTreeNodePropertyName, BSTComparator, CP} from '../types';
export interface IBSTNode<T, FAMILY extends IBSTNode<T, FAMILY>> extends IBinaryTreeNode<T, FAMILY> {
}
export interface IBST<N extends BSTNode<N['val'], N>> extends IBinaryTree<N> {
createNode(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
lastKey(): BinaryTreeNodeId
remove(id: BinaryTreeNodeId, ignoreCount?: boolean): BinaryTreeDeletedResult<N>[]
getNodes(nodeProperty: BinaryTreeNodeId | N, propertyName ?: BinaryTreeNodePropertyName, onlyOne ?: boolean): N[]
// --- start additional functions
lesserSum(id: BinaryTreeNodeId, propertyName ?: BinaryTreeNodePropertyName): number
allGreaterNodesAdd(node: N, delta: number, propertyName ?: BinaryTreeNodePropertyName): boolean
balance(): boolean
isAVLBalanced(): boolean
// --- end additional functions
}

View file

@ -1,6 +1,7 @@
import {VertexId} from '../types';
import {IAbstractGraph} from './abstract-graph';
export interface IDirectedGraph<V, E> {
export interface IDirectedGraph<V, E> extends IAbstractGraph<V, E> {
incomingEdgesOf(vertex: V): E[];
outgoingEdgesOf(vertex: V): E[];
@ -12,4 +13,8 @@ export interface IDirectedGraph<V, E> {
getEdgeSrc(e: E): V | null;
getEdgeDest(e: E): V | null;
removeEdgeSrcToDest(srcOrId: V | VertexId, destOrId: V | VertexId): E | null;
removeEdgesBetween(v1: V | VertexId, v2: V | VertexId): E[];
}

View file

@ -1,4 +1,4 @@
export * from './binary-tree';
export * from './abstract-binary-tree';
export * from './bst';
export * from './avl-tree';
export * from './segment-tree';

View file

@ -0,0 +1,11 @@
import {RBTreeNode} from '../binary-tree';
import {IBST, IBSTNode} from './bst';
export interface IRBTreeNode<T, FAMILY extends IRBTreeNode<T, FAMILY>> extends IBSTNode<T, FAMILY> {
}
export interface IRBTree<N extends RBTreeNode<N['val'], N>> extends IBST<N> {
}

View file

@ -1,3 +1,6 @@
export interface IUNDirectedGraph<V, E> {
import {VertexId} from '../types';
import {IAbstractGraph} from './abstract-graph';
export interface IUNDirectedGraph<V, E> extends IAbstractGraph<V, E>{
removeEdgeBetween(v1: V | VertexId, v2: V | VertexId): E | null;
}

View file

@ -17,12 +17,12 @@ export type DFSOrderPattern = 'in' | 'pre' | 'post';
export type BinaryTreeNodeId = number;
export type BinaryTreeDeletedResult<N> = { deleted: N | null | undefined, needBalanced: N | null };
export type AbstractResultByProperty<N extends AbstractBinaryTreeNode<N['val'], N>> =
export type AbstractBinaryTreeNodeProperty<N extends AbstractBinaryTreeNode<N['val'], N>> =
N['val']
| N
| number
| BinaryTreeNodeId;
export type AbstractResultsByProperty<N extends AbstractBinaryTreeNode<N['val'], N>> = AbstractResultByProperty<N>[];
export type AbstractBinaryTreeNodeProperties<N extends AbstractBinaryTreeNode<N['val'], N>> = AbstractBinaryTreeNodeProperty<N>[];
export type AbstractRecursiveBinaryTreeNode<T> = AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
export type AbstractBinaryTreeOptions = {
loopType?: LoopType,

View file

@ -75,4 +75,67 @@ export const trampolineAsync = (fn: TrlAsyncFn) => {
},
{cont}
)
}
}
// export class AutoPruneMap<K, V> extends Map<K, V> {
//
// private _proxySet: Set<V>;
// get proxySet(): Set<V> {
// return this._proxySet;
// }
//
// set proxySet(value: Set<V>) {
// this._proxySet = value;
// }
//
// private _isEmptyArrayAllowed: boolean;
//
// get isEmptyArrayAllowed(): boolean {
// return this._isEmptyArrayAllowed;
// }
//
// set isEmptyArrayAllowed(value: boolean) {
// this._isEmptyArrayAllowed = value;
// }
//
// constructor(isEmptyArrayAllowed: boolean = false) {
// super();
// this._isEmptyArrayAllowed = isEmptyArrayAllowed;
// this._proxySet = new Set<V>();
// }
//
// set(key: K, value: V): this {
// if (Array.isArray(value) && !this.proxySet.has(value)) {
// if(!this.isEmptyArrayAllowed && value.length === 0) return this;
// value = this.createArrayProxy(value, key);
// if (!this.proxySet.has(value)) this.proxySet.add(value);
// }
// super.set(key, value);
// return this;
// }
//
// private createArrayProxy(array: V & any[], key: K) {
// const that = this;
// const proxyHandler: ProxyHandler<V & any[]> = {
// set(target: any, property: PropertyKey, value: any): boolean {
// const result = Reflect.set(target, property, value);
// that.checkAndDeleteEmptyArray(key);
// return result;
// },
// deleteProperty(target: any, property: PropertyKey): boolean {
// const result = Reflect.deleteProperty(target, property);
// that.checkAndDeleteEmptyArray(key);
// return result;
// },
// }
// return new Proxy(array, proxyHandler);
// }
//
// private checkAndDeleteEmptyArray(key: K): void {
// const value = this.get(key);
//
// if (Array.isArray(value) && value.length === 0) {
// super.delete(key);
// }
// }
// }

View file

@ -100,11 +100,11 @@ class MyEdge<E extends string> extends DirectedEdge<E> {
}
class MyDirectedGraph<V extends MyVertex<string>, E extends MyEdge<string>> extends DirectedGraph<V, E> {
_createVertex(id: VertexId, val: V['val']): V {
createVertex(id: VertexId, val: V['val']): V {
return new MyVertex(id, val) as V;
}
_createEdge(src: VertexId, dest: VertexId, weight?: number, val?: E['val']): E {
createEdge(src: VertexId, dest: VertexId, weight?: number, val?: E['val']): E {
return new MyEdge(src, dest, weight ?? 1, val) as E;
}
}
@ -171,7 +171,7 @@ describe('Inherit from DirectedGraph and perform operations', () => {
myGraph.addVertex(new MyVertex(2, 'data2'));
myGraph.addEdge(new MyEdge(1, 2, 10, 'edge-data1-2'));
const removedEdge = myGraph.removeEdgeBetween(1, 2);
const removedEdge = myGraph.removeEdgeSrcToDest(1, 2);
const edgeAfterRemoval = myGraph.getEdge(1, 2);
expect(removedEdge).toBeInstanceOf(MyEdge);
@ -246,7 +246,7 @@ describe('Inherit from DirectedGraph and perform operations test2.', () => {
expect(myGraph.getEdge(2, 1)).toBeTruthy();
expect(myGraph.getEdge(1, '100')).toBeFalsy();
myGraph.removeEdgeBetween(1, 2);
myGraph.removeEdgeSrcToDest(1, 2);
expect(myGraph.getEdge(1, 2)).toBeFalsy();
myGraph.addEdge(new MyEdge(3, 1, 3, 'edge-data-3-1'));