mirror of
https://github.com/zrwusa/data-structure-typed.git
synced 2024-11-23 12:54:04 +00:00
[core] Besides Binary Trees and Graphs, access control optimizations have been applied to member variables.
This commit is contained in:
parent
3009c14c24
commit
1ec5a19172
|
@ -60,8 +60,4 @@ export class CoordinateMap<V> extends Map<any, V> {
|
|||
override delete(key: number[]) {
|
||||
return super.delete(key.join(this._joint));
|
||||
}
|
||||
|
||||
protected _setJoint(v: string) {
|
||||
this._joint = v;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,8 +49,4 @@ export class CoordinateSet extends Set<any> {
|
|||
override delete(value: number[]) {
|
||||
return super.delete(value.join(this._joint));
|
||||
}
|
||||
|
||||
protected _setJoint(v: string) {
|
||||
this._joint = v;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,66 +38,42 @@ export class HashMap<K, V> {
|
|||
});
|
||||
}
|
||||
|
||||
private _initialCapacity: number;
|
||||
protected _initialCapacity: number;
|
||||
|
||||
get initialCapacity(): number {
|
||||
return this._initialCapacity;
|
||||
}
|
||||
|
||||
set initialCapacity(value: number) {
|
||||
this._initialCapacity = value;
|
||||
}
|
||||
|
||||
private _loadFactor: number;
|
||||
protected _loadFactor: number;
|
||||
|
||||
get loadFactor(): number {
|
||||
return this._loadFactor;
|
||||
}
|
||||
|
||||
set loadFactor(value: number) {
|
||||
this._loadFactor = value;
|
||||
}
|
||||
|
||||
private _capacityMultiplier: number;
|
||||
protected _capacityMultiplier: number;
|
||||
|
||||
get capacityMultiplier(): number {
|
||||
return this._capacityMultiplier;
|
||||
}
|
||||
|
||||
set capacityMultiplier(value: number) {
|
||||
this._capacityMultiplier = value;
|
||||
}
|
||||
|
||||
private _size: number;
|
||||
protected _size: number;
|
||||
|
||||
get size(): number {
|
||||
return this._size;
|
||||
}
|
||||
|
||||
set size(value: number) {
|
||||
this._size = value;
|
||||
}
|
||||
|
||||
private _table: Array<Array<[K, V]>>;
|
||||
protected _table: Array<Array<[K, V]>>;
|
||||
|
||||
get table(): Array<Array<[K, V]>> {
|
||||
return this._table;
|
||||
}
|
||||
|
||||
set table(value: Array<Array<[K, V]>>) {
|
||||
this._table = value;
|
||||
}
|
||||
|
||||
private _hashFn: HashFunction<K>;
|
||||
protected _hashFn: HashFunction<K>;
|
||||
|
||||
get hashFn(): HashFunction<K> {
|
||||
return this._hashFn;
|
||||
}
|
||||
|
||||
set hashFn(value: HashFunction<K>) {
|
||||
this._hashFn = value;
|
||||
}
|
||||
|
||||
set(key: K, value: V): void {
|
||||
const loadFactor = this.size / this.table.length;
|
||||
if (loadFactor >= this.loadFactor) {
|
||||
|
@ -118,7 +94,7 @@ export class HashMap<K, V> {
|
|||
}
|
||||
|
||||
this.table[index].push([key, value]);
|
||||
this.size++;
|
||||
this._size++;
|
||||
}
|
||||
|
||||
get(key: K): V | undefined {
|
||||
|
@ -145,7 +121,7 @@ export class HashMap<K, V> {
|
|||
for (let i = 0; i < this.table[index].length; i++) {
|
||||
if (this.table[index][i][0] === key) {
|
||||
this.table[index].splice(i, 1);
|
||||
this.size--;
|
||||
this._size--;
|
||||
|
||||
// Check if the table needs to be resized down
|
||||
const loadFactor = this.size / this.table.length;
|
||||
|
@ -172,15 +148,15 @@ export class HashMap<K, V> {
|
|||
}
|
||||
|
||||
clear(): void {
|
||||
this.size = 0;
|
||||
this.table = new Array(this.initialCapacity);
|
||||
this._size = 0;
|
||||
this._table = new Array(this.initialCapacity);
|
||||
}
|
||||
|
||||
isEmpty(): boolean {
|
||||
return this.size === 0;
|
||||
}
|
||||
|
||||
private _hash(key: K): number {
|
||||
protected _hash(key: K): number {
|
||||
return this._hashFn(key);
|
||||
}
|
||||
|
||||
|
@ -190,7 +166,7 @@ export class HashMap<K, V> {
|
|||
* @param {number} newCapacity - The newCapacity parameter is the desired capacity for the resized table. It represents
|
||||
* the number of buckets that the new table should have.
|
||||
*/
|
||||
private resizeTable(newCapacity: number): void {
|
||||
protected resizeTable(newCapacity: number): void {
|
||||
const newTable = new Array(newCapacity);
|
||||
for (const bucket of this._table) {
|
||||
// Note that this is this._table
|
||||
|
|
|
@ -21,8 +21,8 @@ export class HashTableNode<K, V> {
|
|||
import {HashFunction} from '../../types';
|
||||
|
||||
export class HashTable<K, V> {
|
||||
private static readonly DEFAULT_CAPACITY = 16;
|
||||
private static readonly LOAD_FACTOR = 0.75;
|
||||
protected static readonly DEFAULT_CAPACITY = 16;
|
||||
protected static readonly LOAD_FACTOR = 0.75;
|
||||
|
||||
constructor(capacity: number = HashTable.DEFAULT_CAPACITY, hashFn?: HashFunction<K>) {
|
||||
this._hashFn = hashFn || this._defaultHashFn;
|
||||
|
@ -31,42 +31,30 @@ export class HashTable<K, V> {
|
|||
this._buckets = new Array<HashTableNode<K, V> | null>(this._capacity).fill(null);
|
||||
}
|
||||
|
||||
private _capacity: number;
|
||||
protected _capacity: number;
|
||||
|
||||
get capacity(): number {
|
||||
return this._capacity;
|
||||
}
|
||||
|
||||
set capacity(value: number) {
|
||||
this._capacity = value;
|
||||
}
|
||||
|
||||
private _size: number;
|
||||
protected _size: number;
|
||||
|
||||
get size(): number {
|
||||
return this._size;
|
||||
}
|
||||
|
||||
private _buckets: Array<HashTableNode<K, V> | null>;
|
||||
protected _buckets: Array<HashTableNode<K, V> | null>;
|
||||
|
||||
get buckets(): Array<HashTableNode<K, V> | null> {
|
||||
return this._buckets;
|
||||
}
|
||||
|
||||
set buckets(value: Array<HashTableNode<K, V> | null>) {
|
||||
this._buckets = value;
|
||||
}
|
||||
|
||||
private _hashFn: HashFunction<K>;
|
||||
protected _hashFn: HashFunction<K>;
|
||||
|
||||
get hashFn(): HashFunction<K> {
|
||||
return this._hashFn;
|
||||
}
|
||||
|
||||
set hashFn(value: HashFunction<K>) {
|
||||
this._hashFn = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* The set function adds a key-value pair to the hash table, handling collisions and resizing if necessary.
|
||||
* @param {K} key - The key parameter represents the key of the key-value pair that you want to insert into the hash
|
||||
|
|
|
@ -8,17 +8,26 @@
|
|||
import type {Comparator, DFSOrderPattern} from '../../types';
|
||||
|
||||
export class Heap<E = any> {
|
||||
protected nodes: E[] = [];
|
||||
protected readonly comparator: Comparator<E>;
|
||||
|
||||
constructor(options: {comparator: Comparator<E>; nodes?: E[]}) {
|
||||
this.comparator = options.comparator;
|
||||
this._comparator = options.comparator;
|
||||
if (options.nodes && options.nodes.length > 0) {
|
||||
this.nodes = options.nodes;
|
||||
this._nodes = options.nodes;
|
||||
this.fix();
|
||||
}
|
||||
}
|
||||
|
||||
protected _nodes: E[] = [];
|
||||
|
||||
get nodes(): E[] {
|
||||
return this._nodes;
|
||||
}
|
||||
|
||||
protected _comparator: Comparator<E>;
|
||||
|
||||
get comparator(): Comparator<E> {
|
||||
return this._comparator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the size (number of elements) of the heap.
|
||||
*/
|
||||
|
@ -110,7 +119,7 @@ export class Heap<E = any> {
|
|||
* Reset the nodes of the heap. Make the nodes empty.
|
||||
*/
|
||||
clear() {
|
||||
this.nodes = [];
|
||||
this._nodes = [];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -118,7 +127,7 @@ export class Heap<E = any> {
|
|||
* @param nodes
|
||||
*/
|
||||
refill(nodes: E[]) {
|
||||
this.nodes = nodes;
|
||||
this._nodes = nodes;
|
||||
this.fix();
|
||||
}
|
||||
|
||||
|
@ -181,7 +190,7 @@ export class Heap<E = any> {
|
|||
*/
|
||||
clone(): Heap<E> {
|
||||
const clonedHeap = new Heap<E>({comparator: this.comparator});
|
||||
clonedHeap.nodes = [...this.nodes];
|
||||
clonedHeap._nodes = [...this.nodes];
|
||||
return clonedHeap;
|
||||
}
|
||||
|
||||
|
@ -268,28 +277,47 @@ export class FibonacciHeapNode<E> {
|
|||
}
|
||||
|
||||
export class FibonacciHeap<E> {
|
||||
root?: FibonacciHeapNode<E>;
|
||||
size = 0;
|
||||
protected min?: FibonacciHeapNode<E>;
|
||||
protected readonly comparator: Comparator<E>;
|
||||
|
||||
constructor(comparator?: Comparator<E>) {
|
||||
this.clear();
|
||||
this.comparator = comparator || this.defaultComparator;
|
||||
this._comparator = comparator || this.defaultComparator;
|
||||
|
||||
if (typeof this.comparator !== 'function') {
|
||||
throw new Error('FibonacciHeap constructor: given comparator should be a function.');
|
||||
}
|
||||
}
|
||||
|
||||
protected _root?: FibonacciHeapNode<E>;
|
||||
|
||||
get root(): FibonacciHeapNode<E> | undefined {
|
||||
return this._root;
|
||||
}
|
||||
|
||||
protected _size = 0;
|
||||
|
||||
get size(): number {
|
||||
return this._size;
|
||||
}
|
||||
|
||||
protected _min?: FibonacciHeapNode<E>;
|
||||
|
||||
get min(): FibonacciHeapNode<E> | undefined {
|
||||
return this._min;
|
||||
}
|
||||
|
||||
protected _comparator: Comparator<E>;
|
||||
|
||||
get comparator(): Comparator<E> {
|
||||
return this._comparator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the size (number of elements) of the heap.
|
||||
* @returns {number} The size of the heap. Returns 0 if the heap is empty. Returns -1 if the heap is invalid.
|
||||
*/
|
||||
clear(): void {
|
||||
this.root = undefined;
|
||||
this.min = undefined;
|
||||
this.size = 0;
|
||||
this._root = undefined;
|
||||
this._min = undefined;
|
||||
this._size = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -315,10 +343,10 @@ export class FibonacciHeap<E> {
|
|||
this.mergeWithRoot(node);
|
||||
|
||||
if (!this.min || this.comparator(node.element, this.min.element) <= 0) {
|
||||
this.min = node;
|
||||
this._min = node;
|
||||
}
|
||||
|
||||
this.size++;
|
||||
this._size++;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -405,14 +433,14 @@ export class FibonacciHeap<E> {
|
|||
this.removeFromRoot(z);
|
||||
|
||||
if (z === z.right) {
|
||||
this.min = undefined;
|
||||
this.root = undefined;
|
||||
this._min = undefined;
|
||||
this._root = undefined;
|
||||
} else {
|
||||
this.min = z.right;
|
||||
this._min = z.right;
|
||||
this.consolidate();
|
||||
}
|
||||
|
||||
this.size--;
|
||||
this._size--;
|
||||
|
||||
return z.element;
|
||||
}
|
||||
|
@ -444,11 +472,11 @@ export class FibonacciHeap<E> {
|
|||
|
||||
// Update the minimum node
|
||||
if (!this.min || (heapToMerge.min && this.comparator(heapToMerge.min.element, this.min.element) < 0)) {
|
||||
this.min = heapToMerge.min;
|
||||
this._min = heapToMerge.min;
|
||||
}
|
||||
|
||||
// Update the size
|
||||
this.size += heapToMerge.size;
|
||||
this._size += heapToMerge.size;
|
||||
|
||||
// Clear the heap that was merged
|
||||
heapToMerge.clear();
|
||||
|
@ -481,7 +509,7 @@ export class FibonacciHeap<E> {
|
|||
*/
|
||||
protected mergeWithRoot(node: FibonacciHeapNode<E>): void {
|
||||
if (!this.root) {
|
||||
this.root = node;
|
||||
this._root = node;
|
||||
} else {
|
||||
node.right = this.root.right;
|
||||
node.left = this.root;
|
||||
|
@ -497,7 +525,7 @@ export class FibonacciHeap<E> {
|
|||
* @protected
|
||||
*/
|
||||
protected removeFromRoot(node: FibonacciHeapNode<E>): void {
|
||||
if (this.root === node) this.root = node.right;
|
||||
if (this.root === node) this._root = node.right;
|
||||
if (node.left) node.left.right = node.right;
|
||||
if (node.right) node.right.left = node.left;
|
||||
}
|
||||
|
@ -554,7 +582,7 @@ export class FibonacciHeap<E> {
|
|||
|
||||
for (let i = 0; i < this.size; i++) {
|
||||
if (A[i] && this.comparator(A[i]!.element, this.min!.element) <= 0) {
|
||||
this.min = A[i]!;
|
||||
this._min = A[i]!;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,45 +6,19 @@
|
|||
* @license MIT License
|
||||
*/
|
||||
export class DoublyLinkedListNode<E = any> {
|
||||
value: E;
|
||||
next: DoublyLinkedListNode<E> | null;
|
||||
prev: DoublyLinkedListNode<E> | null;
|
||||
|
||||
/**
|
||||
* The constructor function initializes the value, next, and previous properties of an object.
|
||||
* @param {E} value - The "value" parameter is the value that will be stored in the node. It can be of any data type, as it
|
||||
* is defined as a generic type "E".
|
||||
*/
|
||||
constructor(value: E) {
|
||||
this._value = value;
|
||||
this._next = null;
|
||||
this._prev = null;
|
||||
}
|
||||
|
||||
private _value: E;
|
||||
|
||||
get value(): E {
|
||||
return this._value;
|
||||
}
|
||||
|
||||
set value(value: E) {
|
||||
this._value = value;
|
||||
}
|
||||
|
||||
private _next: DoublyLinkedListNode<E> | null;
|
||||
|
||||
get next(): DoublyLinkedListNode<E> | null {
|
||||
return this._next;
|
||||
}
|
||||
|
||||
set next(value: DoublyLinkedListNode<E> | null) {
|
||||
this._next = value;
|
||||
}
|
||||
|
||||
private _prev: DoublyLinkedListNode<E> | null;
|
||||
|
||||
get prev(): DoublyLinkedListNode<E> | null {
|
||||
return this._prev;
|
||||
}
|
||||
|
||||
set prev(value: DoublyLinkedListNode<E> | null) {
|
||||
this._prev = value;
|
||||
this.value = value;
|
||||
this.next = null;
|
||||
this.prev = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -58,27 +32,19 @@ export class DoublyLinkedList<E = any> {
|
|||
this._length = 0;
|
||||
}
|
||||
|
||||
private _head: DoublyLinkedListNode<E> | null;
|
||||
protected _head: DoublyLinkedListNode<E> | null;
|
||||
|
||||
get head(): DoublyLinkedListNode<E> | null {
|
||||
return this._head;
|
||||
}
|
||||
|
||||
set head(value: DoublyLinkedListNode<E> | null) {
|
||||
this._head = value;
|
||||
}
|
||||
|
||||
private _tail: DoublyLinkedListNode<E> | null;
|
||||
protected _tail: DoublyLinkedListNode<E> | null;
|
||||
|
||||
get tail(): DoublyLinkedListNode<E> | null {
|
||||
return this._tail;
|
||||
}
|
||||
|
||||
set tail(value: DoublyLinkedListNode<E> | null) {
|
||||
this._tail = value;
|
||||
}
|
||||
|
||||
private _length: number;
|
||||
protected _length: number;
|
||||
|
||||
get length(): number {
|
||||
return this._length;
|
||||
|
@ -109,12 +75,12 @@ export class DoublyLinkedList<E = any> {
|
|||
push(value: E): void {
|
||||
const newNode = new DoublyLinkedListNode(value);
|
||||
if (!this.head) {
|
||||
this.head = newNode;
|
||||
this.tail = newNode;
|
||||
this._head = newNode;
|
||||
this._tail = newNode;
|
||||
} else {
|
||||
newNode.prev = this.tail;
|
||||
this.tail!.next = newNode;
|
||||
this.tail = newNode;
|
||||
this._tail = newNode;
|
||||
}
|
||||
this._length++;
|
||||
}
|
||||
|
@ -136,10 +102,10 @@ export class DoublyLinkedList<E = any> {
|
|||
if (!this.tail) return undefined;
|
||||
const removedNode = this.tail;
|
||||
if (this.head === this.tail) {
|
||||
this.head = null;
|
||||
this.tail = null;
|
||||
this._head = null;
|
||||
this._tail = null;
|
||||
} else {
|
||||
this.tail = removedNode.prev;
|
||||
this._tail = removedNode.prev;
|
||||
this.tail!.next = null;
|
||||
}
|
||||
this._length--;
|
||||
|
@ -164,10 +130,10 @@ export class DoublyLinkedList<E = any> {
|
|||
if (!this.head) return undefined;
|
||||
const removedNode = this.head;
|
||||
if (this.head === this.tail) {
|
||||
this.head = null;
|
||||
this.tail = null;
|
||||
this._head = null;
|
||||
this._tail = null;
|
||||
} else {
|
||||
this.head = removedNode.next;
|
||||
this._head = removedNode.next;
|
||||
this.head!.prev = null;
|
||||
}
|
||||
this._length--;
|
||||
|
@ -191,12 +157,12 @@ export class DoublyLinkedList<E = any> {
|
|||
unshift(value: E): void {
|
||||
const newNode = new DoublyLinkedListNode(value);
|
||||
if (!this.head) {
|
||||
this.head = newNode;
|
||||
this.tail = newNode;
|
||||
this._head = newNode;
|
||||
this._tail = newNode;
|
||||
} else {
|
||||
newNode.next = this.head;
|
||||
this.head!.prev = newNode;
|
||||
this.head = newNode;
|
||||
this._head = newNode;
|
||||
}
|
||||
this._length++;
|
||||
}
|
||||
|
@ -338,7 +304,7 @@ export class DoublyLinkedList<E = any> {
|
|||
newNode.next = existingNode;
|
||||
existingNode.prev = newNode;
|
||||
if (existingNode === this.head) {
|
||||
this.head = newNode;
|
||||
this._head = newNode;
|
||||
}
|
||||
this._length++;
|
||||
return true;
|
||||
|
@ -508,7 +474,7 @@ export class DoublyLinkedList<E = any> {
|
|||
*/
|
||||
reverse(): void {
|
||||
let current = this.head;
|
||||
[this.head, this.tail] = [this.tail, this.head];
|
||||
[this._head, this._tail] = [this.tail, this.head];
|
||||
while (current) {
|
||||
const next = current.next;
|
||||
[current.prev, current.next] = [current.next, current.prev];
|
||||
|
@ -616,7 +582,7 @@ export class DoublyLinkedList<E = any> {
|
|||
newNode.prev = existingNode;
|
||||
existingNode.next = newNode;
|
||||
if (existingNode === this.tail) {
|
||||
this.tail = newNode;
|
||||
this._tail = newNode;
|
||||
}
|
||||
this._length++;
|
||||
return true;
|
||||
|
|
|
@ -6,34 +6,17 @@
|
|||
* @license MIT License
|
||||
*/
|
||||
export class SinglyLinkedListNode<E = any> {
|
||||
value: E;
|
||||
next: SinglyLinkedListNode<E> | null;
|
||||
|
||||
/**
|
||||
* The constructor function initializes an instance of a class with a given value and sets the next property to null.
|
||||
* @param {E} value - The "value" parameter is of type E, which means it can be any data type. It represents the value that
|
||||
* will be stored in the node of a linked list.
|
||||
*/
|
||||
constructor(value: E) {
|
||||
this._value = value;
|
||||
this._next = null;
|
||||
}
|
||||
|
||||
private _value: E;
|
||||
|
||||
get value(): E {
|
||||
return this._value;
|
||||
}
|
||||
|
||||
set value(value: E) {
|
||||
this._value = value;
|
||||
}
|
||||
|
||||
private _next: SinglyLinkedListNode<E> | null;
|
||||
|
||||
get next(): SinglyLinkedListNode<E> | null {
|
||||
return this._next;
|
||||
}
|
||||
|
||||
set next(value: SinglyLinkedListNode<E> | null) {
|
||||
this._next = value;
|
||||
this.value = value;
|
||||
this.next = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,27 +30,19 @@ export class SinglyLinkedList<E = any> {
|
|||
this._length = 0;
|
||||
}
|
||||
|
||||
private _head: SinglyLinkedListNode<E> | null;
|
||||
protected _head: SinglyLinkedListNode<E> | null;
|
||||
|
||||
get head(): SinglyLinkedListNode<E> | null {
|
||||
return this._head;
|
||||
}
|
||||
|
||||
set head(value: SinglyLinkedListNode<E> | null) {
|
||||
this._head = value;
|
||||
}
|
||||
|
||||
private _tail: SinglyLinkedListNode<E> | null;
|
||||
protected _tail: SinglyLinkedListNode<E> | null;
|
||||
|
||||
get tail(): SinglyLinkedListNode<E> | null {
|
||||
return this._tail;
|
||||
}
|
||||
|
||||
set tail(value: SinglyLinkedListNode<E> | null) {
|
||||
this._tail = value;
|
||||
}
|
||||
|
||||
private _length: number;
|
||||
protected _length: number;
|
||||
|
||||
get length(): number {
|
||||
return this._length;
|
||||
|
@ -95,11 +70,11 @@ export class SinglyLinkedList<E = any> {
|
|||
push(value: E): void {
|
||||
const newNode = new SinglyLinkedListNode(value);
|
||||
if (!this.head) {
|
||||
this.head = newNode;
|
||||
this.tail = newNode;
|
||||
this._head = newNode;
|
||||
this._tail = newNode;
|
||||
} else {
|
||||
this.tail!.next = newNode;
|
||||
this.tail = newNode;
|
||||
this._tail = newNode;
|
||||
}
|
||||
this._length++;
|
||||
}
|
||||
|
@ -123,8 +98,8 @@ export class SinglyLinkedList<E = any> {
|
|||
if (!this.head) return undefined;
|
||||
if (this.head === this.tail) {
|
||||
const value = this.head.value;
|
||||
this.head = null;
|
||||
this.tail = null;
|
||||
this._head = null;
|
||||
this._tail = null;
|
||||
this._length--;
|
||||
return value;
|
||||
}
|
||||
|
@ -135,7 +110,7 @@ export class SinglyLinkedList<E = any> {
|
|||
}
|
||||
const value = this.tail!.value;
|
||||
current.next = null;
|
||||
this.tail = current;
|
||||
this._tail = current;
|
||||
this._length--;
|
||||
return value;
|
||||
}
|
||||
|
@ -157,7 +132,7 @@ export class SinglyLinkedList<E = any> {
|
|||
shift(): E | undefined {
|
||||
if (!this.head) return undefined;
|
||||
const removedNode = this.head;
|
||||
this.head = this.head.next;
|
||||
this._head = this.head.next;
|
||||
this._length--;
|
||||
return removedNode.value;
|
||||
}
|
||||
|
@ -178,11 +153,11 @@ export class SinglyLinkedList<E = any> {
|
|||
unshift(value: E): void {
|
||||
const newNode = new SinglyLinkedListNode(value);
|
||||
if (!this.head) {
|
||||
this.head = newNode;
|
||||
this.tail = newNode;
|
||||
this._head = newNode;
|
||||
this._tail = newNode;
|
||||
} else {
|
||||
newNode.next = this.head;
|
||||
this.head = newNode;
|
||||
this._head = newNode;
|
||||
}
|
||||
this._length++;
|
||||
}
|
||||
|
@ -267,14 +242,14 @@ export class SinglyLinkedList<E = any> {
|
|||
while (current) {
|
||||
if (current.value === value) {
|
||||
if (prev === null) {
|
||||
this.head = current.next;
|
||||
this._head = current.next;
|
||||
if (current === this.tail) {
|
||||
this.tail = null;
|
||||
this._tail = null;
|
||||
}
|
||||
} else {
|
||||
prev.next = current.next;
|
||||
if (current === this.tail) {
|
||||
this.tail = prev;
|
||||
this._tail = prev;
|
||||
}
|
||||
}
|
||||
this._length--;
|
||||
|
@ -365,7 +340,7 @@ export class SinglyLinkedList<E = any> {
|
|||
current = next;
|
||||
}
|
||||
|
||||
[this.head, this.tail] = [this.tail!, this.head!];
|
||||
[this._head, this._tail] = [this.tail!, this.head!];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -486,7 +461,7 @@ export class SinglyLinkedList<E = any> {
|
|||
newNode.next = existingNode.next;
|
||||
existingNode.next = newNode;
|
||||
if (existingNode === this.tail) {
|
||||
this.tail = newNode;
|
||||
this._tail = newNode;
|
||||
}
|
||||
this._length++;
|
||||
return true;
|
||||
|
|
|
@ -33,46 +33,30 @@ export class SkipList<K, V> {
|
|||
this._probability = probability;
|
||||
}
|
||||
|
||||
private _head: SkipListNode<K, V>;
|
||||
protected _head: SkipListNode<K, V>;
|
||||
|
||||
get head(): SkipListNode<K, V> {
|
||||
return this._head;
|
||||
}
|
||||
|
||||
set head(value: SkipListNode<K, V>) {
|
||||
this._head = value;
|
||||
}
|
||||
|
||||
private _level: number;
|
||||
protected _level: number;
|
||||
|
||||
get level(): number {
|
||||
return this._level;
|
||||
}
|
||||
|
||||
set level(value: number) {
|
||||
this._level = value;
|
||||
}
|
||||
|
||||
private _maxLevel: number;
|
||||
protected _maxLevel: number;
|
||||
|
||||
get maxLevel(): number {
|
||||
return this._maxLevel;
|
||||
}
|
||||
|
||||
set maxLevel(value: number) {
|
||||
this._maxLevel = value;
|
||||
}
|
||||
|
||||
private _probability: number;
|
||||
protected _probability: number;
|
||||
|
||||
get probability(): number {
|
||||
return this._probability;
|
||||
}
|
||||
|
||||
set probability(value: number) {
|
||||
this._probability = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* The add function adds a new node with a given key and value to a Skip List data structure.
|
||||
* @param {K} key - The key parameter represents the key of the node that needs to be added to the skip list.
|
||||
|
@ -80,7 +64,7 @@ export class SkipList<K, V> {
|
|||
* List.
|
||||
*/
|
||||
add(key: K, value: V): void {
|
||||
const newNode = new SkipListNode(key, value, this.randomLevel());
|
||||
const newNode = new SkipListNode(key, value, this._randomLevel());
|
||||
const update: SkipListNode<K, V>[] = new Array(this.maxLevel).fill(this.head);
|
||||
let current = this.head;
|
||||
|
||||
|
@ -97,7 +81,7 @@ export class SkipList<K, V> {
|
|||
}
|
||||
|
||||
if (newNode.forward[0] !== null) {
|
||||
this.level = Math.max(this.level, newNode.forward.length);
|
||||
this._level = Math.max(this.level, newNode.forward.length);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -124,6 +108,10 @@ export class SkipList<K, V> {
|
|||
return undefined;
|
||||
}
|
||||
|
||||
has(key: K): boolean {
|
||||
return this.get(key) !== undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* The `delete` function removes a node with a specific key from a Skip List data structure.
|
||||
* @param {K} key - The key parameter represents the key of the node that needs to be removed from the skip list.
|
||||
|
@ -151,7 +139,7 @@ export class SkipList<K, V> {
|
|||
update[i].forward[i] = current.forward[i];
|
||||
}
|
||||
while (this.level > 0 && this.head.forward[this.level - 1] === null) {
|
||||
this.level--;
|
||||
this._level--;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -160,10 +148,70 @@ export class SkipList<K, V> {
|
|||
}
|
||||
|
||||
/**
|
||||
* The function "randomLevel" generates a random level based on a given probability and maximum level.
|
||||
* Get the value of the first element (the smallest element) in the Skip List.
|
||||
* @returns The value of the first element, or undefined if the Skip List is empty.
|
||||
*/
|
||||
getFirst(): V | undefined {
|
||||
const firstNode = this.head.forward[0];
|
||||
return firstNode ? firstNode.value : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of the last element (the largest element) in the Skip List.
|
||||
* @returns The value of the last element, or undefined if the Skip List is empty.
|
||||
*/
|
||||
getLast(): V | undefined {
|
||||
let current = this.head;
|
||||
for (let i = this.level - 1; i >= 0; i--) {
|
||||
while (current.forward[i]) {
|
||||
current = current.forward[i];
|
||||
}
|
||||
}
|
||||
return current.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of the first element in the Skip List that is greater than the given key.
|
||||
* @param key - the given key.
|
||||
* @returns The value of the first element greater than the given key, or undefined if there is no such element.
|
||||
*/
|
||||
higher(key: K): V | undefined {
|
||||
let current = this.head;
|
||||
for (let i = this.level - 1; i >= 0; i--) {
|
||||
while (current.forward[i] && current.forward[i].key <= key) {
|
||||
current = current.forward[i];
|
||||
}
|
||||
}
|
||||
const nextNode = current.forward[0];
|
||||
return nextNode ? nextNode.value : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of the last element in the Skip List that is less than the given key.
|
||||
* @param key - the given key.
|
||||
* @returns The value of the last element less than the given key, or undefined if there is no such element.
|
||||
*/
|
||||
lower(key: K): V | undefined {
|
||||
let current = this.head;
|
||||
let lastLess = null;
|
||||
|
||||
for (let i = this.level - 1; i >= 0; i--) {
|
||||
while (current.forward[i] && current.forward[i].key < key) {
|
||||
current = current.forward[i];
|
||||
}
|
||||
if (current.key < key) {
|
||||
lastLess = current;
|
||||
}
|
||||
}
|
||||
|
||||
return lastLess ? lastLess.value : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* The function "_randomLevel" generates a random level based on a given probability and maximum level.
|
||||
* @returns the level, which is a number.
|
||||
*/
|
||||
private randomLevel(): number {
|
||||
protected _randomLevel(): number {
|
||||
let level = 1;
|
||||
while (Math.random() < this.probability && level < this.maxLevel) {
|
||||
level++;
|
||||
|
|
|
@ -19,43 +19,31 @@ export class ObjectDeque<E = number> {
|
|||
if (capacity !== undefined) this._capacity = capacity;
|
||||
}
|
||||
|
||||
private _nodes: {[key: number]: E} = {};
|
||||
protected _nodes: {[key: number]: E} = {};
|
||||
|
||||
get nodes(): {[p: number]: E} {
|
||||
return this._nodes;
|
||||
}
|
||||
|
||||
private _capacity = Number.MAX_SAFE_INTEGER;
|
||||
protected _capacity = Number.MAX_SAFE_INTEGER;
|
||||
|
||||
get capacity(): number {
|
||||
return this._capacity;
|
||||
}
|
||||
|
||||
set capacity(value: number) {
|
||||
this._capacity = value;
|
||||
}
|
||||
|
||||
private _first = -1;
|
||||
protected _first = -1;
|
||||
|
||||
get first(): number {
|
||||
return this._first;
|
||||
}
|
||||
|
||||
set first(value: number) {
|
||||
this._first = value;
|
||||
}
|
||||
|
||||
private _last = -1;
|
||||
protected _last = -1;
|
||||
|
||||
get last(): number {
|
||||
return this._last;
|
||||
}
|
||||
|
||||
set last(value: number) {
|
||||
this._last = value;
|
||||
}
|
||||
|
||||
private _size = 0;
|
||||
protected _size = 0;
|
||||
|
||||
get size(): number {
|
||||
return this._size;
|
||||
|
@ -67,14 +55,14 @@ export class ObjectDeque<E = number> {
|
|||
* structure.
|
||||
*/
|
||||
addFirst(value: E) {
|
||||
if (this._size === 0) {
|
||||
const mid = Math.floor(this._capacity / 2);
|
||||
if (this.size === 0) {
|
||||
const mid = Math.floor(this.capacity / 2);
|
||||
this._first = mid;
|
||||
this._last = mid;
|
||||
} else {
|
||||
this._first--;
|
||||
}
|
||||
this._nodes[this._first] = value;
|
||||
this.nodes[this.first] = value;
|
||||
this._size++;
|
||||
}
|
||||
|
||||
|
@ -83,14 +71,14 @@ export class ObjectDeque<E = number> {
|
|||
* @param {E} value - The `value` parameter represents the value that you want to add to the end of the data structure.
|
||||
*/
|
||||
addLast(value: E) {
|
||||
if (this._size === 0) {
|
||||
const mid = Math.floor(this._capacity / 2);
|
||||
if (this.size === 0) {
|
||||
const mid = Math.floor(this.capacity / 2);
|
||||
this._first = mid;
|
||||
this._last = mid;
|
||||
} else {
|
||||
this._last++;
|
||||
}
|
||||
this._nodes[this._last] = value;
|
||||
this.nodes[this.last] = value;
|
||||
this._size++;
|
||||
}
|
||||
|
||||
|
@ -99,9 +87,9 @@ export class ObjectDeque<E = number> {
|
|||
* @returns The value of the first element in the data structure.
|
||||
*/
|
||||
popFirst() {
|
||||
if (!this._size) return;
|
||||
if (!this.size) return;
|
||||
const value = this.getFirst();
|
||||
delete this._nodes[this._first];
|
||||
delete this.nodes[this.first];
|
||||
this._first++;
|
||||
this._size--;
|
||||
return value;
|
||||
|
@ -112,7 +100,7 @@ export class ObjectDeque<E = number> {
|
|||
* @returns The element at the first position of the `_nodes` array.
|
||||
*/
|
||||
getFirst() {
|
||||
if (this._size) return this._nodes[this._first];
|
||||
if (this.size) return this.nodes[this.first];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -120,9 +108,9 @@ export class ObjectDeque<E = number> {
|
|||
* @returns The value that was removed from the data structure.
|
||||
*/
|
||||
popLast() {
|
||||
if (!this._size) return;
|
||||
if (!this.size) return;
|
||||
const value = this.getLast();
|
||||
delete this._nodes[this._last];
|
||||
delete this.nodes[this.last];
|
||||
this._last--;
|
||||
this._size--;
|
||||
|
||||
|
@ -134,7 +122,7 @@ export class ObjectDeque<E = number> {
|
|||
* @returns The last element in the array "_nodes" is being returned.
|
||||
*/
|
||||
getLast() {
|
||||
if (this._size) return this._nodes[this._last];
|
||||
if (this.size) return this.nodes[this.last];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -145,7 +133,7 @@ export class ObjectDeque<E = number> {
|
|||
* index, `null` is returned.
|
||||
*/
|
||||
get(index: number) {
|
||||
return this._nodes[this._first + index] || null;
|
||||
return this.nodes[this.first + index] || null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -153,25 +141,20 @@ export class ObjectDeque<E = number> {
|
|||
* @returns The method is returning a boolean value indicating whether the size of the object is less than or equal to 0.
|
||||
*/
|
||||
isEmpty() {
|
||||
return this._size <= 0;
|
||||
}
|
||||
|
||||
protected _seNodes(value: {[p: number]: E}) {
|
||||
this._nodes = value;
|
||||
}
|
||||
|
||||
protected _setSize(value: number) {
|
||||
this._size = value;
|
||||
return this.size <= 0;
|
||||
}
|
||||
}
|
||||
|
||||
// O(1) time complexity of obtaining the value
|
||||
// O(n) time complexity of adding at the beginning and the end
|
||||
export class ArrayDeque<E> {
|
||||
get nodes(): E[] {
|
||||
return this._nodes;
|
||||
}
|
||||
protected _nodes: E[] = [];
|
||||
|
||||
get size() {
|
||||
return this._nodes.length;
|
||||
return this.nodes.length;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -184,7 +167,7 @@ export class ArrayDeque<E> {
|
|||
* @returns The return value is the new length of the array after the value has been added.
|
||||
*/
|
||||
addLast(value: E) {
|
||||
return this._nodes.push(value);
|
||||
return this.nodes.push(value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -192,7 +175,7 @@ export class ArrayDeque<E> {
|
|||
* @returns The method `popLast()` returns the last element of the `_nodes` array, or `null` if the array is empty.
|
||||
*/
|
||||
popLast(): E | null {
|
||||
return this._nodes.pop() ?? null;
|
||||
return this.nodes.pop() ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -201,7 +184,7 @@ export class ArrayDeque<E> {
|
|||
* empty.
|
||||
*/
|
||||
popFirst(): E | null {
|
||||
return this._nodes.shift() ?? null;
|
||||
return this.nodes.shift() ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -215,7 +198,7 @@ export class ArrayDeque<E> {
|
|||
* `value` at the beginning.
|
||||
*/
|
||||
addFirst(value: E) {
|
||||
return this._nodes.unshift(value);
|
||||
return this.nodes.unshift(value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -224,7 +207,7 @@ export class ArrayDeque<E> {
|
|||
* empty, it will return `null`.
|
||||
*/
|
||||
getFirst(): E | null {
|
||||
return this._nodes[0] ?? null;
|
||||
return this.nodes[0] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -232,7 +215,7 @@ export class ArrayDeque<E> {
|
|||
* @returns The method `getLast()` returns the last element of the `_nodes` array, or `null` if the array is empty.
|
||||
*/
|
||||
getLast(): E | null {
|
||||
return this._nodes[this._nodes.length - 1] ?? null;
|
||||
return this.nodes[this.nodes.length - 1] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -247,7 +230,7 @@ export class ArrayDeque<E> {
|
|||
* will be returned. If the element does not exist (i.e., the index is out of bounds), `null` will be returned.
|
||||
*/
|
||||
get(index: number): E | null {
|
||||
return this._nodes[index] ?? null;
|
||||
return this.nodes[index] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -259,7 +242,7 @@ export class ArrayDeque<E> {
|
|||
* @returns The value that is being set at the specified index in the `_nodes` array.
|
||||
*/
|
||||
set(index: number, value: E) {
|
||||
return (this._nodes[index] = value);
|
||||
return (this.nodes[index] = value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -273,7 +256,7 @@ export class ArrayDeque<E> {
|
|||
* are being removed, an empty array will be returned.
|
||||
*/
|
||||
insert(index: number, value: E) {
|
||||
return this._nodes.splice(index, 0, value);
|
||||
return this.nodes.splice(index, 0, value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -283,7 +266,7 @@ export class ArrayDeque<E> {
|
|||
* @returns The method is returning an array containing the removed element.
|
||||
*/
|
||||
delete(index: number) {
|
||||
return this._nodes.splice(index, 1);
|
||||
return this.nodes.splice(index, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -292,6 +275,6 @@ export class ArrayDeque<E> {
|
|||
* is 0, indicating that the array is empty. Otherwise, it returns `false`.
|
||||
*/
|
||||
isEmpty() {
|
||||
return this._nodes.length === 0;
|
||||
return this.nodes.length === 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,26 +51,18 @@ export class Queue<E = any> {
|
|||
this._offset = 0;
|
||||
}
|
||||
|
||||
private _nodes: E[];
|
||||
protected _nodes: E[];
|
||||
|
||||
get nodes(): E[] {
|
||||
return this._nodes;
|
||||
}
|
||||
|
||||
set nodes(value: E[]) {
|
||||
this._nodes = value;
|
||||
}
|
||||
|
||||
private _offset: number;
|
||||
protected _offset: number;
|
||||
|
||||
get offset(): number {
|
||||
return this._offset;
|
||||
}
|
||||
|
||||
set offset(value: number) {
|
||||
this._offset = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* The size function returns the number of elements in an array.
|
||||
* @returns {number} The size of the array, which is the difference between the length of the array and the offset.
|
||||
|
@ -110,14 +102,14 @@ export class Queue<E = any> {
|
|||
if (this.size === 0) return undefined;
|
||||
|
||||
const first = this.getFirst();
|
||||
this.offset += 1;
|
||||
this._offset += 1;
|
||||
|
||||
if (this.offset * 2 < this.nodes.length) return first;
|
||||
|
||||
// only delete dequeued elements when reaching half size
|
||||
// to decrease latency of shifting elements.
|
||||
this.nodes = this.nodes.slice(this.offset);
|
||||
this.offset = 0;
|
||||
this._nodes = this.nodes.slice(this.offset);
|
||||
this._offset = 0;
|
||||
return first;
|
||||
}
|
||||
|
||||
|
@ -130,7 +122,6 @@ export class Queue<E = any> {
|
|||
return this.size > 0 ? this.nodes[this.offset] : undefined;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The `peek` function returns the first element of the array `_nodes` if it exists, otherwise it returns `null`.
|
||||
* @returns The `peek()` method returns the first element of the data structure, represented by the `_nodes` array at
|
||||
|
@ -157,7 +148,7 @@ export class Queue<E = any> {
|
|||
peekLast(): E | undefined {
|
||||
return this.getLast();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The enqueue function adds a value to the end of a queue.
|
||||
* @param {E} value - The value parameter represents the value that you want to add to the queue.
|
||||
|
@ -198,8 +189,8 @@ export class Queue<E = any> {
|
|||
* The clear function resets the nodes array and offset to their initial values.
|
||||
*/
|
||||
clear(): void {
|
||||
this.nodes = [];
|
||||
this.offset = 0;
|
||||
this._nodes = [];
|
||||
this._offset = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -4,6 +4,9 @@
|
|||
* @class
|
||||
*/
|
||||
export class Stack<E = any> {
|
||||
get elements(): E[] {
|
||||
return this._elements;
|
||||
}
|
||||
protected _elements: E[];
|
||||
|
||||
/**
|
||||
|
@ -31,7 +34,7 @@ export class Stack<E = any> {
|
|||
* @returns A boolean value indicating whether the `_elements` array is empty or not.
|
||||
*/
|
||||
isEmpty(): boolean {
|
||||
return this._elements.length === 0;
|
||||
return this.elements.length === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -39,7 +42,7 @@ export class Stack<E = any> {
|
|||
* @returns The size of the elements array.
|
||||
*/
|
||||
size(): number {
|
||||
return this._elements.length;
|
||||
return this.elements.length;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -49,7 +52,7 @@ export class Stack<E = any> {
|
|||
peek(): E | null {
|
||||
if (this.isEmpty()) return null;
|
||||
|
||||
return this._elements[this._elements.length - 1];
|
||||
return this.elements[this.elements.length - 1];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -58,7 +61,7 @@ export class Stack<E = any> {
|
|||
* @returns The `push` method is returning the updated `Stack<E>` object.
|
||||
*/
|
||||
push(element: E): Stack<E> {
|
||||
this._elements.push(element);
|
||||
this.elements.push(element);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -70,7 +73,7 @@ export class Stack<E = any> {
|
|||
pop(): E | null {
|
||||
if (this.isEmpty()) return null;
|
||||
|
||||
return this._elements.pop() || null;
|
||||
return this.elements.pop() || null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -78,7 +81,7 @@ export class Stack<E = any> {
|
|||
* @returns An array of type E.
|
||||
*/
|
||||
toArray(): E[] {
|
||||
return this._elements.slice();
|
||||
return this.elements.slice();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -93,6 +96,6 @@ export class Stack<E = any> {
|
|||
* @returns The `clone()` method is returning a new `Stack` object with a copy of the `_elements` array.
|
||||
*/
|
||||
clone(): Stack<E> {
|
||||
return new Stack(this._elements.slice());
|
||||
return new Stack(this.elements.slice());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,39 +1,15 @@
|
|||
export class TreeNode<V = any> {
|
||||
constructor(key: string, value?: V, children?: TreeNode<V>[]) {
|
||||
this._key = key;
|
||||
this._value = value || undefined;
|
||||
this._children = children || [];
|
||||
this.key = key;
|
||||
this.value = value || undefined;
|
||||
this.children = children || [];
|
||||
}
|
||||
|
||||
private _key: string;
|
||||
key: string;
|
||||
|
||||
get key(): string {
|
||||
return this._key;
|
||||
}
|
||||
value?: V | undefined;
|
||||
|
||||
set key(value: string) {
|
||||
this._key = value;
|
||||
}
|
||||
|
||||
private _value?: V | undefined;
|
||||
|
||||
get value(): V | undefined {
|
||||
return this._value;
|
||||
}
|
||||
|
||||
set value(value: V | undefined) {
|
||||
this._value = value;
|
||||
}
|
||||
|
||||
private _children?: TreeNode<V>[] | undefined;
|
||||
|
||||
get children(): TreeNode<V>[] | undefined {
|
||||
return this._children;
|
||||
}
|
||||
|
||||
set children(value: TreeNode<V>[] | undefined) {
|
||||
this._children = value;
|
||||
}
|
||||
children?: TreeNode<V>[] | undefined;
|
||||
|
||||
addChildren(children: TreeNode<V> | TreeNode<V>[]) {
|
||||
if (!this.children) {
|
||||
|
|
|
@ -12,47 +12,26 @@
|
|||
*/
|
||||
export class TrieNode {
|
||||
constructor(key: string) {
|
||||
this._key = key;
|
||||
this._isEnd = false;
|
||||
this._children = new Map<string, TrieNode>();
|
||||
this.key = key;
|
||||
this.isEnd = false;
|
||||
this.children = new Map<string, TrieNode>();
|
||||
}
|
||||
|
||||
private _key;
|
||||
key: string;
|
||||
|
||||
get key(): string {
|
||||
return this._key;
|
||||
}
|
||||
children: Map<string, TrieNode>;
|
||||
|
||||
set key(v: string) {
|
||||
this._key = v;
|
||||
}
|
||||
|
||||
protected _children: Map<string, TrieNode>;
|
||||
|
||||
get children(): Map<string, TrieNode> {
|
||||
return this._children;
|
||||
}
|
||||
|
||||
set children(v: Map<string, TrieNode>) {
|
||||
this._children = v;
|
||||
}
|
||||
|
||||
protected _isEnd: boolean;
|
||||
|
||||
get isEnd(): boolean {
|
||||
return this._isEnd;
|
||||
}
|
||||
|
||||
set isEnd(v: boolean) {
|
||||
this._isEnd = v;
|
||||
}
|
||||
isEnd: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trie represents a Trie data structure. It provides basic Trie operations and additional methods.
|
||||
*/
|
||||
export class Trie {
|
||||
private readonly _caseSensitive: boolean;
|
||||
get caseSensitive(): boolean {
|
||||
return this._caseSensitive;
|
||||
}
|
||||
protected _caseSensitive: boolean;
|
||||
|
||||
constructor(words?: string[], caseSensitive = true) {
|
||||
this._root = new TrieNode('');
|
||||
|
@ -70,10 +49,6 @@ export class Trie {
|
|||
return this._root;
|
||||
}
|
||||
|
||||
set root(v: TrieNode) {
|
||||
this._root = v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a word to the Trie structure.
|
||||
* @param {string} word - The word to add.
|
||||
|
@ -277,7 +252,7 @@ export class Trie {
|
|||
return words;
|
||||
}
|
||||
|
||||
private _caseProcess(str: string) {
|
||||
protected _caseProcess(str: string) {
|
||||
if (!this._caseSensitive) {
|
||||
str = str.toLowerCase(); // Convert str to lowercase if case-insensitive
|
||||
}
|
||||
|
|
|
@ -54,12 +54,12 @@ class MyGraph<
|
|||
}
|
||||
|
||||
edgesOf(vertexOrKey: VO | VertexKey): EO[] {
|
||||
const a = typeof vertexOrKey === "string" ? vertexOrKey : "a";
|
||||
const a = typeof vertexOrKey === 'string' ? vertexOrKey : 'a';
|
||||
return [new MyEdge(a, 'b') as EO];
|
||||
}
|
||||
|
||||
getNeighbors(vertexOrKey: VO | VertexKey): VO[] {
|
||||
const a = typeof vertexOrKey === "string" ? vertexOrKey : "a";
|
||||
const a = typeof vertexOrKey === 'string' ? vertexOrKey : 'a';
|
||||
return [new MyVertex(a, 'b') as VO];
|
||||
}
|
||||
|
||||
|
@ -75,8 +75,7 @@ class MyGraph<
|
|||
describe('AbstractGraph Operation Test', () => {
|
||||
const myGraph: MyGraph<number, string> = new MyGraph<number, string>();
|
||||
|
||||
beforeEach(() => {
|
||||
});
|
||||
beforeEach(() => {});
|
||||
it('should edge cases', function () {
|
||||
myGraph.addVertex('A', 1);
|
||||
myGraph.addVertex('B', 2);
|
||||
|
|
|
@ -57,7 +57,7 @@ describe('CoordinateMap', () => {
|
|||
class MyCoordinateMap<V = any> extends CoordinateMap<V> {
|
||||
constructor(joint?: string) {
|
||||
super(joint);
|
||||
this._setJoint((joint += '-'));
|
||||
this._joint = joint += '-';
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ describe('MyCoordinateSet', () => {
|
|||
class MyCoordinateSet extends CoordinateSet {
|
||||
constructor(joint?: string) {
|
||||
super(joint);
|
||||
this._setJoint((joint += '-'));
|
||||
this._joint = joint += '-';
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,6 @@ describe('HashMap', () => {
|
|||
|
||||
it('should handle key collisions', () => {
|
||||
// Force a collision by setting two different keys to the same bucket
|
||||
hashMap.hashFn = () => 0; // Override hash function to return the same index
|
||||
hashMap.set('key1', 1);
|
||||
hashMap.set('key2', 2);
|
||||
|
||||
|
|
|
@ -15,9 +15,9 @@ describe('HashNode', () => {
|
|||
describe('HashTable', () => {
|
||||
it('should initialize with default capacity', () => {
|
||||
const hashTable = new HashTable<string, string>();
|
||||
hashTable.capacity = hashTable.capacity;
|
||||
hashTable.buckets = hashTable.buckets;
|
||||
hashTable.hashFn = hashTable.hashFn;
|
||||
expect(hashTable.capacity).toBe(16);
|
||||
expect(hashTable.buckets).toEqual(new Array(16).fill(null));
|
||||
expect(hashTable.hashFn('a')).toBe(6);
|
||||
expect(hashTable.capacity).toBe(16);
|
||||
expect(hashTable.size).toBe(0);
|
||||
expect(hashTable.buckets.length).toBe(16);
|
||||
|
|
|
@ -53,3 +53,34 @@ describe('SkipList', () => {
|
|||
expect(skipList.get(4)).toBe('Four');
|
||||
});
|
||||
});
|
||||
|
||||
describe('SkipList', () => {
|
||||
let skipList: SkipList<number, string>;
|
||||
|
||||
beforeEach(() => {
|
||||
skipList = new SkipList();
|
||||
skipList.add(1, 'One');
|
||||
skipList.add(2, 'Two');
|
||||
skipList.add(3, 'Three');
|
||||
skipList.add(4, 'Four');
|
||||
});
|
||||
|
||||
test('getFirst() should return the getFirst element', () => {
|
||||
expect(skipList.getFirst()).toBe('One');
|
||||
});
|
||||
|
||||
test('getLast() should return the getLast element', () => {
|
||||
expect(skipList.getLast()).toBe('Four');
|
||||
});
|
||||
|
||||
test('higher(key) should return the getFirst element greater than the given key', () => {
|
||||
expect(skipList.higher(2)).toBe('Three');
|
||||
expect(skipList.higher(3)).toBe('Four');
|
||||
expect(skipList.higher(4)).toBeUndefined();
|
||||
});
|
||||
|
||||
test('lower(key) should return the getLast element less than the given key', () => {
|
||||
expect(skipList.lower(2)).toBe('One');
|
||||
expect(skipList.lower(1)).toBe(null);
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue