mirror of
https://github.com/zrwusa/data-structure-typed.git
synced 2024-11-23 12:54:04 +00:00
By constraining the necessity to implement the _createNode method, we ensure that the node types are correct within the subclass. The current design of the Graph needs further optimization.
This commit is contained in:
parent
c1b5969c51
commit
1b441f1d47
|
@ -7,22 +7,17 @@
|
|||
*/
|
||||
import {BST, BSTNode} from './bst';
|
||||
import type {AVLTreeDeleted, BinaryTreeNodeId} from '../types';
|
||||
import {IBinaryTreeNode} from '../interfaces';
|
||||
|
||||
export class AVLTreeNode<T> extends BSTNode<T> {
|
||||
/**
|
||||
* The function overrides the clone method of the AVLTreeNode class to create a new AVLTreeNode object with the same
|
||||
* id, value, and count.
|
||||
* @returns The method is returning a new instance of the AVLTreeNode class with the same id, val, and count values as
|
||||
* the current instance.
|
||||
*/
|
||||
override clone(): AVLTreeNode<T> {
|
||||
return new AVLTreeNode<T>(this.id, this.val, this.count);
|
||||
export class AVLTreeNode<T> extends BSTNode<T> implements IBinaryTreeNode<T> {
|
||||
override _createNode(id: BinaryTreeNodeId, val: T | null, count?: number): AVLTreeNode<T> | null {
|
||||
return val !== null ? new AVLTreeNode<T>(id, val, count) : null;
|
||||
}
|
||||
}
|
||||
|
||||
export class AVLTree<T> extends BST<T> {
|
||||
|
||||
override createNode(id: BinaryTreeNodeId, val: T, count?: number): AVLTreeNode<T> {
|
||||
override _createNode(id: BinaryTreeNodeId, val: T, count?: number): AVLTreeNode<T> {
|
||||
return new AVLTreeNode<T>(id, val, count);
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ import type {
|
|||
ResultByProperty,
|
||||
ResultsByProperty
|
||||
} from '../types';
|
||||
import {IBinaryTree, IBinaryTreeNode} from '../interfaces';
|
||||
|
||||
/* This enumeration defines the position of a node within a family tree composed of three associated nodes, where 'root' represents the root node of the family tree, 'left' represents the left child node, and 'right' represents the right child node. */
|
||||
export enum FamilyPosition {root, left, right}
|
||||
|
@ -28,7 +29,7 @@ export enum FamilyPosition {root, left, right}
|
|||
*/
|
||||
export enum LoopType { iterative = 1, recursive = 2}
|
||||
|
||||
export class BinaryTreeNode<T> {
|
||||
export class BinaryTreeNode<T> implements IBinaryTreeNode<T> {
|
||||
|
||||
constructor(id: BinaryTreeNodeId, val: T, count?: number) {
|
||||
this._id = id;
|
||||
|
@ -47,6 +48,7 @@ export class BinaryTreeNode<T> {
|
|||
}
|
||||
|
||||
private _val: T;
|
||||
|
||||
get val(): T {
|
||||
return this._val;
|
||||
}
|
||||
|
@ -123,31 +125,37 @@ export class BinaryTreeNode<T> {
|
|||
this._height = v;
|
||||
}
|
||||
|
||||
_createNode(id: BinaryTreeNodeId, val: T | null, count?: number): BinaryTreeNode<T> | null {
|
||||
return val !== null ? new BinaryTreeNode<T>(id, val, count) : null;
|
||||
}
|
||||
|
||||
swapLocation(swapNode: BinaryTreeNode<T>): BinaryTreeNode<T> {
|
||||
const {val, count, height} = swapNode;
|
||||
const tempNode = new BinaryTreeNode<T>(swapNode.id, val);
|
||||
tempNode.val = val;
|
||||
tempNode.count = count;
|
||||
tempNode.height = height;
|
||||
const tempNode = this._createNode(swapNode.id, val);
|
||||
if (tempNode instanceof BinaryTreeNode) {
|
||||
tempNode.val = val;
|
||||
tempNode.count = count;
|
||||
tempNode.height = height;
|
||||
|
||||
swapNode.id = this.id;
|
||||
swapNode.val = this.val;
|
||||
swapNode.count = this.count;
|
||||
swapNode.height = this.height;
|
||||
swapNode.id = this.id;
|
||||
swapNode.val = this.val;
|
||||
swapNode.count = this.count;
|
||||
swapNode.height = this.height;
|
||||
|
||||
this.id = tempNode.id;
|
||||
this.val = tempNode.val;
|
||||
this.count = tempNode.count;
|
||||
this.height = tempNode.height;
|
||||
this.id = tempNode.id;
|
||||
this.val = tempNode.val;
|
||||
this.count = tempNode.count;
|
||||
this.height = tempNode.height;
|
||||
}
|
||||
return swapNode;
|
||||
}
|
||||
|
||||
clone(): BinaryTreeNode<T> {
|
||||
return new BinaryTreeNode<T>(this.id, this.val, this.count);
|
||||
clone(): BinaryTreeNode<T> | null {
|
||||
return this._createNode(this.id, this.val, this.count);
|
||||
}
|
||||
}
|
||||
|
||||
export class BinaryTree<T> {
|
||||
export class BinaryTree<T> implements IBinaryTree<T> {
|
||||
|
||||
/**
|
||||
* The constructor function accepts an optional options object and sets the values of loopType, autoIncrementId, and
|
||||
|
@ -243,19 +251,18 @@ export class BinaryTree<T> {
|
|||
}
|
||||
|
||||
/**
|
||||
* The function creates a new binary tree node with the given id, value, and count, or returns null if the value is
|
||||
* null.
|
||||
* The function creates a new binary tree node with the given id, value, and count if the value is not null, otherwise
|
||||
* it returns null.
|
||||
* @param {BinaryTreeNodeId} id - The `id` parameter is the identifier for the binary tree node. It is of type
|
||||
* `BinaryTreeNodeId`, which could be a string or a number, depending on how you want to identify your nodes.
|
||||
* @param {T | null} val - The `val` parameter represents the value to be stored in the binary tree node. It can be of
|
||||
* any type `T` or `null`.
|
||||
* @param {number} [count] - The count parameter is an optional parameter that represents the number of occurrences of
|
||||
* the value in the binary tree node. It is of type number.
|
||||
* @returns The function `createNode` returns a `BinaryTreeNode<T>` object if the `val` parameter is not null.
|
||||
* Otherwise, it returns null.
|
||||
* `BinaryTreeNodeId`.
|
||||
* @param {T | null} val - The `val` parameter represents the value of the node. It can be of type `T` (generic type)
|
||||
* or `null`.
|
||||
* @param {number} [count] - The `count` parameter is an optional parameter of type `number`. It represents the number
|
||||
* 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: T | null, count?: number): BinaryTreeNode<T> | null {
|
||||
return val !== null ? new BinaryTreeNode(id, val, count) : null;
|
||||
_createNode(id: BinaryTreeNodeId, val: T | null, count?: number): BinaryTreeNode<T> | null {
|
||||
return val !== null ? new BinaryTreeNode<T>(id, val, count) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -305,7 +312,7 @@ export class BinaryTree<T> {
|
|||
};
|
||||
|
||||
let inserted: BinaryTreeNode<T> | null | undefined;
|
||||
const needInsert = val !== null ? new BinaryTreeNode<T>(id, val, count) : null;
|
||||
const needInsert = val !== null ? this._createNode(id, val, count) : null;
|
||||
const existNode = val !== null ? this.get(id, 'id') : null;
|
||||
if (this.root) {
|
||||
if (existNode) {
|
||||
|
@ -319,7 +326,7 @@ export class BinaryTree<T> {
|
|||
inserted = _bfs(this.root, needInsert);
|
||||
}
|
||||
} else {
|
||||
this._setRoot(val !== null ? new BinaryTreeNode<T>(id, val, count) : null);
|
||||
this._setRoot(val !== null ? this._createNode(id, val, count) : null);
|
||||
if (needInsert !== null) {
|
||||
this._setSize(1);
|
||||
this._setCount(count);
|
||||
|
|
|
@ -7,16 +7,17 @@
|
|||
*/
|
||||
import type {BinaryTreeNodeId, BinaryTreeNodePropertyName, BSTComparator, BSTDeletedResult} from '../types';
|
||||
import {BinaryTree, BinaryTreeNode, FamilyPosition, LoopType,} from './binary-tree';
|
||||
import {IBinaryTree, IBinaryTreeNode} from '../interfaces';
|
||||
|
||||
export enum CP {lt = -1, eq = 0, gt = 1}
|
||||
|
||||
export class BSTNode<T> extends BinaryTreeNode<T> {
|
||||
override clone(): BSTNode<T> {
|
||||
return new BSTNode<T>(this.id, this.val, this.count);
|
||||
export class BSTNode<T> extends BinaryTreeNode<T> implements IBinaryTreeNode<T> {
|
||||
override _createNode(id: BinaryTreeNodeId, val: T | null, count?: number): BSTNode<T> | null {
|
||||
return val !== null ? new BSTNode<T>(id, val, count) : null;
|
||||
}
|
||||
}
|
||||
|
||||
export class BST<T> extends BinaryTree<T> {
|
||||
export class BST<T> extends BinaryTree<T> implements IBinaryTree<T> {
|
||||
/**
|
||||
* 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:
|
||||
|
@ -34,7 +35,7 @@ export class BST<T> extends BinaryTree<T> {
|
|||
}
|
||||
}
|
||||
|
||||
override createNode(id: BinaryTreeNodeId, val: T | null, count?: number): BSTNode<T> | null {
|
||||
override _createNode(id: BinaryTreeNodeId, val: T | null, count?: number): BSTNode<T> | null {
|
||||
return val !== null ? new BSTNode<T>(id, val, count) : null;
|
||||
}
|
||||
|
||||
|
@ -52,7 +53,7 @@ export class BST<T> extends BinaryTree<T> {
|
|||
*/
|
||||
override add(id: BinaryTreeNodeId, val: T | null, count: number = 1): BSTNode<T> | null {
|
||||
let inserted: BSTNode<T> | 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);
|
||||
|
|
|
@ -1,3 +1,110 @@
|
|||
export class RBTree {
|
||||
import {BinaryTree, BinaryTreeNode, LoopType} from './binary-tree';
|
||||
import {IBinaryTree, IBinaryTreeNode} from '../interfaces';
|
||||
|
||||
enum RBColor { Red, Black }
|
||||
|
||||
class RBNode<T> extends BinaryTreeNode<T> implements IBinaryTreeNode<T> {
|
||||
// override createNode(id: BinaryTreeNodeId, val: T | null, count?: number): RBNode<T> | null {
|
||||
// return val !== null ? new RBNode<T>(id, val, count) : null;
|
||||
// }
|
||||
|
||||
constructor(id: number, val: T, count?: number) {
|
||||
super(id, val, count);
|
||||
}
|
||||
|
||||
private _color: RBColor = RBColor.Red;
|
||||
|
||||
get color(): RBColor {
|
||||
return this._color;
|
||||
}
|
||||
|
||||
set color(value: RBColor) {
|
||||
this._color = value;
|
||||
}
|
||||
|
||||
// private override _parent: RBNode<T> | null;
|
||||
// override set parent(v: RBNode<T> | null) {
|
||||
// this._parent = v;
|
||||
// }
|
||||
// override get parent(): RBNode<T> | null {
|
||||
// return this._parent;
|
||||
// }
|
||||
// private override _left?: RBNode<T> | null;
|
||||
//
|
||||
// override get left(): RBNode<T> | null | undefined {
|
||||
// return this._left;
|
||||
// }
|
||||
//
|
||||
// override set left(v: RBNode<T> | null | undefined) {
|
||||
// if (v) {
|
||||
// v.parent = this;
|
||||
// v.familyPosition = FamilyPosition.left;
|
||||
// }
|
||||
// this._left = v;
|
||||
// }
|
||||
//
|
||||
// private override _right?: RBNode<T> | null;
|
||||
//
|
||||
// override get right(): RBNode<T> | null | undefined {
|
||||
// return this._right;
|
||||
// }
|
||||
//
|
||||
// override set right(v: RBNode<T> | null | undefined) {
|
||||
// if (v) {
|
||||
// v.parent = this;
|
||||
// v.familyPosition = FamilyPosition.right;
|
||||
// }
|
||||
// this._right = v;
|
||||
// }
|
||||
}
|
||||
|
||||
class RBTree<T> extends BinaryTree<T> implements IBinaryTree<T> {
|
||||
constructor(options?: {
|
||||
loopType?: LoopType,
|
||||
autoIncrementId?: boolean,
|
||||
isDuplicatedVal?: boolean
|
||||
}) {
|
||||
super(options);
|
||||
}
|
||||
|
||||
// override _createNode(id: BinaryTreeNodeId, val: T | null, count?: number): RBNode<T> | null {
|
||||
// return val !== null ? new RBNode<T>(id, val, count) : null;
|
||||
// }
|
||||
|
||||
// private override _root: BinaryTreeNode<T> | null = null;
|
||||
//
|
||||
// override get root(): BinaryTreeNode<T> | null {
|
||||
// return this._root;
|
||||
// }
|
||||
|
||||
insert(id: number, val: T | null) {
|
||||
|
||||
}
|
||||
|
||||
private leftRotate(node: RBNode<T>) {
|
||||
|
||||
}
|
||||
|
||||
private rightRotate(node: RBNode<T>) {
|
||||
|
||||
}
|
||||
|
||||
private insertFixup(node: RBNode<T>) {
|
||||
|
||||
}
|
||||
|
||||
private deleteFixup(node: RBNode<T>) {
|
||||
|
||||
}
|
||||
|
||||
private transplant(u: RBNode<T>, v: RBNode<T>) {
|
||||
|
||||
}
|
||||
|
||||
// override remove(id: BinaryTreeNodeId, ignoreCount?: boolean): BinaryTreeDeleted<T>[] {
|
||||
//
|
||||
// return [{deleted: new RBNode<T>(0, 0), needBalanced: null}];
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -7,8 +7,9 @@
|
|||
*/
|
||||
import {BST, BSTNode} from './bst';
|
||||
import type {BinaryTreeNodeId, TreeMultiSetDeletedResult} from '../types';
|
||||
import {IBinaryTree} from '../interfaces';
|
||||
|
||||
export class TreeMultiSet<T> extends BST<T> {
|
||||
export class TreeMultiSet<T> extends BST<T> implements IBinaryTree<T> {
|
||||
/**
|
||||
* The function creates a new BSTNode with the given id, value, and count.
|
||||
* @param {BinaryTreeNodeId} id - The id parameter is the unique identifier for the binary tree node. It is used to
|
||||
|
@ -18,7 +19,7 @@ export class TreeMultiSet<T> extends BST<T> {
|
|||
* 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: T, count?: number): BSTNode<T> {
|
||||
override _createNode(id: BinaryTreeNodeId, val: T, count?: number): BSTNode<T> {
|
||||
return new BSTNode<T>(id, val, count);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
*/
|
||||
import {arrayRemove, uuidV4} from '../../utils';
|
||||
import {PriorityQueue} from '../priority-queue';
|
||||
import type {DijkstraResult, IGraph, VertexId} from '../types';
|
||||
import type {DijkstraResult, VertexId} from '../types';
|
||||
import {IGraph} from '../interfaces';
|
||||
|
||||
export class AbstractVertex {
|
||||
constructor(id: VertexId) {
|
||||
|
@ -389,7 +390,7 @@ export abstract class AbstractGraph<V extends AbstractVertex, E extends Abstract
|
|||
* @returns The function `dijkstraWithoutHeap` returns an object of type `DijkstraResult<V>`.
|
||||
*/
|
||||
dijkstraWithoutHeap(src: V | VertexId, dest?: V | VertexId | null, getMinDist?: boolean, genPaths?: boolean): DijkstraResult<V> {
|
||||
if (getMinDist === undefined) getMinDist = false ;
|
||||
if (getMinDist === undefined) getMinDist = false;
|
||||
if (genPaths === undefined) genPaths = false;
|
||||
|
||||
if (dest === undefined) dest = null;
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
*/
|
||||
import {arrayRemove} from '../../utils';
|
||||
import {AbstractEdge, AbstractGraph, AbstractVertex} from './abstract-graph';
|
||||
import type {IDirectedGraph, TopologicalStatus, VertexId} from '../types';
|
||||
import type {TopologicalStatus, VertexId} from '../types';
|
||||
import {IDirectedGraph} from '../interfaces';
|
||||
|
||||
export class DirectedVertex extends AbstractVertex {
|
||||
/**
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
||||
* @license MIT License
|
||||
*/
|
||||
export class CoordinateSet extends Set {
|
||||
export class CoordinateSet extends Set<any> {
|
||||
constructor(joint?: string) {
|
||||
super();
|
||||
if (joint !== undefined) this._joint = joint;
|
||||
|
|
|
@ -9,6 +9,7 @@ export * from './heap';
|
|||
export * from './priority-queue';
|
||||
export * from './matrix';
|
||||
export * from './trie';
|
||||
export * from './interfaces';
|
||||
export * from './types';
|
||||
|
||||
|
||||
|
|
40
src/data-structures/interfaces/abstract-graph.ts
Normal file
40
src/data-structures/interfaces/abstract-graph.ts
Normal file
|
@ -0,0 +1,40 @@
|
|||
import {VertexId} from '../types';
|
||||
|
||||
export interface IGraph<V, E> {
|
||||
|
||||
hasVertex(vertexOrId: V | VertexId): boolean;
|
||||
|
||||
getVertex(vertexOrId: VertexId | V): V | null;
|
||||
|
||||
getVertexId(vertexOrId: V | VertexId): VertexId;
|
||||
|
||||
vertexSet(): Map<VertexId, V>;
|
||||
|
||||
addVertex(v: V): boolean;
|
||||
|
||||
removeVertex(vertexOrId: V | VertexId): boolean;
|
||||
|
||||
removeAllVertices(vertices: V[] | VertexId[]): boolean;
|
||||
|
||||
degreeOf(vertexOrId: V | VertexId): number;
|
||||
|
||||
edgesOf(vertexOrId: V | VertexId): E[];
|
||||
|
||||
hasEdge(src: V | VertexId, dest: V | VertexId): boolean;
|
||||
|
||||
getEdge(srcOrId: V | VertexId, destOrId: V | VertexId): E | null;
|
||||
|
||||
edgeSet(): E[];
|
||||
|
||||
addEdge(edge: E): boolean;
|
||||
|
||||
removeEdgeBetween(srcOrId: V | VertexId, destOrId: V | VertexId): E | null;
|
||||
|
||||
removeEdge(edge: E): E | null;
|
||||
|
||||
setEdgeWeight(srcOrId: V | VertexId, destOrId: V | VertexId, weight: number): boolean;
|
||||
|
||||
getMinPathBetween(v1: V | VertexId, v2: V | VertexId, isWeight?: boolean): V[] | null;
|
||||
|
||||
getNeighbors(vertexOrId: V | VertexId): V[];
|
||||
}
|
1
src/data-structures/interfaces/avl-tree.ts
Normal file
1
src/data-structures/interfaces/avl-tree.ts
Normal file
|
@ -0,0 +1 @@
|
|||
export {}
|
10
src/data-structures/interfaces/binary-tree.ts
Normal file
10
src/data-structures/interfaces/binary-tree.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
import {BinaryTreeNodeId} from '../types';
|
||||
import {BinaryTreeNode} from '../binary-tree';
|
||||
|
||||
export interface IBinaryTreeNode<T> {
|
||||
_createNode(id: BinaryTreeNodeId, val: T | null, count?: number): BinaryTreeNode<T> | null
|
||||
}
|
||||
|
||||
export interface IBinaryTree<T> {
|
||||
_createNode(id: BinaryTreeNodeId, val: T | null, count?: number): BinaryTreeNode<T> | null
|
||||
}
|
1
src/data-structures/interfaces/bst.ts
Normal file
1
src/data-structures/interfaces/bst.ts
Normal file
|
@ -0,0 +1 @@
|
|||
export {}
|
15
src/data-structures/interfaces/directed-graph.ts
Normal file
15
src/data-structures/interfaces/directed-graph.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
import {VertexId} from '../types';
|
||||
|
||||
export interface IDirectedGraph<V, E> {
|
||||
incomingEdgesOf(vertex: V): E[];
|
||||
|
||||
outgoingEdgesOf(vertex: V): E[];
|
||||
|
||||
inDegreeOf(vertexOrId: V | VertexId): number;
|
||||
|
||||
outDegreeOf(vertexOrId: V | VertexId): number;
|
||||
|
||||
getEdgeSrc(e: E): V | null;
|
||||
|
||||
getEdgeDest(e: E): V | null;
|
||||
}
|
1
src/data-structures/interfaces/doubly-linked-list.ts
Normal file
1
src/data-structures/interfaces/doubly-linked-list.ts
Normal file
|
@ -0,0 +1 @@
|
|||
export {}
|
1
src/data-structures/interfaces/heap.ts
Normal file
1
src/data-structures/interfaces/heap.ts
Normal file
|
@ -0,0 +1 @@
|
|||
export {}
|
13
src/data-structures/interfaces/index.ts
Normal file
13
src/data-structures/interfaces/index.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
export * from './binary-tree';
|
||||
export * from './bst';
|
||||
export * from './avl-tree';
|
||||
export * from './segment-tree';
|
||||
export * from './tree-multiset';
|
||||
export * from './abstract-graph';
|
||||
export * from './directed-graph';
|
||||
export * from './undirected-graph';
|
||||
export * from './priority-queue';
|
||||
export * from './heap';
|
||||
export * from './singly-linked-list';
|
||||
export * from './doubly-linked-list';
|
||||
export * from './navigator';
|
1
src/data-structures/interfaces/navigator.ts
Normal file
1
src/data-structures/interfaces/navigator.ts
Normal file
|
@ -0,0 +1 @@
|
|||
export {}
|
1
src/data-structures/interfaces/priority-queue.ts
Normal file
1
src/data-structures/interfaces/priority-queue.ts
Normal file
|
@ -0,0 +1 @@
|
|||
export {}
|
1
src/data-structures/interfaces/segment-tree.ts
Normal file
1
src/data-structures/interfaces/segment-tree.ts
Normal file
|
@ -0,0 +1 @@
|
|||
export {}
|
1
src/data-structures/interfaces/singly-linked-list.ts
Normal file
1
src/data-structures/interfaces/singly-linked-list.ts
Normal file
|
@ -0,0 +1 @@
|
|||
export {}
|
1
src/data-structures/interfaces/tree-multiset.ts
Normal file
1
src/data-structures/interfaces/tree-multiset.ts
Normal file
|
@ -0,0 +1 @@
|
|||
export {}
|
3
src/data-structures/interfaces/undirected-graph.ts
Normal file
3
src/data-structures/interfaces/undirected-graph.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
export interface IUNDirectedGraph<V, E> {
|
||||
|
||||
}
|
|
@ -49,7 +49,7 @@ export class DoublyLinkedListNode<T = number> {
|
|||
}
|
||||
}
|
||||
|
||||
export class DoublyLinkedList<T> {
|
||||
export class DoublyLinkedList<T = number> {
|
||||
|
||||
/**
|
||||
* The constructor initializes the linked list with an empty head, tail, and length.
|
||||
|
|
|
@ -38,7 +38,7 @@ export class SinglyLinkedListNode<T = number> {
|
|||
}
|
||||
}
|
||||
|
||||
export class SinglyLinkedList<T> {
|
||||
export class SinglyLinkedList<T = number> {
|
||||
|
||||
/**
|
||||
* The constructor initializes the linked list with an empty head, tail, and length.
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
* @license MIT License
|
||||
*/
|
||||
import {PriorityQueue} from './priority-queue';
|
||||
import type {PriorityQueueOptions, SpecifyOptional} from '../types';
|
||||
import type {PriorityQueueOptions} from '../types';
|
||||
import {SpecifyOptional} from '../../utils';
|
||||
|
||||
export class MaxPriorityQueue<T = number> extends PriorityQueue<T> {
|
||||
constructor(options?: Omit<PriorityQueueOptions<number>, 'comparator'>)
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
* @license MIT License
|
||||
*/
|
||||
import {PriorityQueue} from './priority-queue';
|
||||
import type {PriorityQueueOptions, SpecifyOptional} from '../types';
|
||||
import type {PriorityQueueOptions} from '../types';
|
||||
import {SpecifyOptional} from '../../utils';
|
||||
|
||||
export class MinPriorityQueue<T = number> extends PriorityQueue<T> {
|
||||
constructor(options?: Omit<PriorityQueueOptions<number>, 'comparator'>)
|
||||
|
|
|
@ -30,10 +30,6 @@ export class PriorityQueue<T = number> {
|
|||
return this._nodes;
|
||||
}
|
||||
|
||||
protected set nodes(value: T[]) {
|
||||
this._nodes = value;
|
||||
}
|
||||
|
||||
get size(): number {
|
||||
return this.nodes.length;
|
||||
}
|
||||
|
@ -137,7 +133,7 @@ export class PriorityQueue<T = number> {
|
|||
* The clear function clears the nodes array.
|
||||
*/
|
||||
clear() {
|
||||
this.nodes = [];
|
||||
this._setNodes([]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -231,6 +227,10 @@ export class PriorityQueue<T = number> {
|
|||
return visitedNode;
|
||||
}
|
||||
|
||||
protected _setNodes(value: T[]) {
|
||||
this._nodes = value;
|
||||
}
|
||||
|
||||
protected readonly _comparator: PriorityQueueComparator<T> = (a: T, b: T) => {
|
||||
const aKey = a as unknown as number, bKey = b as unknown as number;
|
||||
return aKey - bKey;
|
||||
|
|
|
@ -16,7 +16,7 @@ export class Deque<T> extends DoublyLinkedList<T> {
|
|||
// O(1) time complexity of obtaining the value
|
||||
// O(n) time complexity of adding at the beginning and the end
|
||||
// todo tested slowest one
|
||||
export class ObjectDeque<T> {
|
||||
export class ObjectDeque<T = number> {
|
||||
constructor(capacity?: number) {
|
||||
if (capacity !== undefined) this._capacity = capacity;
|
||||
}
|
||||
|
@ -27,10 +27,6 @@ export class ObjectDeque<T> {
|
|||
return this._nodes;
|
||||
}
|
||||
|
||||
protected set nodes(value: { [p: number]: T }) {
|
||||
this._nodes = value;
|
||||
}
|
||||
|
||||
private _capacity = Number.MAX_SAFE_INTEGER;
|
||||
|
||||
get capacity(): number {
|
||||
|
@ -67,10 +63,6 @@ export class ObjectDeque<T> {
|
|||
return this._size;
|
||||
}
|
||||
|
||||
protected set size(value: number) {
|
||||
this._size = value;
|
||||
}
|
||||
|
||||
addFirst(value: T) {
|
||||
if (this._size === 0) {
|
||||
const mid = Math.floor(this._capacity / 2);
|
||||
|
@ -129,6 +121,14 @@ export class ObjectDeque<T> {
|
|||
isEmpty() {
|
||||
return this._size <= 0;
|
||||
}
|
||||
|
||||
protected _seNodes(value: { [p: number]: T }) {
|
||||
this._nodes = value;
|
||||
}
|
||||
|
||||
protected _setSize(value: number) {
|
||||
this._size = value;
|
||||
}
|
||||
}
|
||||
|
||||
// O(1) time complexity of obtaining the value
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* @copyright Tyler Zeng <zrwusa@gmail.com>
|
||||
* @class
|
||||
*/
|
||||
export class Queue<T> {
|
||||
export class Queue<T = number> {
|
||||
protected _nodes: T[];
|
||||
protected _offset: number;
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* @copyright Tyler Zeng <zrwusa@gmail.com>
|
||||
* @class
|
||||
*/
|
||||
export class Stack<T> {
|
||||
export class Stack<T = number> {
|
||||
protected _elements: T[];
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,50 +2,3 @@ export type VertexId = string | number;
|
|||
export type DijkstraResult<V> =
|
||||
{ distMap: Map<V, number>, preMap: Map<V, V | null>, seen: Set<V>, paths: V[][], minDist: number, minPath: V[] }
|
||||
| null;
|
||||
|
||||
export interface IGraph<V, E> {
|
||||
|
||||
hasVertex(vertexOrId: V | VertexId): boolean;
|
||||
|
||||
getVertex(vertexOrId: VertexId | V): V | null;
|
||||
|
||||
getVertexId(vertexOrId: V | VertexId): VertexId;
|
||||
|
||||
vertexSet(): Map<VertexId, V>;
|
||||
|
||||
addVertex(v: V): boolean;
|
||||
|
||||
removeVertex(vertexOrId: V | VertexId): boolean;
|
||||
|
||||
removeAllVertices(vertices: V[] | VertexId[]): boolean;
|
||||
|
||||
degreeOf(vertexOrId: V | VertexId): number;
|
||||
|
||||
edgesOf(vertexOrId: V | VertexId): E[];
|
||||
|
||||
hasEdge(src: V | VertexId, dest: V | VertexId): boolean;
|
||||
|
||||
// hasEdge(e: E): boolean;
|
||||
|
||||
getEdge(srcOrId: V | VertexId, destOrId: V | VertexId): E | null;
|
||||
|
||||
// getAllEdges(src: V, dest: V): E[];
|
||||
|
||||
edgeSet(): E[];
|
||||
|
||||
addEdge(edge: E): boolean;
|
||||
|
||||
removeEdgeBetween(srcOrId: V | VertexId, destOrId: V | VertexId): E | null;
|
||||
|
||||
removeEdge(edge: E): E | null;
|
||||
|
||||
// removeAllEdges(v1: VertexId | V, v2: VertexId | V): (E | null)[];
|
||||
|
||||
// removeAllEdges(edges: E[] | [VertexId, VertexId]): boolean;
|
||||
|
||||
setEdgeWeight(srcOrId: V | VertexId, destOrId: V | VertexId, weight: number): boolean;
|
||||
|
||||
getMinPathBetween(v1: V | VertexId, v2: V | VertexId, isWeight?: boolean): V[] | null;
|
||||
|
||||
getNeighbors(vertexOrId: V | VertexId): V[];
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
import {AVLTreeNode} from '../binary-tree';
|
||||
|
||||
export interface AVLTreeDeleted<T> {
|
||||
export type AVLTreeDeleted<T> = {
|
||||
deleted: AVLTreeNode<T> | null;
|
||||
needBalanced: AVLTreeNode<T> | null;
|
||||
}
|
|
@ -1,18 +1,8 @@
|
|||
import {VertexId} from './abstract-graph';
|
||||
|
||||
export interface IDirectedGraph<V, E> {
|
||||
incomingEdgesOf(vertex: V): E[];
|
||||
|
||||
outgoingEdgesOf(vertex: V): E[];
|
||||
|
||||
inDegreeOf(vertexOrId: V | VertexId): number;
|
||||
|
||||
outDegreeOf(vertexOrId: V | VertexId): number;
|
||||
|
||||
getEdgeSrc(e: E): V | null;
|
||||
|
||||
getEdgeDest(e: E): V | null;
|
||||
}
|
||||
|
||||
// 0 means unknown, 1 means visiting, 2 means visited;
|
||||
export type TopologicalStatus = 0 | 1 | 2;
|
||||
export type TopologicalStatus = 0 | 1 | 2;
|
||||
|
||||
export enum TopologicalProperty {
|
||||
VAL = 'VAL',
|
||||
NODE = 'NODE',
|
||||
ID = 'ID',
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
export interface HeapOptions<T> {
|
||||
export type HeapOptions<T> = {
|
||||
priority?: (element: T) => number;
|
||||
// TODO there is an idea that support chaining which is for conveniently using the data structure
|
||||
// isChaining? : boolean
|
||||
|
|
|
@ -9,5 +9,4 @@ export * from './priority-queue';
|
|||
export * from './heap';
|
||||
export * from './singly-linked-list';
|
||||
export * from './doubly-linked-list';
|
||||
export * from './navigator';
|
||||
export * from '../../utils/types/utils';
|
||||
export * from './navigator';
|
|
@ -1,7 +1,7 @@
|
|||
export type Direction = 'up' | 'right' | 'down' | 'left';
|
||||
export type Turning = { [key in Direction]: Direction };
|
||||
|
||||
export interface NavigatorParams<T> {
|
||||
export type NavigatorParams<T> = {
|
||||
matrix: T[][],
|
||||
turning: Turning,
|
||||
onMove: (cur: [number, number]) => void
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
export type PriorityQueueComparator<T> = (a: T, b: T) => number;
|
||||
|
||||
export interface PriorityQueueOptions<T> {
|
||||
export type PriorityQueueOptions<T> = {
|
||||
nodes?: T[];
|
||||
isFix?: boolean;
|
||||
comparator: PriorityQueueComparator<T>;
|
||||
|
|
|
@ -59,7 +59,7 @@ describe('DirectedGraph Operation Test', () => {
|
|||
graph.addEdge(edgeBC);
|
||||
|
||||
const topologicalOrder = graph.topologicalSort();
|
||||
if (topologicalOrder) expect(topologicalOrder.map(v => v.id)).toEqual(['A', 'B', 'C']);
|
||||
if (topologicalOrder) expect(topologicalOrder.map(v => v instanceof DirectedVertex ? v.id: '')).toEqual(['A', 'B', 'C']);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -168,9 +168,9 @@ describe('DirectedGraph Test2 operations', () => {
|
|||
expect(sorted).toBeInstanceOf(Array);
|
||||
if (sorted && sorted.length > 0) {
|
||||
expect(sorted.length).toBe(9);
|
||||
expect(sorted[0].data).toBe('data9');
|
||||
expect(sorted[3].data).toBe('data6');
|
||||
expect(sorted[8].id).toBe(1);
|
||||
if (sorted[0] instanceof MyVertex) expect(sorted[0].data).toBe('data9');
|
||||
sorted[3] instanceof MyVertex && expect(sorted[3].data).toBe('data6');
|
||||
sorted[8] instanceof MyVertex && expect(sorted[8].id).toBe(1);
|
||||
}
|
||||
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue