mirror of
https://github.com/zrwusa/data-structure-typed.git
synced 2024-11-23 12:54:04 +00:00
Organized all the interfaces. Implemented the removeEdgeSrcToDest method for the Graph class.
This commit is contained in:
parent
e70d988ac9
commit
6bc894c5c1
694
package-lock.json
generated
694
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
// }
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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) {
|
||||
|
|
238
src/data-structures/interfaces/abstract-binary-tree.ts
Normal file
238
src/data-structures/interfaces/abstract-binary-tree.ts
Normal 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 ---
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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> {
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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[];
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
export * from './binary-tree';
|
||||
export * from './abstract-binary-tree';
|
||||
export * from './bst';
|
||||
export * from './avl-tree';
|
||||
export * from './segment-tree';
|
||||
|
|
11
src/data-structures/interfaces/rb-tree.ts
Normal file
11
src/data-structures/interfaces/rb-tree.ts
Normal 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> {
|
||||
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
// }
|
||||
// }
|
||||
// }
|
|
@ -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'));
|
||||
|
|
Loading…
Reference in a new issue