mirror of
https://github.com/zrwusa/data-structure-typed.git
synced 2024-11-23 12:54:04 +00:00
fix: Fix the bug in the getCycles method. refactor: Rename some variables.
This commit is contained in:
parent
6ceaf21fba
commit
bbfa64fc64
|
@ -156,10 +156,10 @@ export abstract class AbstractGraph<
|
|||
|
||||
addVertex(keyOrVertex: VertexKey | VO, value?: V): boolean {
|
||||
if (keyOrVertex instanceof AbstractVertex) {
|
||||
return this._addVertexOnly(keyOrVertex);
|
||||
return this._addVertex(keyOrVertex);
|
||||
} else {
|
||||
const newVertex = this.createVertex(keyOrVertex, value);
|
||||
return this._addVertexOnly(newVertex);
|
||||
return this._addVertex(newVertex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -242,14 +242,14 @@ export abstract class AbstractGraph<
|
|||
|
||||
addEdge(srcOrEdge: VO | VertexKey | EO, dest?: VO | VertexKey, weight?: number, value?: E): boolean {
|
||||
if (srcOrEdge instanceof AbstractEdge) {
|
||||
return this._addEdgeOnly(srcOrEdge);
|
||||
return this._addEdge(srcOrEdge);
|
||||
} else {
|
||||
if (dest instanceof AbstractVertex || typeof dest === 'string' || typeof dest === 'number') {
|
||||
if (!(this.hasVertex(srcOrEdge) && this.hasVertex(dest))) return false;
|
||||
if (srcOrEdge instanceof AbstractVertex) srcOrEdge = srcOrEdge.key;
|
||||
if (dest instanceof AbstractVertex) dest = dest.key;
|
||||
const newEdge = this.createEdge(srcOrEdge, dest, weight, value);
|
||||
return this._addEdgeOnly(newEdge);
|
||||
return this._addEdge(newEdge);
|
||||
} else {
|
||||
throw new Error('dest must be a Vertex or vertex key while srcOrEdge is an Edge');
|
||||
}
|
||||
|
@ -1147,14 +1147,6 @@ export abstract class AbstractGraph<
|
|||
return this.tarjan(false, false, false, false).lowMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* The function `getCycles` returns a map of cycles found using the Tarjan algorithm.
|
||||
* @returns The function `getCycles()` is returning a `Map<number, VO[]>`.
|
||||
*/
|
||||
getCycles(): Map<number, VO[]> {
|
||||
return this.tarjan(false, false, false, true).cycles;
|
||||
}
|
||||
|
||||
/**
|
||||
* The function "getCutVertexes" returns an array of cut vertexes using the Tarjan algorithm.
|
||||
* @returns an array of VO objects, specifically the cut vertexes.
|
||||
|
@ -1180,6 +1172,55 @@ export abstract class AbstractGraph<
|
|||
return this.tarjan(false, true, false, false).bridges;
|
||||
}
|
||||
|
||||
/**
|
||||
* O(V+E+C)
|
||||
* O(V+C)
|
||||
*/
|
||||
getCycles(isInclude2Cycle: boolean = false): VertexKey[][] {
|
||||
const cycles: VertexKey[][] = [];
|
||||
const visited: Set<VO> = new Set();
|
||||
|
||||
const dfs = (vertex: VO, currentPath: VertexKey[], visited: Set<VO>) => {
|
||||
if (visited.has(vertex)) {
|
||||
if ((!isInclude2Cycle && currentPath.length > 2 || isInclude2Cycle && currentPath.length >= 2) && currentPath[0] === vertex.key) {
|
||||
cycles.push([...currentPath]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
visited.add(vertex);
|
||||
currentPath.push(vertex.key);
|
||||
|
||||
for (const neighbor of this.getNeighbors(vertex)) {
|
||||
neighbor && dfs(neighbor, currentPath, visited);
|
||||
}
|
||||
|
||||
visited.delete(vertex);
|
||||
currentPath.pop();
|
||||
};
|
||||
|
||||
for (const vertex of this.vertexMap.values()) {
|
||||
dfs(vertex, [], visited);
|
||||
}
|
||||
|
||||
// Use a set to eliminate duplicate cycles
|
||||
const uniqueCycles = new Map<string, VertexKey[]>();
|
||||
|
||||
for (const cycle of cycles) {
|
||||
const sorted = [...cycle].sort().toString()
|
||||
|
||||
if (uniqueCycles.has(sorted)) continue
|
||||
else {
|
||||
uniqueCycles.set(sorted, cycle)
|
||||
}
|
||||
}
|
||||
|
||||
// Convert the unique cycles back to an array
|
||||
return [...uniqueCycles].map(cycleString =>
|
||||
cycleString[1]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n)
|
||||
* Space Complexity: O(n)
|
||||
|
@ -1247,9 +1288,9 @@ export abstract class AbstractGraph<
|
|||
}
|
||||
}
|
||||
|
||||
protected abstract _addEdgeOnly(edge: EO): boolean;
|
||||
protected abstract _addEdge(edge: EO): boolean;
|
||||
|
||||
protected _addVertexOnly(newVertex: VO): boolean {
|
||||
protected _addVertex(newVertex: VO): boolean {
|
||||
if (this.hasVertex(newVertex)) {
|
||||
return false;
|
||||
// throw (new Error('Duplicated vertex key is not allowed'));
|
||||
|
|
|
@ -596,6 +596,7 @@ export class DirectedGraph<
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1)
|
||||
* Space Complexity: O(1)
|
||||
|
@ -605,13 +606,13 @@ export class DirectedGraph<
|
|||
* Time Complexity: O(1)
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The function `_addEdgeOnly` adds an edge to a graph if the source and destination vertexMap exist.
|
||||
* The function `_addEdge` adds an edge to a graph if the source and destination vertexMap exist.
|
||||
* @param {EO} edge - The parameter `edge` is of type `EO`, which represents an edge in a graph. It is the edge that
|
||||
* needs to be added to the graph.
|
||||
* @returns a boolean value. It returns true if the edge was successfully added to the graph, and false if either the
|
||||
* source or destination vertex does not exist in the graph.
|
||||
*/
|
||||
protected _addEdgeOnly(edge: EO): boolean {
|
||||
protected _addEdge(edge: EO): boolean {
|
||||
if (!(this.hasVertex(edge.src) && this.hasVertex(edge.dest))) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -381,7 +381,7 @@ export class UndirectedGraph<
|
|||
* @param {EO} edge - The parameter "edge" is of type EO, which represents an edge in a graph.
|
||||
* @returns a boolean value.
|
||||
*/
|
||||
protected _addEdgeOnly(edge: EO): boolean {
|
||||
protected _addEdge(edge: EO): boolean {
|
||||
for (const end of edge.vertexMap) {
|
||||
const endVertex = this._getVertex(end);
|
||||
if (endVertex === undefined) return false;
|
||||
|
|
|
@ -70,6 +70,38 @@ export class DoublyLinkedList<E = any> extends IterableElementBase<E> {
|
|||
* Space Complexity: O(n)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n), where n is the number of elements in the linked list.
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The `get first` function returns the first node in a doubly linked list, or undefined if the list is empty.
|
||||
* @returns The method `get first()` returns the first node of the doubly linked list, or `undefined` if the list is empty.
|
||||
*/
|
||||
get first(): E | undefined {
|
||||
return this.head?.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1)
|
||||
* Space Complexity: O(1)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n), where n is the number of elements in the linked list.
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The `get last` function returns the last node in a doubly linked list, or undefined if the list is empty.
|
||||
* @returns The method `get last()` returns the last node of the doubly linked list, or `undefined` if the list is empty.
|
||||
*/
|
||||
get last(): E | undefined {
|
||||
return this.tail?.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1)
|
||||
* Space Complexity: O(1)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n), where n is the size of the input array.
|
||||
* Space Complexity: O(n)
|
||||
|
@ -141,7 +173,7 @@ export class DoublyLinkedList<E = any> extends IterableElementBase<E> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1)
|
||||
* Time Complexity: O(n), where n is the number of elements in the linked list.
|
||||
* Space Complexity: O(1)
|
||||
*/
|
||||
|
||||
|
@ -168,7 +200,7 @@ export class DoublyLinkedList<E = any> extends IterableElementBase<E> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1)
|
||||
* Time Complexity: O(n), where n is the number of elements in the linked list.
|
||||
* Space Complexity: O(1)
|
||||
*/
|
||||
|
||||
|
@ -399,11 +431,6 @@ export class DoublyLinkedList<E = any> extends IterableElementBase<E> {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n), where n is the number of elements in the linked list.
|
||||
* Space Complexity: O(1)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n), where n is the number of elements in the linked list.
|
||||
* Space Complexity: O(1)
|
||||
|
@ -434,11 +461,6 @@ export class DoublyLinkedList<E = any> extends IterableElementBase<E> {
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n), where n is the number of elements in the linked list.
|
||||
* Space Complexity: O(1)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n), where n is the number of elements in the linked list.
|
||||
* Space Complexity: O(1)
|
||||
|
@ -475,6 +497,11 @@ export class DoublyLinkedList<E = any> extends IterableElementBase<E> {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n), where n is the number of elements in the linked list.
|
||||
* Space Complexity: O(1)
|
||||
*/
|
||||
|
||||
/**
|
||||
* The function checks if a variable has a size greater than zero and returns a boolean value.
|
||||
* @returns A boolean value is being returned.
|
||||
|
@ -483,6 +510,11 @@ export class DoublyLinkedList<E = any> extends IterableElementBase<E> {
|
|||
return this.size === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n), where n is the number of elements in the linked list.
|
||||
* Space Complexity: O(1)
|
||||
*/
|
||||
|
||||
/**
|
||||
* The `clear` function resets the linked list by setting the head, tail, and size to undefined and 0 respectively.
|
||||
*/
|
||||
|
@ -548,7 +580,7 @@ export class DoublyLinkedList<E = any> extends IterableElementBase<E> {
|
|||
|
||||
/**
|
||||
* Time Complexity: O(n), where n is the number of elements in the linked list.
|
||||
* Space Complexity: O(1)
|
||||
* Space Complexity: O(n)
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -575,7 +607,7 @@ export class DoublyLinkedList<E = any> extends IterableElementBase<E> {
|
|||
|
||||
/**
|
||||
* Time Complexity: O(n), where n is the number of elements in the linked list.
|
||||
* Space Complexity: O(1)
|
||||
* Space Complexity: O(n)
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -596,7 +628,7 @@ export class DoublyLinkedList<E = any> extends IterableElementBase<E> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n), where n is the number of elements in the linked list.
|
||||
* Time Complexity: O(n)
|
||||
* Space Complexity: O(n)
|
||||
*/
|
||||
|
||||
|
@ -640,8 +672,8 @@ export class DoublyLinkedList<E = any> extends IterableElementBase<E> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n)
|
||||
* Space Complexity: O(n)
|
||||
* Time Complexity: O(1)
|
||||
* Space Complexity: O(1)
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -674,8 +706,8 @@ export class DoublyLinkedList<E = any> extends IterableElementBase<E> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n), where n is the number of elements in the linked list.
|
||||
* Space Complexity: O(n)
|
||||
* Time Complexity: O(1)
|
||||
* Space Complexity: O(1)
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -740,7 +772,7 @@ export class DoublyLinkedList<E = any> extends IterableElementBase<E> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1)
|
||||
* Time Complexity: O(n), where n is the number of elements in the linked list.
|
||||
* Space Complexity: O(1)
|
||||
*/
|
||||
|
||||
|
@ -757,7 +789,7 @@ export class DoublyLinkedList<E = any> extends IterableElementBase<E> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1)
|
||||
* Time Complexity: O(n), where n is the number of elements in the linked list.
|
||||
* Space Complexity: O(1)
|
||||
*/
|
||||
|
||||
|
@ -773,38 +805,6 @@ export class DoublyLinkedList<E = any> extends IterableElementBase<E> {
|
|||
this.unshift(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n), where n is the number of elements in the linked list.
|
||||
* Space Complexity: O(1)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n), where n is the number of elements in the linked list.
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The `get first` function returns the first node in a doubly linked list, or undefined if the list is empty.
|
||||
* @returns The method `get first()` returns the first node of the doubly linked list, or `undefined` if the list is empty.
|
||||
*/
|
||||
get first(): E | undefined {
|
||||
return this.head?.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n), where n is the number of elements in the linked list.
|
||||
* Space Complexity: O(1)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n), where n is the number of elements in the linked list.
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The `get last` function returns the last node in a doubly linked list, or undefined if the list is empty.
|
||||
* @returns The method `get last()` returns the last node of the doubly linked list, or `undefined` if the list is empty.
|
||||
*/
|
||||
get last(): E | undefined {
|
||||
return this.tail?.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* The function returns an iterator that iterates over the values of a linked list.
|
||||
*/
|
||||
|
|
|
@ -348,7 +348,7 @@ export class SinglyLinkedList<E = any> extends IterableElementBase<E> {
|
|||
* @returns The `delete` method returns a boolean value. It returns `true` if the value or node is found and
|
||||
* successfully deleted from the linked list, and `false` if the value or node is not found in the linked list.
|
||||
*/
|
||||
delete(valueOrNode: E | SinglyLinkedListNode<E> | undefined ): boolean {
|
||||
delete(valueOrNode: E | SinglyLinkedListNode<E> | undefined): boolean {
|
||||
if (!valueOrNode) return false;
|
||||
let value: E;
|
||||
if (valueOrNode instanceof SinglyLinkedListNode) {
|
||||
|
|
|
@ -57,6 +57,45 @@ export class SkipList<K, V> {
|
|||
return this._probability;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(log n) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.
|
||||
* Space Complexity: O(1) - constant space, as it uses a fixed amount of space regardless of the size of the SkipList.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.
|
||||
* Space Complexity: O(1) - constant space, as it uses a fixed amount of space regardless of the size of the SkipList.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
get first(): V | undefined {
|
||||
const firstNode = this.head.forward[0];
|
||||
return firstNode ? firstNode.value : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(log n) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.
|
||||
* Space Complexity: O(1) - constant space, as it uses a fixed amount of space regardless of the size of the SkipList.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time Complexity: O(log n) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.
|
||||
* Space Complexity: O(1) - constant space, as it uses a fixed amount of space regardless of the size of the SkipList.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
get last(): 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(log n) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.
|
||||
* Space Complexity: O(1) - constant space, as it uses a fixed amount of space regardless of the size of the SkipList.
|
||||
|
@ -125,7 +164,7 @@ export class SkipList<K, V> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(log n) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.
|
||||
* Time Complexity: O(1) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.
|
||||
* Space Complexity: O(1) - constant space, as it uses a fixed amount of space regardless of the size of the SkipList.
|
||||
*/
|
||||
|
||||
|
@ -181,45 +220,6 @@ export class SkipList<K, V> {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.
|
||||
* Space Complexity: O(1) - constant space, as it uses a fixed amount of space regardless of the size of the SkipList.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.
|
||||
* Space Complexity: O(1) - constant space, as it uses a fixed amount of space regardless of the size of the SkipList.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
get first(): V | undefined {
|
||||
const firstNode = this.head.forward[0];
|
||||
return firstNode ? firstNode.value : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(log n) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.
|
||||
* Space Complexity: O(1) - constant space, as it uses a fixed amount of space regardless of the size of the SkipList.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time Complexity: O(log n) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.
|
||||
* Space Complexity: O(1) - constant space, as it uses a fixed amount of space regardless of the size of the SkipList.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
get last(): 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(log n) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.
|
||||
* Space Complexity: O(1) - constant space, as it uses a fixed amount of space regardless of the size of the SkipList.
|
||||
|
|
|
@ -49,6 +49,40 @@ export class Queue<E = any> extends IterableElementBase<E> {
|
|||
return this.nodes.length - this.offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1) - constant time as it retrieves the value at the current offset.
|
||||
* Space Complexity: O(1) - no additional space is used.
|
||||
*
|
||||
* The `first` function returns the first element of the array `_nodes` if it exists, otherwise it returns `undefined`.
|
||||
* @returns The `get first()` method returns the first element of the data structure, represented by the `_nodes` array at
|
||||
* the `_offset` index. If the data structure is empty (size is 0), it returns `undefined`.
|
||||
*/
|
||||
get first(): E | undefined {
|
||||
return this.size > 0 ? this.nodes[this.offset] : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1) - constant time as it adds an element to the end of the array.
|
||||
* Space Complexity: O(1) - no additional space is used.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1) - constant time as it retrieves the value at the current offset.
|
||||
* Space Complexity: O(1) - no additional space is used.
|
||||
*
|
||||
* The `last` function returns the last element in an array-like data structure, or undefined if the structure is empty.
|
||||
* @returns The method `get last()` returns the last element of the `_nodes` array if the array is not empty. If the
|
||||
* array is empty, it returns `undefined`.
|
||||
*/
|
||||
get last(): E | undefined {
|
||||
return this.size > 0 ? this.nodes[this.nodes.length - 1] : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n) - where n is the number of elements in the queue. In the worst case, it may need to shift all elements to update the offset.
|
||||
* Space Complexity: O(1) - no additional space is used.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The function "fromArray" creates a new Queue object from an array of elements.Creates a queue from an existing array.
|
||||
* @public
|
||||
|
@ -62,7 +96,7 @@ export class Queue<E = any> extends IterableElementBase<E> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1) - constant time as it adds an element to the end of the array.
|
||||
* Time Complexity: O(1) - constant time as it retrieves the value at the current offset.
|
||||
* Space Complexity: O(1) - no additional space is used.
|
||||
*/
|
||||
|
||||
|
@ -80,7 +114,7 @@ export class Queue<E = any> extends IterableElementBase<E> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n) - where n is the number of elements in the queue. In the worst case, it may need to shift all elements to update the offset.
|
||||
* Time Complexity: O(1) - constant time as it retrieves the value at the current offset.
|
||||
* Space Complexity: O(1) - no additional space is used.
|
||||
*/
|
||||
|
||||
|
@ -107,23 +141,6 @@ export class Queue<E = any> extends IterableElementBase<E> {
|
|||
return first;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1) - constant time as it retrieves the value at the current offset.
|
||||
* Space Complexity: O(1) - no additional space is used.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1) - constant time as it retrieves the value at the current offset.
|
||||
* Space Complexity: O(1) - no additional space is used.
|
||||
*
|
||||
* The `first` function returns the first element of the array `_nodes` if it exists, otherwise it returns `undefined`.
|
||||
* @returns The `get first()` method returns the first element of the data structure, represented by the `_nodes` array at
|
||||
* the `_offset` index. If the data structure is empty (size is 0), it returns `undefined`.
|
||||
*/
|
||||
get first(): E | undefined {
|
||||
return this.size > 0 ? this.nodes[this.offset] : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1) - constant time as it retrieves the value at the current offset.
|
||||
* Space Complexity: O(1) - no additional space is used.
|
||||
|
@ -141,23 +158,6 @@ export class Queue<E = any> extends IterableElementBase<E> {
|
|||
return this.first;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1) - constant time as it retrieves the value at the current offset.
|
||||
* Space Complexity: O(1) - no additional space is used.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1) - constant time as it retrieves the value at the current offset.
|
||||
* Space Complexity: O(1) - no additional space is used.
|
||||
*
|
||||
* The `last` function returns the last element in an array-like data structure, or undefined if the structure is empty.
|
||||
* @returns The method `get last()` returns the last element of the `_nodes` array if the array is not empty. If the
|
||||
* array is empty, it returns `undefined`.
|
||||
*/
|
||||
get last(): E | undefined {
|
||||
return this.size > 0 ? this.nodes[this.nodes.length - 1] : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1) - constant time as it retrieves the value at the current offset.
|
||||
* Space Complexity: O(1) - no additional space is used.
|
||||
|
@ -358,12 +358,20 @@ export class Queue<E = any> extends IterableElementBase<E> {
|
|||
* 4. Frequent Enqueuing and Dequeuing Operations: If your application involves frequent enqueuing and dequeuing operations and is less concerned with random access, then LinkedListQueue is a good choice.
|
||||
*/
|
||||
export class LinkedListQueue<E = any> extends SinglyLinkedList<E> {
|
||||
/**
|
||||
* The `get first` function returns the value of the head node in a linked list, or `undefined` if the list is empty.
|
||||
* @returns The `get first()` method is returning the value of the `head` node if it exists, otherwise it returns `undefined`.
|
||||
*/
|
||||
get first(): E | undefined {
|
||||
return this.head?.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* The enqueue function adds a value to the end of an array.
|
||||
* @param {E} value - The value parameter represents the value that you want to add to the queue.
|
||||
*/
|
||||
enqueue(value: E): boolean {
|
||||
return this.push(value);
|
||||
return this.push(value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -374,14 +382,6 @@ export class LinkedListQueue<E = any> extends SinglyLinkedList<E> {
|
|||
return this.shift();
|
||||
}
|
||||
|
||||
/**
|
||||
* The `get first` function returns the value of the head node in a linked list, or `undefined` if the list is empty.
|
||||
* @returns The `get first()` method is returning the value of the `head` node if it exists, otherwise it returns `undefined`.
|
||||
*/
|
||||
get first(): E | undefined {
|
||||
return this.head?.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* The `peek` function returns the value of the head node in a linked list, or `undefined` if the list is empty.
|
||||
* @returns The `peek()` method is returning the value of the `head` node if it exists, otherwise it returns `undefined`.
|
||||
|
|
|
@ -66,7 +66,7 @@ class MyGraph<
|
|||
return edge ? undefined : undefined;
|
||||
}
|
||||
|
||||
protected _addEdgeOnly(edge: EO): boolean {
|
||||
protected _addEdge(edge: EO): boolean {
|
||||
return edge ? true : true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -588,7 +588,7 @@ describe('cycles, strongly connected components, bridges, articular points in Di
|
|||
const cutVertexes = graph.getCutVertexes();
|
||||
const dfnMap = graph.getDFNMap();
|
||||
const lowMap = graph.getLowMap();
|
||||
expect(cycles.size).toBe(2);
|
||||
expect(cycles.length).toBe(2);
|
||||
expect(scCs.size).toBe(5);
|
||||
expect(bridges.length).toBe(4);
|
||||
expect(cutVertexes.length).toBe(4);
|
||||
|
@ -688,8 +688,53 @@ describe('DirectedGraph getCycles', () => {
|
|||
graph.addEdge('D', 'E');
|
||||
graph.addEdge('E', 'B');
|
||||
const cycles = graph.getCycles();
|
||||
expect(cycles.size).toBe(1);
|
||||
expect(cycles.get(2)).toEqual( [{ "key": "B", "value": undefined }, { "key": "D", "value": undefined }, { "key": "E", "value": undefined }]);
|
||||
expect(cycles.length).toBe(1);
|
||||
expect(cycles[0]).toEqual(["B", "D", "E"]);
|
||||
})
|
||||
|
||||
test('should simple cycles graph getCycles return correct result', () => {
|
||||
const graph = new DirectedGraph();
|
||||
|
||||
graph.addVertex('A');
|
||||
graph.addVertex('B');
|
||||
graph.addVertex('C');
|
||||
graph.addVertex('D');
|
||||
|
||||
graph.addEdge('A', 'B');
|
||||
graph.addEdge('B', 'C');
|
||||
graph.addEdge('C', 'A');
|
||||
graph.addEdge('A', 'D');
|
||||
graph.addEdge('D', 'C');
|
||||
const cycles = graph.getCycles();
|
||||
expect(cycles.length).toBe(2)
|
||||
expect(cycles).toEqual([["A", "B", "C"], ["A", "D", "C"]])
|
||||
});
|
||||
|
||||
test('should 3 cycles graph getCycles return correct result', () => {
|
||||
const graph = new DirectedGraph();
|
||||
|
||||
graph.addVertex('A');
|
||||
graph.addVertex('B');
|
||||
graph.addVertex('C');
|
||||
graph.addVertex('D');
|
||||
graph.addVertex('E');
|
||||
graph.addVertex('F');
|
||||
graph.addVertex('G');
|
||||
|
||||
graph.addEdge('A', 'B');
|
||||
graph.addEdge('A', 'C');
|
||||
graph.addEdge('B', 'D');
|
||||
graph.addEdge('C', 'D');
|
||||
graph.addEdge('D', 'E');
|
||||
graph.addEdge('E', 'B');
|
||||
graph.addEdge('B', 'F');
|
||||
graph.addEdge('F', 'E');
|
||||
graph.addEdge('C', 'G');
|
||||
graph.addEdge('G', 'A');
|
||||
|
||||
const cycles = graph.getCycles();
|
||||
expect(cycles.length).toBe(3)
|
||||
expect(cycles).toEqual([["A", "C", "G"], ["B", "D", "E"], ["B", "F", "E"]]);
|
||||
});
|
||||
})
|
||||
|
||||
|
|
|
@ -237,7 +237,7 @@ describe('cycles, strongly connected components, bridges, articular points in Un
|
|||
const cutVertexes = graph.getCutVertexes();
|
||||
const dfnMap = graph.getDFNMap();
|
||||
const lowMap = graph.getLowMap();
|
||||
expect(cycles.size).toBe(2);
|
||||
expect(cycles.length).toBe(3);
|
||||
expect(scCs.size).toBe(5);
|
||||
expect(bridges.length).toBe(4);
|
||||
expect(cutVertexes.length).toBe(4);
|
||||
|
@ -277,8 +277,52 @@ describe('UndirectedGraph getCycles', () => {
|
|||
graph.addEdge('D', 'E');
|
||||
graph.addEdge('E', 'B');
|
||||
const cycles = graph.getCycles();
|
||||
expect(cycles.size).toBe(2);
|
||||
expect(cycles.get(1)).toEqual([{ "key": "A", "value": "A" }, { "key": "B", "value": "B" }, { "key": "D", "value": "D" }, { "key": "C", "value": "C" }]);
|
||||
expect(cycles.get(2)).toEqual([{ "key": "B", "value": "B" }, { "key": "D", "value": "D" }, { "key": "E", "value": "E" }]);
|
||||
expect(cycles.length).toBe(3);
|
||||
expect(cycles).toEqual([["A", "B", "D", "C"], ["A", "B", "E", "D", "C"], ["B", "D", "E"]]);
|
||||
})
|
||||
|
||||
test('should simple cycles graph getCycles return correct result', () => {
|
||||
const graph = new UndirectedGraph();
|
||||
|
||||
graph.addVertex('A');
|
||||
graph.addVertex('B');
|
||||
graph.addVertex('C');
|
||||
graph.addVertex('D');
|
||||
|
||||
graph.addEdge('A', 'B');
|
||||
graph.addEdge('B', 'C');
|
||||
graph.addEdge('C', 'A');
|
||||
graph.addEdge('A', 'D');
|
||||
graph.addEdge('D', 'C');
|
||||
const cycles = graph.getCycles();
|
||||
expect(cycles.length).toBe(3)
|
||||
expect(cycles).toEqual([["A", "B", "C"], ["A", "B", "C", "D"], ["A", "C", "D"]])
|
||||
});
|
||||
|
||||
test('should 3 cycles graph getCycles return correct result', () => {
|
||||
const graph = new UndirectedGraph();
|
||||
|
||||
graph.addVertex('A');
|
||||
graph.addVertex('B');
|
||||
graph.addVertex('C');
|
||||
graph.addVertex('D');
|
||||
graph.addVertex('E');
|
||||
graph.addVertex('F');
|
||||
graph.addVertex('G');
|
||||
|
||||
graph.addEdge('A', 'B');
|
||||
graph.addEdge('A', 'C');
|
||||
graph.addEdge('B', 'D');
|
||||
graph.addEdge('C', 'D');
|
||||
graph.addEdge('D', 'E');
|
||||
graph.addEdge('E', 'B');
|
||||
graph.addEdge('B', 'F');
|
||||
graph.addEdge('F', 'E');
|
||||
graph.addEdge('C', 'G');
|
||||
graph.addEdge('G', 'A');
|
||||
|
||||
const cycles = graph.getCycles();
|
||||
expect(cycles.length).toBe(10)
|
||||
expect(cycles).toEqual([["A", "B", "D", "C"], ["A", "B", "D", "C", "G"], ["A", "B", "E", "D", "C"], ["A", "B", "E", "D", "C", "G"], ["A", "B", "F", "E", "D", "C"], ["A", "B", "F", "E", "D", "C", "G"], ["A", "C", "G"], ["B", "D", "E"], ["B", "D", "E", "F"], ["B", "E", "F"]]);
|
||||
});
|
||||
})
|
|
@ -5,7 +5,12 @@ import { logBigOMetricsWrap } from '../../../utils';
|
|||
describe('Heap Operation Test', () => {
|
||||
it('should numeric heap work well', function () {
|
||||
const minNumHeap = new MinHeap<number>();
|
||||
minNumHeap.add(1);minNumHeap.add(6);minNumHeap.add(2);minNumHeap.add(0);minNumHeap.add(5);minNumHeap.add(9);
|
||||
minNumHeap.add(1);
|
||||
minNumHeap.add(6);
|
||||
minNumHeap.add(2);
|
||||
minNumHeap.add(0);
|
||||
minNumHeap.add(5);
|
||||
minNumHeap.add(9);
|
||||
expect(minNumHeap.has(1)).toBe(true);
|
||||
expect(minNumHeap.has(2)).toBe(true);
|
||||
expect(minNumHeap.poll()).toBe(0);
|
||||
|
|
Loading…
Reference in a new issue