refactor: Unify the return types of all methods and align them with Java, extract the print and hasValue methods to base class. This will make the code more consistent and easier to understand.

This commit is contained in:
Revone 2023-12-12 21:14:17 +08:00
parent 61369adbdd
commit 3e97e806ba
28 changed files with 498 additions and 542 deletions

View file

@ -1005,10 +1005,10 @@ avl2.print();
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>100,000 add & pop</td><td>80.37</td><td>12.44</td><td>0.00</td></tr><tr><td>100,000 add & dfs</td><td>36.20</td><td>27.63</td><td>0.00</td></tr><tr><td>10,000 fib add & pop</td><td>362.24</td><td>2.76</td><td>0.00</td></tr></table></div>
</div><div class="json-to-html-collapse clearfix 0">
<div class='collapsible level0' ><span class='json-to-html-label'>doubly-linked-list</span></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000,000 push</td><td>216.09</td><td>4.63</td><td>0.06</td></tr><tr><td>1,000,000 unshift</td><td>220.68</td><td>4.53</td><td>0.02</td></tr><tr><td>1,000,000 unshift & shift</td><td>172.93</td><td>5.78</td><td>0.04</td></tr><tr><td>1,000,000 insertBefore</td><td>332.25</td><td>3.01</td><td>0.08</td></tr></table></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000,000 push</td><td>216.09</td><td>4.63</td><td>0.06</td></tr><tr><td>1,000,000 unshift</td><td>220.68</td><td>4.53</td><td>0.02</td></tr><tr><td>1,000,000 unshift & shift</td><td>172.93</td><td>5.78</td><td>0.04</td></tr><tr><td>1,000,000 addBefore</td><td>332.25</td><td>3.01</td><td>0.08</td></tr></table></div>
</div><div class="json-to-html-collapse clearfix 0">
<div class='collapsible level0' ><span class='json-to-html-label'>singly-linked-list</span></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000,000 push & shift</td><td>222.99</td><td>4.48</td><td>0.10</td></tr><tr><td>10,000 push & pop</td><td>214.82</td><td>4.66</td><td>0.01</td></tr><tr><td>10,000 insertBefore</td><td>251.24</td><td>3.98</td><td>0.01</td></tr></table></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000,000 push & shift</td><td>222.99</td><td>4.48</td><td>0.10</td></tr><tr><td>10,000 push & pop</td><td>214.82</td><td>4.66</td><td>0.01</td></tr><tr><td>10,000 addBefore</td><td>251.24</td><td>3.98</td><td>0.01</td></tr></table></div>
</div><div class="json-to-html-collapse clearfix 0">
<div class='collapsible level0' ><span class='json-to-html-label'>max-priority-queue</span></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>10,000 refill & poll</td><td>8.91</td><td>112.19</td><td>1.57e-4</td></tr></table></div>

View file

@ -990,10 +990,10 @@ avl2.print();
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>100,000 add & pop</td><td>90.67</td><td>11.03</td><td>0.02</td></tr><tr><td>100,000 add & dfs</td><td>40.30</td><td>24.81</td><td>0.01</td></tr><tr><td>10,000 fib add & pop</td><td>414.94</td><td>2.41</td><td>0.02</td></tr></table></div>
</div><div class="json-to-html-collapse clearfix 0">
<div class='collapsible level0' ><span class='json-to-html-label'>doubly-linked-list</span></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000,000 push</td><td>290.62</td><td>3.44</td><td>0.10</td></tr><tr><td>1,000,000 unshift</td><td>253.88</td><td>3.94</td><td>0.10</td></tr><tr><td>1,000,000 unshift & shift</td><td>259.65</td><td>3.85</td><td>0.14</td></tr><tr><td>1,000,000 insertBefore</td><td>463.16</td><td>2.16</td><td>0.10</td></tr></table></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000,000 push</td><td>290.62</td><td>3.44</td><td>0.10</td></tr><tr><td>1,000,000 unshift</td><td>253.88</td><td>3.94</td><td>0.10</td></tr><tr><td>1,000,000 unshift & shift</td><td>259.65</td><td>3.85</td><td>0.14</td></tr><tr><td>1,000,000 addBefore</td><td>463.16</td><td>2.16</td><td>0.10</td></tr></table></div>
</div><div class="json-to-html-collapse clearfix 0">
<div class='collapsible level0' ><span class='json-to-html-label'>singly-linked-list</span></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000,000 push & shift</td><td>250.27</td><td>4.00</td><td>0.08</td></tr><tr><td>10,000 push & pop</td><td>261.13</td><td>3.83</td><td>0.03</td></tr><tr><td>10,000 insertBefore</td><td>282.46</td><td>3.54</td><td>0.02</td></tr></table></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000,000 push & shift</td><td>250.27</td><td>4.00</td><td>0.08</td></tr><tr><td>10,000 push & pop</td><td>261.13</td><td>3.83</td><td>0.03</td></tr><tr><td>10,000 addBefore</td><td>282.46</td><td>3.54</td><td>0.02</td></tr></table></div>
</div><div class="json-to-html-collapse clearfix 0">
<div class='collapsible level0' ><span class='json-to-html-label'>max-priority-queue</span></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>10,000 refill & poll</td><td>10.49</td><td>95.29</td><td>0.00</td></tr></table></div>

View file

@ -181,6 +181,21 @@ export abstract class IterableEntryBase<K = any, V = any> {
return accumulator;
}
hasValue(value: V): boolean {
for (const [, elementValue] of this) {
if (elementValue === value) return true;
}
return false;
}
/**
* Time Complexity: O(n)
* Space Complexity: O(n)
*/
print(): void {
console.log([...this])
}
protected abstract _getIterator(...args: any[]): IterableIterator<[K, V]>;
}
@ -325,5 +340,14 @@ export abstract class IterableElementBase<V> {
return accumulator;
}
/**
* Time Complexity: O(n)
* Space Complexity: O(n)
*/
print(): void {
console.log([...this])
}
protected abstract _getIterator(...args: any[]): IterableIterator<V>;
}

View file

@ -35,7 +35,6 @@ export class HashMap<K = any, V = any> extends IterableEntryBase<K, V> {
const { hashFn } = options;
if (hashFn) {
this._hashFn = hashFn;
}
}
if (elements) {
@ -68,8 +67,7 @@ export class HashMap<K = any, V = any> extends IterableEntryBase<K, V> {
* @param {V} value - The value parameter represents the value that you want to associate with the
* key in the data structure.
*/
set(key: K, value: V) {
set(key: K, value: V): boolean {
if (this._isObjKey(key)) {
if (!this._objMap.has(key)) {
this._size++;
@ -83,6 +81,7 @@ export class HashMap<K = any, V = any> extends IterableEntryBase<K, V> {
}
this._store[strKey] = { key, value };
}
return true;
}
/**
@ -90,8 +89,10 @@ export class HashMap<K = any, V = any> extends IterableEntryBase<K, V> {
* @param elements - The `elements` parameter is an iterable containing key-value pairs. Each
* key-value pair is represented as an array with two elements: the key and the value.
*/
setMany(elements: Iterable<[K, V]>) {
for (const [key, value] of elements) this.set(key, value);
setMany(elements: Iterable<[K, V]>): boolean[] {
const results: boolean[] = [];
for (const [key, value] of elements) results.push(this.set(key, value));
return results;
}
/**
@ -215,6 +216,10 @@ export class HashMap<K = any, V = any> extends IterableEntryBase<K, V> {
console.log([...this.entries()]);
}
put(key: K, value: V): boolean {
return this.set(key, value);
}
/**
* The function returns an iterator that yields key-value pairs from both an object store and an
* object map.
@ -286,7 +291,6 @@ export class LinkedHashMap<K = any, V = any> extends IterableEntryBase<K, V> {
this.set(el[0], el[1]);
}
}
}
protected _size = 0;
@ -356,7 +360,7 @@ export class LinkedHashMap<K = any, V = any> extends IterableEntryBase<K, V> {
* value associated with the key being set in the data structure.
* @returns the size of the data structure after the key-value pair has been set.
*/
set(key: K, value?: V) {
set(key: K, value?: V): boolean {
let node;
const isNewKey = !this.has(key); // Check if the key is new
@ -398,7 +402,7 @@ export class LinkedHashMap<K = any, V = any> extends IterableEntryBase<K, V> {
this._size++;
}
return this._size;
return true;
}
has(key: K): boolean {
@ -411,18 +415,13 @@ export class LinkedHashMap<K = any, V = any> extends IterableEntryBase<K, V> {
}
}
hasValue(value: V): boolean {
for (const [, elementValue] of this) {
if (elementValue === value) return true;
}
return false;
}
setMany(entries: Iterable<[K, V]>): void {
setMany(entries: Iterable<[K, V]>): boolean[] {
const results: boolean[] = [];
for (const entry of entries) {
const [key, value] = entry;
this.set(key, value);
results.push(this.set(key, value));
}
return results;
}
/**
@ -461,13 +460,13 @@ export class LinkedHashMap<K = any, V = any> extends IterableEntryBase<K, V> {
* the specified index in the data structure. The key-value pair is represented as a tuple `[K, V]`,
* where `K` is the key and `V` is the value.
*/
getAt(index: number) {
getAt(index: number): V | undefined {
rangeCheck(index, 0, this._size - 1);
let node = this._head;
while (index--) {
node = node.next;
}
return <[K, V]>[node.key, node.value];
return node.value;
}
/**
@ -480,7 +479,7 @@ export class LinkedHashMap<K = any, V = any> extends IterableEntryBase<K, V> {
* @returns a boolean value. It returns `true` if the deletion was successful, and `false` if the key
* was not found.
*/
delete(key: K) {
delete(key: K): boolean {
let node;
if (isWeakKey(key)) {
@ -521,14 +520,13 @@ export class LinkedHashMap<K = any, V = any> extends IterableEntryBase<K, V> {
* deleted in the linked list.
* @returns The size of the list after deleting the element at the specified index.
*/
deleteAt(index: number) {
deleteAt(index: number): boolean {
rangeCheck(index, 0, this._size - 1);
let node = this._head;
while (index--) {
node = node.next;
}
this._deleteNode(node);
return this._size;
return this._deleteNode(node);
}
/**
@ -539,7 +537,7 @@ export class LinkedHashMap<K = any, V = any> extends IterableEntryBase<K, V> {
* @returns The method is returning a boolean value indicating whether the size of the object is 0 or
* not.
*/
isEmpty() {
isEmpty(): boolean {
return this._size === 0;
}
@ -549,7 +547,7 @@ export class LinkedHashMap<K = any, V = any> extends IterableEntryBase<K, V> {
*
* The `clear` function clears all the elements in a data structure and resets its properties.
*/
clear() {
clear(): void {
this._noObjMap = {};
this._size = 0;
this._head = this._tail = this._sentinel.prev = this._sentinel.next = this._sentinel;
@ -629,8 +627,8 @@ export class LinkedHashMap<K = any, V = any> extends IterableEntryBase<K, V> {
return mappedMap;
}
print() {
console.log([...this]);
put(key: K, value: V): boolean {
return this.set(key, value);
}
/**
@ -657,7 +655,7 @@ export class LinkedHashMap<K = any, V = any> extends IterableEntryBase<K, V> {
* represents a node in a linked list. It contains a key-value pair and references to the previous
* and next nodes in the list.
*/
protected _deleteNode(node: HashMapLinkedNode<K, V | undefined>) {
protected _deleteNode(node: HashMapLinkedNode<K, V | undefined>): boolean {
const { prev, next } = node;
prev.next = next;
next.prev = prev;
@ -671,5 +669,6 @@ export class LinkedHashMap<K = any, V = any> extends IterableEntryBase<K, V> {
}
this._size -= 1;
return true;
}
}

View file

@ -42,7 +42,7 @@ export class Heap<E = any> extends IterableElementBase<E> {
if (elements) {
for (const el of elements) {
this.push(el);
this.add(el);
}
// this.fix();
}
@ -91,26 +91,9 @@ export class Heap<E = any> extends IterableElementBase<E> {
* Insert an element into the heap and maintain the heap properties.
* @param element - The element to be inserted.
*/
add(element: E): Heap<E> {
return this.push(element);
}
/**
* Time Complexity: O(log n), where n is the number of elements in the heap.
* Space Complexity: O(1)
*/
/**
* Time Complexity: O(log n), where n is the number of elements in the heap.
* Space Complexity: O(1)
*
* Insert an element into the heap and maintain the heap properties.
* @param element - The element to be inserted.
*/
push(element: E): Heap<E> {
add(element: E): boolean {
this._elements.push(element);
this._bubbleUp(this.elements.length - 1);
return this;
return this._bubbleUp(this.elements.length - 1);
}
/**
@ -136,22 +119,6 @@ export class Heap<E = any> extends IterableElementBase<E> {
return value;
}
/**
* Time Complexity: O(log n), where n is the number of elements in the heap.
* Space Complexity: O(1)
*/
/**
* Time Complexity: O(log n), where n is the number of elements in the heap.
* Space Complexity: O(1)
*
* Remove and return the top element (smallest or largest element) from the heap.
* @returns The top element or undefined if the heap is empty.
*/
pop(): E | undefined {
return this.poll();
}
/**
* Peek at the top element of the heap without removing it.
* @returns The top element or undefined if the heap is empty.
@ -164,14 +131,14 @@ export class Heap<E = any> extends IterableElementBase<E> {
* Check if the heap is empty.
* @returns True if the heap is empty, otherwise false.
*/
isEmpty() {
isEmpty(): boolean {
return this.size === 0;
}
/**
* Reset the elements of the heap. Make the elements empty.
*/
clear() {
clear(): void {
this._elements = [];
}
@ -187,9 +154,9 @@ export class Heap<E = any> extends IterableElementBase<E> {
* Clear and add elements of the heap
* @param elements
*/
refill(elements: E[]) {
refill(elements: E[]): boolean[] {
this._elements = elements;
this.fix();
return this.fix();
}
/**
@ -225,11 +192,11 @@ export class Heap<E = any> extends IterableElementBase<E> {
* @returns The `delete` function is returning a boolean value. It returns `true` if the element was
* successfully deleted from the array, and `false` if the element was not found in the array.
*/
delete(element: E) {
delete(element: E): boolean {
const index = this.elements.indexOf(element);
if (index < 0) return false;
if (index === 0) {
this.pop();
this.poll();
} else if (index === this.elements.length - 1) {
this.elements.pop();
} else {
@ -348,8 +315,10 @@ export class Heap<E = any> extends IterableElementBase<E> {
*
* Fix the entire heap to maintain heap properties.
*/
fix() {
for (let i = Math.floor(this.size / 2); i >= 0; i--) this._sinkDown(i, this.elements.length >> 1);
fix(): boolean[] {
const results: boolean[] = [];
for (let i = Math.floor(this.size / 2); i >= 0; i--) results.push(this._sinkDown(i, this.elements.length >> 1));
return results;
}
/**
@ -378,7 +347,7 @@ export class Heap<E = any> extends IterableElementBase<E> {
let index = 0;
for (const current of this) {
if (callback.call(thisArg, current, index, this)) {
filteredList.push(current);
filteredList.add(current);
}
index++;
}
@ -421,16 +390,7 @@ export class Heap<E = any> extends IterableElementBase<E> {
return mappedHeap;
}
/**
* Time Complexity: O(log n)
* Space Complexity: O(1)
*/
print(): void {
console.log([...this]);
}
protected* _getIterator() {
protected* _getIterator(): IterableIterator<E> {
for (const element of this.elements) {
yield element;
}
@ -448,7 +408,7 @@ export class Heap<E = any> extends IterableElementBase<E> {
* Float operation to maintain heap properties after adding an element.
* @param index - The index of the newly added element.
*/
protected _bubbleUp(index: number) {
protected _bubbleUp(index: number): boolean {
const element = this.elements[index];
while (index > 0) {
const parent = (index - 1) >> 1;
@ -458,6 +418,7 @@ export class Heap<E = any> extends IterableElementBase<E> {
index = parent;
}
this.elements[index] = element;
return true;
}
/**
@ -468,7 +429,7 @@ export class Heap<E = any> extends IterableElementBase<E> {
* @param index - The index from which to start sinking.
* @param halfLength
*/
protected _sinkDown(index: number, halfLength: number) {
protected _sinkDown(index: number, halfLength: number): boolean {
const element = this.elements[index];
while (index < halfLength) {
let left = index << 1 | 1;
@ -486,6 +447,7 @@ export class Heap<E = any> extends IterableElementBase<E> {
index = left;
}
this.elements[index] = element;
return true;
}
}

View file

@ -33,13 +33,13 @@ export class DoublyLinkedListNode<E = any> {
*/
export class DoublyLinkedList<E = any> extends IterableElementBase<E> {
/**
* The constructor initializes the linked list with an empty head, tail, and length.
* The constructor initializes the linked list with an empty head, tail, and size.
*/
constructor(elements?: Iterable<E>) {
super();
this._head = undefined;
this._tail = undefined;
this._length = 0;
this._size = 0;
if (elements) {
for (const el of elements) {
this.push(el);
@ -59,23 +59,19 @@ export class DoublyLinkedList<E = any> extends IterableElementBase<E> {
return this._tail;
}
protected _length: number;
get length(): number {
return this._length;
}
protected _size: number;
get size(): number {
return this.length;
return this._size;
}
/**
* Time Complexity: O(n), where n is the length of the input array.
* Time Complexity: O(n), where n is the size of the input array.
* Space Complexity: O(n)
*/
/**
* Time Complexity: O(n), where n is the length of the input array.
* Time Complexity: O(n), where n is the size of the input array.
* Space Complexity: O(n)
*
* The `fromArray` function creates a new instance of a DoublyLinkedList and populates it with the elements from the
@ -103,7 +99,7 @@ export class DoublyLinkedList<E = any> extends IterableElementBase<E> {
* The push function adds a new node with the given value to the end of the doubly linked list.
* @param {E} value - The value to be added to the linked list.
*/
push(value: E): void {
push(value: E): boolean {
const newNode = new DoublyLinkedListNode(value);
if (!this.head) {
this._head = newNode;
@ -113,23 +109,8 @@ export class DoublyLinkedList<E = any> extends IterableElementBase<E> {
this.tail!.next = newNode;
this._tail = newNode;
}
this._length++;
}
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*/
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*
* The addLast function adds a new node with the given value to the end of the doubly linked list.
* @param {E} value - The value to be added to the linked list.
*/
addLast(value: E): void {
this.push(value);
this._size++;
return true;
}
/**
@ -155,27 +136,10 @@ export class DoublyLinkedList<E = any> extends IterableElementBase<E> {
this._tail = removedNode.prev;
this.tail!.next = undefined;
}
this._length--;
this._size--;
return removedNode.value;
}
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*/
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*
* The `pollLast()` function removes and returns the value of the last node in a doubly linked list.
* @returns The method is returning the value of the removed node (removedNode.value) if the list is not empty. If the
* list is empty, it returns undefined.
*/
pollLast(): E | undefined {
return this.pop();
}
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
@ -199,27 +163,10 @@ export class DoublyLinkedList<E = any> extends IterableElementBase<E> {
this._head = removedNode.next;
this.head!.prev = undefined;
}
this._length--;
this._size--;
return removedNode.value;
}
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*/
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*
* The `pollFirst()` function removes and returns the value of the first node in a doubly linked list.
* @returns The method `shift()` returns the value of the node that is removed from the beginning of the doubly linked
* list.
*/
pollFirst(): E | undefined {
return this.shift();
}
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
@ -233,7 +180,7 @@ export class DoublyLinkedList<E = any> extends IterableElementBase<E> {
* @param {E} value - The `value` parameter represents the value of the new node that will be added to the beginning of the
* doubly linked list.
*/
unshift(value: E): void {
unshift(value: E): boolean {
const newNode = new DoublyLinkedListNode(value);
if (!this.head) {
this._head = newNode;
@ -243,56 +190,8 @@ export class DoublyLinkedList<E = any> extends IterableElementBase<E> {
this.head!.prev = newNode;
this._head = newNode;
}
this._length++;
}
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*/
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*
* The addFirst function adds a new node with the given value to the beginning of a doubly linked list.
* @param {E} value - The `value` parameter represents the value of the new node that will be added to the beginning of the
* doubly linked list.
*/
addFirst(value: E): void {
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 `getFirst` function returns the first node in a doubly linked list, or undefined if the list is empty.
* @returns The method `getFirst()` returns the first node of the doubly linked list, or `undefined` if the list is empty.
*/
getFirst(): 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 `getLast` function returns the last node in a doubly linked list, or undefined if the list is empty.
* @returns The method `getLast()` returns the last node of the doubly linked list, or `undefined` if the list is empty.
*/
getLast(): E | undefined {
return this.tail?.value;
this._size++;
return true;
}
/**
@ -311,7 +210,7 @@ export class DoublyLinkedList<E = any> extends IterableElementBase<E> {
* or the linked list is empty, it will return undefined.
*/
getAt(index: number): E | undefined {
if (index < 0 || index >= this.length) return undefined;
if (index < 0 || index >= this.size) return undefined;
let current = this.head;
for (let i = 0; i < index; i++) {
current = current!.next;
@ -336,7 +235,7 @@ export class DoublyLinkedList<E = any> extends IterableElementBase<E> {
* valid range of the linked list, otherwise it returns `undefined`.
*/
getNodeAt(index: number): DoublyLinkedListNode<E> | undefined {
if (index < 0 || index >= this.length) return undefined;
if (index < 0 || index >= this.size) return undefined;
let current = this.head;
for (let i = 0; i < index; i++) {
current = current!.next;
@ -389,13 +288,13 @@ export class DoublyLinkedList<E = any> extends IterableElementBase<E> {
* @returns The `insert` method returns a boolean value. It returns `true` if the insertion is successful, and `false`
* if the index is out of bounds.
*/
insertAt(index: number, value: E): boolean {
if (index < 0 || index > this.length) return false;
addAt(index: number, value: E): boolean {
if (index < 0 || index > this.size) return false;
if (index === 0) {
this.unshift(value);
return true;
}
if (index === this.length) {
if (index === this.size) {
this.push(value);
return true;
}
@ -407,7 +306,7 @@ export class DoublyLinkedList<E = any> extends IterableElementBase<E> {
newNode.next = nextNode;
prevNode!.next = newNode;
nextNode!.prev = newNode;
this._length++;
this._size++;
return true;
}
@ -420,7 +319,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)
*
* The `insertBefore` function inserts a new value before an existing value or node in a doubly linked list.
* The `addBefore` function inserts a new value before an existing value or node in a doubly linked list.
* @param {E | DoublyLinkedListNode<E>} existingValueOrNode - The existing value or node in the doubly linked list
* before which the new value will be inserted. It can be either the value of the existing node or the existing node
* itself.
@ -429,7 +328,7 @@ export class DoublyLinkedList<E = any> extends IterableElementBase<E> {
* @returns The method returns a boolean value. It returns `true` if the insertion is successful, and `false` if the
* insertion fails.
*/
insertBefore(existingValueOrNode: E | DoublyLinkedListNode<E>, newValue: E): boolean {
addBefore(existingValueOrNode: E | DoublyLinkedListNode<E>, newValue: E): boolean {
let existingNode;
if (existingValueOrNode instanceof DoublyLinkedListNode) {
@ -449,7 +348,7 @@ export class DoublyLinkedList<E = any> extends IterableElementBase<E> {
if (existingNode === this.head) {
this._head = newNode;
}
this._length++;
this._size++;
return true;
}
@ -465,7 +364,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)
*
* The `insertAfter` function inserts a new node with a given value after an existing node in a doubly linked list.
* The `addAfter` function inserts a new node with a given value after an existing node in a doubly linked list.
* @param {E | DoublyLinkedListNode<E>} existingValueOrNode - The existing value or node in the doubly linked list
* after which the new value will be inserted. It can be either the value of the existing node or the existing node
* itself.
@ -473,7 +372,7 @@ export class DoublyLinkedList<E = any> extends IterableElementBase<E> {
* @returns The method returns a boolean value. It returns true if the insertion is successful, and false if the
* existing value or node is not found in the doubly linked list.
*/
insertAfter(existingValueOrNode: E | DoublyLinkedListNode<E>, newValue: E): boolean {
addAfter(existingValueOrNode: E | DoublyLinkedListNode<E>, newValue: E): boolean {
let existingNode;
if (existingValueOrNode instanceof DoublyLinkedListNode) {
@ -493,7 +392,7 @@ export class DoublyLinkedList<E = any> extends IterableElementBase<E> {
if (existingNode === this.tail) {
this._tail = newNode;
}
this._length++;
this._size++;
return true;
}
@ -515,18 +414,24 @@ export class DoublyLinkedList<E = any> extends IterableElementBase<E> {
* @returns The method `deleteAt` returns the value of the node that was deleted, or `undefined` if the index is out of
* bounds.
*/
deleteAt(index: number): E | undefined {
if (index < 0 || index >= this.length) return undefined;
if (index === 0) return this.shift();
if (index === this.length - 1) return this.pop();
deleteAt(index: number): boolean {
if (index < 0 || index >= this.size) return false;
if (index === 0) {
this.shift();
return true;
}
if (index === this.size - 1) {
this.pop();
return true;
}
const removedNode = this.getNodeAt(index);
const prevNode = removedNode!.prev;
const nextNode = removedNode!.next;
prevNode!.next = nextNode;
nextNode!.prev = prevNode;
this._length--;
return removedNode!.value;
this._size--;
return true;
}
/**
@ -563,7 +468,7 @@ export class DoublyLinkedList<E = any> extends IterableElementBase<E> {
const nextNode = node.next;
prevNode!.next = nextNode;
nextNode!.prev = prevNode;
this._length--;
this._size--;
}
return true;
}
@ -571,20 +476,20 @@ export class DoublyLinkedList<E = any> extends IterableElementBase<E> {
}
/**
* The function checks if a variable has a length greater than zero and returns a boolean value.
* The function checks if a variable has a size greater than zero and returns a boolean value.
* @returns A boolean value is being returned.
*/
isEmpty(): boolean {
return this.length === 0;
return this.size === 0;
}
/**
* The `clear` function resets the linked list by setting the head, tail, and length to undefined and 0 respectively.
* The `clear` function resets the linked list by setting the head, tail, and size to undefined and 0 respectively.
*/
clear(): void {
this._head = undefined;
this._tail = undefined;
this._length = 0;
this._size = 0;
}
/**
@ -679,7 +584,7 @@ export class DoublyLinkedList<E = any> extends IterableElementBase<E> {
*
* The `reverse` function reverses the order of the elements in a doubly linked list.
*/
reverse(): void {
reverse(): this {
let current = this.head;
[this._head, this._tail] = [this.tail, this.head];
while (current) {
@ -687,6 +592,7 @@ export class DoublyLinkedList<E = any> extends IterableElementBase<E> {
[current.prev, current.next] = [current.next, current.prev];
current = next;
}
return this;
}
/**
@ -801,12 +707,102 @@ 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)
*/
print(): void {
console.log([...this]);
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*
* The addLast function adds a new node with the given value to the end of the doubly linked list.
* @param {E} value - The value to be added to the linked list.
*/
addLast(value: E): boolean {
return this.push(value);
}
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*/
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*
* The `pollLast()` function removes and returns the value of the last node in a doubly linked list.
* @returns The method is returning the value of the removed node (removedNode.value) if the list is not empty. If the
* list is empty, it returns undefined.
*/
pollLast(): E | undefined {
return this.pop();
}
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*/
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*
* The `pollFirst()` function removes and returns the value of the first node in a doubly linked list.
* @returns The method `shift()` returns the value of the node that is removed from the beginning of the doubly linked
* list.
*/
pollFirst(): E | undefined {
return this.shift();
}
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*/
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*
* The addFirst function adds a new node with the given value to the beginning of a doubly linked list.
* @param {E} value - The `value` parameter represents the value of the new node that will be added to the beginning of the
* doubly linked list.
*/
addFirst(value: E): void {
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;
}
/**

View file

@ -31,7 +31,7 @@ export class SinglyLinkedList<E = any> extends IterableElementBase<E> {
super();
this._head = undefined;
this._tail = undefined;
this._length = 0;
this._size = 0;
if (elements) {
for (const el of elements)
this.push(el);
@ -50,10 +50,10 @@ export class SinglyLinkedList<E = any> extends IterableElementBase<E> {
return this._tail;
}
protected _length: number;
protected _size: number;
get length(): number {
return this._length;
get size(): number {
return this._size;
}
/**
@ -91,7 +91,7 @@ export class SinglyLinkedList<E = any> extends IterableElementBase<E> {
* @param {E} value - The "value" parameter represents the value that you want to add to the linked list. It can be of
* any type (E) as specified in the generic type declaration of the class or function.
*/
push(value: E): void {
push(value: E): boolean {
const newNode = new SinglyLinkedListNode(value);
if (!this.head) {
this._head = newNode;
@ -100,7 +100,8 @@ export class SinglyLinkedList<E = any> extends IterableElementBase<E> {
this.tail!.next = newNode;
this._tail = newNode;
}
this._length++;
this._size++;
return true;
}
/**
@ -116,8 +117,8 @@ export class SinglyLinkedList<E = any> extends IterableElementBase<E> {
* @param {E} value - The "value" parameter represents the value that you want to add to the linked list. It can be of
* any type (E) as specified in the generic type declaration of the class or function.
*/
addLast(value: E): void {
this.push(value);
addLast(value: E): boolean {
return this.push(value);
}
/**
@ -140,7 +141,7 @@ export class SinglyLinkedList<E = any> extends IterableElementBase<E> {
const value = this.head.value;
this._head = undefined;
this._tail = undefined;
this._length--;
this._size--;
return value;
}
@ -151,7 +152,7 @@ export class SinglyLinkedList<E = any> extends IterableElementBase<E> {
const value = this.tail!.value;
current.next = undefined;
this._tail = current;
this._length--;
this._size--;
return value;
}
@ -189,7 +190,7 @@ export class SinglyLinkedList<E = any> extends IterableElementBase<E> {
if (!this.head) return undefined;
const removedNode = this.head;
this._head = this.head.next;
this._length--;
this._size--;
return removedNode.value;
}
@ -222,7 +223,7 @@ export class SinglyLinkedList<E = any> extends IterableElementBase<E> {
* @param {E} value - The parameter "value" represents the value of the new node that will be added to the beginning of the
* linked list.
*/
unshift(value: E): void {
unshift(value: E): boolean {
const newNode = new SinglyLinkedListNode(value);
if (!this.head) {
this._head = newNode;
@ -231,7 +232,8 @@ export class SinglyLinkedList<E = any> extends IterableElementBase<E> {
newNode.next = this.head;
this._head = newNode;
}
this._length++;
this._size++;
return true;
}
/**
@ -247,8 +249,8 @@ export class SinglyLinkedList<E = any> extends IterableElementBase<E> {
* @param {E} value - The parameter "value" represents the value of the new node that will be added to the beginning of the
* linked list.
*/
addFirst(value: E): void {
this.unshift(value);
addFirst(value: E): boolean {
return this.unshift(value);
}
/**
@ -267,7 +269,7 @@ export class SinglyLinkedList<E = any> extends IterableElementBase<E> {
* `undefined` if the index is out of bounds.
*/
getAt(index: number): E | undefined {
if (index < 0 || index >= this.length) return undefined;
if (index < 0 || index >= this.size) return undefined;
let current = this.head;
for (let i = 0; i < index; i++) {
current = current!.next;
@ -313,16 +315,22 @@ export class SinglyLinkedList<E = any> extends IterableElementBase<E> {
* @returns The method `deleteAt` returns the value of the node that was deleted, or `undefined` if the index is out of
* bounds.
*/
deleteAt(index: number): E | undefined {
if (index < 0 || index >= this.length) return undefined;
if (index === 0) return this.shift();
if (index === this.length - 1) return this.pop();
deleteAt(index: number): boolean {
if (index < 0 || index >= this.size) return false;
if (index === 0) {
this.shift();
return true;
}
if (index === this.size - 1) {
this.pop();
return true;
}
const prevNode = this.getNodeAt(index - 1);
const removedNode = prevNode!.next;
prevNode!.next = removedNode!.next;
this._length--;
return removedNode!.value;
this._size--;
return true;
}
/**
@ -340,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 | undefined): boolean {
delete(valueOrNode: E | SinglyLinkedListNode<E> | undefined ): boolean {
if (!valueOrNode) return false;
let value: E;
if (valueOrNode instanceof SinglyLinkedListNode) {
@ -364,7 +372,7 @@ export class SinglyLinkedList<E = any> extends IterableElementBase<E> {
this._tail = prev;
}
}
this._length--;
this._size--;
return true;
}
prev = current;
@ -383,7 +391,7 @@ export class SinglyLinkedList<E = any> extends IterableElementBase<E> {
* Time Complexity: O(n) - Linear time, where n is the index, as it may need to traverse the list to find the desired node.
* Space Complexity: O(1) - Constant space.
*
* The `insertAt` function inserts a value at a specified index in a singly linked list.
* The `addAt` function inserts a value at a specified index in a singly linked list.
* @param {number} index - The index parameter represents the position at which the new value should be inserted in the
* linked list. It is of type number.
* @param {E} value - The `value` parameter represents the value that you want to insert into the linked list at the
@ -391,13 +399,13 @@ export class SinglyLinkedList<E = any> extends IterableElementBase<E> {
* @returns The `insert` method returns a boolean value. It returns `true` if the insertion is successful, and `false`
* if the index is out of bounds.
*/
insertAt(index: number, value: E): boolean {
if (index < 0 || index > this.length) return false;
addAt(index: number, value: E): boolean {
if (index < 0 || index > this.size) return false;
if (index === 0) {
this.unshift(value);
return true;
}
if (index === this.length) {
if (index === this.size) {
this.push(value);
return true;
}
@ -406,7 +414,7 @@ export class SinglyLinkedList<E = any> extends IterableElementBase<E> {
const prevNode = this.getNodeAt(index - 1);
newNode.next = prevNode!.next;
prevNode!.next = newNode;
this._length++;
this._size++;
return true;
}
@ -416,7 +424,7 @@ export class SinglyLinkedList<E = any> extends IterableElementBase<E> {
* @returns A boolean value indicating whether the length of the object is equal to 0.
*/
isEmpty(): boolean {
return this.length === 0;
return this.size === 0;
}
/**
@ -425,7 +433,7 @@ export class SinglyLinkedList<E = any> extends IterableElementBase<E> {
clear(): void {
this._head = undefined;
this._tail = undefined;
this._length = 0;
this._size = 0;
}
/**
@ -462,8 +470,8 @@ export class SinglyLinkedList<E = any> extends IterableElementBase<E> {
* The `reverse` function reverses the order of the nodes in a singly linked list.
* @returns The reverse() method does not return anything. It has a return type of void.
*/
reverse(): void {
if (!this.head || this.head === this.tail) return;
reverse(): this {
if (!this.head || this.head === this.tail) return this;
let prev: SinglyLinkedListNode<E> | undefined = undefined;
let current: SinglyLinkedListNode<E> | undefined = this.head;
@ -477,6 +485,7 @@ export class SinglyLinkedList<E = any> extends IterableElementBase<E> {
}
[this._head, this._tail] = [this.tail!, this.head!];
return this;
}
/**
@ -571,14 +580,14 @@ export class SinglyLinkedList<E = any> extends IterableElementBase<E> {
* Time Complexity: O(n) - Linear time, where n is the length of the list, as it needs to reverse the pointers of each node.
* Space Complexity: O(1) - Constant space.
*
* The `insertBefore` function inserts a new value before an existing value in a singly linked list.
* The `addBefore` function inserts a new value before an existing value in a singly linked list.
* @param {E | SinglyLinkedListNode<E>} existingValueOrNode - The existing value or node that you want to insert the
* new value before. It can be either the value itself or a node containing the value in the linked list.
* @param {E} newValue - The `newValue` parameter represents the value that you want to insert into the linked list.
* @returns The method `insertBefore` returns a boolean value. It returns `true` if the new value was successfully
* @returns The method `addBefore` returns a boolean value. It returns `true` if the new value was successfully
* inserted before the existing value, and `false` otherwise.
*/
insertBefore(existingValueOrNode: E | SinglyLinkedListNode<E>, newValue: E): boolean {
addBefore(existingValueOrNode: E | SinglyLinkedListNode<E>, newValue: E): boolean {
if (!this.head) return false;
let existingValue: E;
@ -598,7 +607,7 @@ export class SinglyLinkedList<E = any> extends IterableElementBase<E> {
const newNode = new SinglyLinkedListNode(newValue);
newNode.next = current.next;
current.next = newNode;
this._length++;
this._size++;
return true;
}
current = current.next;
@ -616,14 +625,14 @@ export class SinglyLinkedList<E = any> extends IterableElementBase<E> {
* Time Complexity: O(n) - Linear time, where n is the length of the list, as it needs to reverse the pointers of each node.
* Space Complexity: O(1) - Constant space.
*
* The `insertAfter` function inserts a new node with a given value after an existing node in a singly linked list.
* The `addAfter` function inserts a new node with a given value after an existing node in a singly linked list.
* @param {E | SinglyLinkedListNode<E>} existingValueOrNode - The existing value or node in the linked list after which
* the new value will be inserted. It can be either the value of the existing node or the existing node itself.
* @param {E} newValue - The value that you want to insert into the linked list after the existing value or node.
* @returns The method returns a boolean value. It returns true if the new value was successfully inserted after the
* existing value or node, and false if the existing value or node was not found in the linked list.
*/
insertAfter(existingValueOrNode: E | SinglyLinkedListNode<E>, newValue: E): boolean {
addAfter(existingValueOrNode: E | SinglyLinkedListNode<E>, newValue: E): boolean {
let existingNode: E | SinglyLinkedListNode<E> | undefined;
if (existingValueOrNode instanceof SinglyLinkedListNode) {
@ -639,7 +648,7 @@ export class SinglyLinkedList<E = any> extends IterableElementBase<E> {
if (existingNode === this.tail) {
this._tail = newNode;
}
this._length++;
this._size++;
return true;
}
@ -737,15 +746,6 @@ export class SinglyLinkedList<E = any> extends IterableElementBase<E> {
return mappedList;
}
/**
* Time Complexity: O(n), where n is the number of elements in the linked list.
* Space Complexity: O(n)
*/
print(): void {
console.log([...this]);
}
protected* _getIterator(): IterableIterator<E> {
let current = this.head;

View file

@ -193,7 +193,7 @@ export class SkipList<K, V> {
* 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 {
get first(): V | undefined {
const firstNode = this.head.forward[0];
return firstNode ? firstNode.value : undefined;
}
@ -210,7 +210,7 @@ export class SkipList<K, V> {
* 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 {
get last(): V | undefined {
let current = this.head;
for (let i = this.level - 1; i >= 0; i--) {
while (current.forward[i]) {

View file

@ -83,106 +83,6 @@ export class Deque<E> extends IterableElementBase<E> {
return this._buckets[this._bucketLast][this._lastInBucket];
}
/**
* Time Complexity: O(1) - Removes the last element.
* Space Complexity: O(1) - Operates in-place.
*/
isEmpty() {
return this.size === 0;
}
/**
* Time Complexity: Amortized O(1) - Similar to push, resizing leads to O(n).
* Space Complexity: O(n) - Due to potential resizing.
*/
/**
* Time Complexity: O(1)
* Space Complexity: O(n) - In worst case, resizing doubles the array size.
*
* The addLast function adds an element to the end of an array.
* @param {E} element - The element parameter represents the element that you want to add to the end of the
* data structure.
*/
addLast(element: E): void {
this.push(element);
}
/**
* Time Complexity: O(1) - Removes the first element.
* Space Complexity: O(1) - In-place operation.
*/
/**
* Time Complexity: O(1) - Removes the last element.
* Space Complexity: O(1) - Operates in-place.
*
* The function "pollLast" removes and returns the last element of an array.
* @returns The last element of the array is being returned.
*/
pollLast(): E | undefined {
return this.pop();
}
/**
* Time Complexity: O(1).
* Space Complexity: O(n) - Due to potential resizing.
*
* The "addFirst" function adds an element to the beginning of an array.
* @param {E} element - The parameter "element" represents the element that you want to add to the
* beginning of the data structure.
*/
addFirst(element: E): void {
this.unshift(element);
}
/**
* Time Complexity: O(1) - Removes the first element.
* Space Complexity: O(1) - In-place operation.
*
* The function "pollFirst" removes and returns the first element of an array.
* @returns The method `pollFirst()` is returning the first element of the array after removing it
* from the beginning. If the array is empty, it will return `undefined`.
*/
pollFirst(): E | undefined {
return this.shift();
}
/**
* The clear() function resets the state of the object by initializing all variables to their default
* values.
*/
clear() {
this._buckets = [new Array(this._bucketSize)];
this._bucketCount = 1;
this._bucketFirst = this._bucketLast = this._size = 0;
this._firstInBucket = this._lastInBucket = this._bucketSize >> 1;
}
/**
* The below function is a generator that yields elements from a collection one by one.
*/
* begin(): Generator<E> {
let index = 0;
while (index < this.size) {
yield this.getAt(index);
index++;
}
}
/**
* The function `reverseBegin()` is a generator that yields elements in reverse order starting from
* the last element.
*/
* reverseBegin(): Generator<E> {
let index = this.size - 1;
while (index >= 0) {
yield this.getAt(index);
index--;
}
}
/**
* Time Complexity - Amortized O(1) (possible reallocation)
* Space Complexity - O(n) (due to potential resizing).
@ -197,7 +97,7 @@ export class Deque<E> extends IterableElementBase<E> {
* structure.
* @returns The size of the data structure after the element has been pushed.
*/
push(element: E) {
push(element: E): boolean {
if (this.size) {
if (this._lastInBucket < this._bucketSize - 1) {
this._lastInBucket += 1;
@ -215,7 +115,7 @@ export class Deque<E> extends IterableElementBase<E> {
}
this._size += 1;
this._buckets[this._bucketLast][this._lastInBucket] = element;
return this.size;
return true;
}
/**
@ -231,7 +131,7 @@ export class Deque<E> extends IterableElementBase<E> {
* internal state variables accordingly.
* @returns The element that was removed from the data structure is being returned.
*/
pop() {
pop(): E | undefined {
if (this.size === 0) return;
const element = this._buckets[this._bucketLast][this._lastInBucket];
if (this.size !== 1) {
@ -264,7 +164,7 @@ export class Deque<E> extends IterableElementBase<E> {
* beginning of the data structure.
* @returns The size of the data structure after the element has been added.
*/
unshift(element: E) {
unshift(element: E): boolean {
if (this.size) {
if (this._firstInBucket > 0) {
this._firstInBucket -= 1;
@ -282,10 +182,9 @@ export class Deque<E> extends IterableElementBase<E> {
}
this._size += 1;
this._buckets[this._bucketFirst][this._firstInBucket] = element;
return this.size;
return true;
}
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
@ -300,7 +199,7 @@ export class Deque<E> extends IterableElementBase<E> {
* @returns The element that is being removed from the beginning of the data structure is being
* returned.
*/
shift() {
shift(): E | undefined {
if (this.size === 0) return;
const element = this._buckets[this._bucketFirst][this._firstInBucket];
if (this.size !== 1) {
@ -318,6 +217,49 @@ export class Deque<E> extends IterableElementBase<E> {
return element;
}
/**
* Time Complexity: O(1) - Removes the last element.
* Space Complexity: O(1) - Operates in-place.
*/
isEmpty(): boolean {
return this.size === 0;
}
/**
* The clear() function resets the state of the object by initializing all variables to their default
* values.
*/
clear(): void {
this._buckets = [new Array(this._bucketSize)];
this._bucketCount = 1;
this._bucketFirst = this._bucketLast = this._size = 0;
this._firstInBucket = this._lastInBucket = this._bucketSize >> 1;
}
/**
* The below function is a generator that yields elements from a collection one by one.
*/
* begin(): Generator<E> {
let index = 0;
while (index < this.size) {
yield this.getAt(index);
index++;
}
}
/**
* The function `reverseBegin()` is a generator that yields elements in reverse order starting from
* the last element.
*/
* reverseBegin(): Generator<E> {
let index = this.size - 1;
while (index >= 0) {
yield this.getAt(index);
index--;
}
}
/**
* Time Complexity: O(1)
@ -359,13 +301,14 @@ export class Deque<E> extends IterableElementBase<E> {
* @param {E} element - The `element` parameter is the value that you want to set at the specified
* position in the data structure.
*/
setAt(pos: number, element: E) {
setAt(pos: number, element: E): boolean {
rangeCheck(pos, 0, this.size - 1);
const {
bucketIndex,
indexInBucket
} = this._getBucketAndPosition(pos);
this._buckets[bucketIndex][indexInBucket] = element;
return true;
}
/**
@ -377,7 +320,7 @@ export class Deque<E> extends IterableElementBase<E> {
* Time Complexity: O(n)
* Space Complexity: O(n)
*
* The `insertAt` function inserts one or more elements at a specified position in an array-like data
* The `addAt` function inserts one or more elements at a specified position in an array-like data
* structure.
* @param {number} pos - The `pos` parameter represents the position at which the element(s) should
* be inserted. It is of type `number`.
@ -388,7 +331,7 @@ export class Deque<E> extends IterableElementBase<E> {
* will be inserted once. However, you can provide a different value for `num` if you want
* @returns The size of the array after the insertion is being returned.
*/
insertAt(pos: number, element: E, num = 1) {
addAt(pos: number, element: E, num = 1): boolean {
const length = this.size;
rangeCheck(pos, 0, length);
if (pos === 0) {
@ -404,7 +347,7 @@ export class Deque<E> extends IterableElementBase<E> {
for (let i = 0; i < num; ++i) this.push(element);
for (let i = 0; i < arr.length; ++i) this.push(arr[i]);
}
return this.size;
return true;
}
/**
@ -422,7 +365,7 @@ export class Deque<E> extends IterableElementBase<E> {
* cut. It is a number that indicates the index of the character where the cut should be made.
* @returns The method is returning the updated size of the data structure.
*/
cut(pos: number) {
cut(pos: number): number {
if (pos < 0) {
this.clear();
return 0;
@ -453,7 +396,7 @@ export class Deque<E> extends IterableElementBase<E> {
* the index of the element to be deleted.
* @returns The size of the data structure after the deletion operation is performed.
*/
deleteAt(pos: number) {
deleteAt(pos: number): boolean {
rangeCheck(pos, 0, this.size - 1);
if (pos === 0) this.shift();
else if (pos === this.size - 1) this.pop();
@ -474,7 +417,7 @@ export class Deque<E> extends IterableElementBase<E> {
}
this.pop();
}
return this.size;
return true;
}
/**
@ -492,9 +435,9 @@ export class Deque<E> extends IterableElementBase<E> {
* the data structure.
* @returns The size of the data structure after the element has been deleted.
*/
delete(element: E) {
delete(element: E): boolean {
const size = this.size;
if (size === 0) return 0;
if (size === 0) return false;
let i = 0;
let index = 0;
while (i < size) {
@ -506,7 +449,7 @@ export class Deque<E> extends IterableElementBase<E> {
i += 1;
}
this.cut(index - 1);
return this.size;
return true;
}
/**
@ -523,7 +466,7 @@ export class Deque<E> extends IterableElementBase<E> {
* @returns The reverse() method is returning the object itself (this) after performing the reverse
* operation on the buckets and updating the relevant properties.
*/
reverse() {
reverse(): this {
this._buckets.reverse().forEach(function (bucket) {
bucket.reverse();
});
@ -548,9 +491,9 @@ export class Deque<E> extends IterableElementBase<E> {
* the number of unique elements.
* @returns The size of the modified array is being returned.
*/
unique() {
unique(): this {
if (this.size <= 1) {
return this.size;
return this;
}
let index = 1;
let prev = this.getAt(0);
@ -562,7 +505,7 @@ export class Deque<E> extends IterableElementBase<E> {
}
}
this.cut(index - 1);
return this.size;
return this;
}
/**
@ -578,9 +521,9 @@ export class Deque<E> extends IterableElementBase<E> {
* @param [comparator] - The `comparator` parameter is a function that takes in two elements `x` and
* `y` of type `E` and returns a number. The comparator function is used to determine the order of
* the elements in the sorted array.
* @returns The method is returning the sorted instance of the object on which the method is called.
* @returns Deque<E>
*/
sort(comparator?: (x: E, y: E) => number) {
sort(comparator?: (x: E, y: E) => number): this {
const arr: E[] = [];
for (let i = 0; i < this.size; ++i) {
arr.push(this.getAt(i));
@ -606,7 +549,7 @@ export class Deque<E> extends IterableElementBase<E> {
* @returns Nothing is being returned. The function is using the `return` statement to exit early if
* `this.size` is 0, but it does not return any value.
*/
shrinkToFit() {
shrinkToFit(): void {
if (this.size === 0) return;
const newBuckets = [];
if (this._bucketFirst === this._bucketLast) return;
@ -650,7 +593,7 @@ export class Deque<E> extends IterableElementBase<E> {
return element;
}
}
return undefined;
return;
}
/**
@ -691,11 +634,7 @@ export class Deque<E> extends IterableElementBase<E> {
* @returns The `toArray()` method is returning an array of elements of type `E`.
*/
toArray(): E[] {
const arr: E[] = [];
for (let i = 0; i < this.size; ++i) {
arr.push(this.getAt(i));
}
return arr;
return [...this];
}
/**
@ -758,12 +697,60 @@ export class Deque<E> extends IterableElementBase<E> {
}
/**
* Time Complexity: O(n)
* Space Complexity: O(n)
* Time Complexity: Amortized O(1) - Similar to push, resizing leads to O(n).
* Space Complexity: O(n) - Due to potential resizing.
*/
print(): void {
console.log([...this])
/**
* Time Complexity: O(1)
* Space Complexity: O(n) - In worst case, resizing doubles the array size.
*
* The addLast function adds an element to the end of an array.
* @param {E} element - The element parameter represents the element that you want to add to the end of the
* data structure.
*/
addLast(element: E): boolean {
return this.push(element);
}
/**
* Time Complexity: O(1) - Removes the first element.
* Space Complexity: O(1) - In-place operation.
*/
/**
* Time Complexity: O(1) - Removes the last element.
* Space Complexity: O(1) - Operates in-place.
*
* The function "pollLast" removes and returns the last element of an array.
* @returns The last element of the array is being returned.
*/
pollLast(): E | undefined {
return this.pop();
}
/**
* Time Complexity: O(1).
* Space Complexity: O(n) - Due to potential resizing.
*
* The "addFirst" function adds an element to the beginning of an array.
* @param {E} element - The parameter "element" represents the element that you want to add to the
* beginning of the data structure.
*/
addFirst(element: E): boolean {
return this.unshift(element);
}
/**
* Time Complexity: O(1) - Removes the first element.
* Space Complexity: O(1) - In-place operation.
*
* The function "pollFirst" removes and returns the first element of an array.
* @returns The method `pollFirst()` is returning the first element of the array after removing it
* from the beginning. If the array is empty, it will return `undefined`.
*/
pollFirst(): E | undefined {
return this.shift();
}
/**
@ -773,7 +760,7 @@ export class Deque<E> extends IterableElementBase<E> {
* The above function is an implementation of the iterator protocol in TypeScript, allowing the
* object to be iterated over using a for...of loop.
*/
protected* _getIterator() {
protected* _getIterator(): IterableIterator<E> {
for (let i = 0; i < this.size; ++i) {
yield this.getAt(i);
}

View file

@ -74,9 +74,9 @@ export class Queue<E = any> extends IterableElementBase<E> {
* @param {E} element - The `element` parameter represents the element that you want to add to the queue.
* @returns The `add` method is returning a `Queue<E>` object.
*/
push(element: E): Queue<E> {
push(element: E): boolean {
this.nodes.push(element);
return this;
return true;
}
/**
@ -95,7 +95,7 @@ export class Queue<E = any> extends IterableElementBase<E> {
shift(): E | undefined {
if (this.size === 0) return undefined;
const first = this.getFirst();
const first = this.first;
this._offset += 1;
if (this.offset * 2 < this.nodes.length) return first;
@ -116,11 +116,11 @@ export class Queue<E = any> extends IterableElementBase<E> {
* 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 `getFirst` function returns the first element of the array `_nodes` if it exists, otherwise it returns `undefined`.
* @returns The `getFirst()` method returns the first element of the data structure, represented by the `_nodes` array at
* 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`.
*/
getFirst(): E | undefined {
get first(): E | undefined {
return this.size > 0 ? this.nodes[this.offset] : undefined;
}
@ -138,7 +138,7 @@ export class Queue<E = any> extends IterableElementBase<E> {
* the `_offset` index. If the data structure is empty (size is 0), it returns `undefined`.
*/
peek(): E | undefined {
return this.getFirst();
return this.first;
}
/**
@ -150,11 +150,11 @@ export class Queue<E = any> extends IterableElementBase<E> {
* 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 `getLast` function returns the last element in an array-like data structure, or undefined if the structure is empty.
* @returns The method `getLast()` returns the last element of the `_nodes` array if the array is not empty. If the
* 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`.
*/
getLast(): E | undefined {
get last(): E | undefined {
return this.size > 0 ? this.nodes[this.nodes.length - 1] : undefined;
}
@ -172,7 +172,7 @@ export class Queue<E = any> extends IterableElementBase<E> {
* array is empty, it returns `undefined`.
*/
peekLast(): E | undefined {
return this.getLast();
return this.last;
}
/**
@ -187,7 +187,7 @@ export class Queue<E = any> extends IterableElementBase<E> {
* 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.
*/
enqueue(value: E) {
enqueue(value: E): boolean {
return this.push(value);
}
@ -278,10 +278,6 @@ export class Queue<E = any> extends IterableElementBase<E> {
return new Queue(this.nodes.slice(this.offset));
}
print(): void {
console.log([...this]);
}
/**
* Time Complexity: O(n)
* Space Complexity: O(n)
@ -348,7 +344,7 @@ export class Queue<E = any> extends IterableElementBase<E> {
* Space Complexity: O(n)
*/
protected* _getIterator() {
protected* _getIterator(): IterableIterator<E> {
for (const item of this.nodes) {
yield item;
}
@ -366,8 +362,8 @@ export class LinkedListQueue<E = any> extends SinglyLinkedList<E> {
* 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) {
this.push(value);
enqueue(value: E): boolean {
return this.push(value);
}
/**
@ -379,10 +375,10 @@ export class LinkedListQueue<E = any> extends SinglyLinkedList<E> {
}
/**
* The `getFirst` function returns the value of the head node in a linked list, or `undefined` if the list is empty.
* @returns The `getFirst()` method is returning the value of the `head` node if it exists, otherwise it returns `undefined`.
* 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`.
*/
getFirst(): E | undefined {
get first(): E | undefined {
return this.head?.value;
}
@ -391,6 +387,6 @@ export class LinkedListQueue<E = any> extends SinglyLinkedList<E> {
* @returns The `peek()` method is returning the value of the `head` node if it exists, otherwise it returns `undefined`.
*/
peek(): E | undefined {
return this.getFirst();
return this.first;
}
}

View file

@ -104,9 +104,9 @@ export class Stack<E = any> extends IterableElementBase<E> {
* @param {E} element - The parameter "element" is of type E, which means it can be any data type.
* @returns The `push` method is returning the updated `Stack<E>` object.
*/
push(element: E): Stack<E> {
push(element: E): boolean {
this.elements.push(element);
return this;
return true;
}
/**
@ -123,7 +123,7 @@ export class Stack<E = any> extends IterableElementBase<E> {
* array is empty, it returns `undefined`.
*/
pop(): E | undefined {
if (this.isEmpty()) return undefined;
if (this.isEmpty()) return;
return this.elements.pop();
}
@ -228,15 +228,11 @@ export class Stack<E = any> extends IterableElementBase<E> {
return newStack;
}
print(): void {
console.log([...this]);
}
/**
* Custom iterator for the Stack class.
* @returns An iterator object.
*/
protected* _getIterator() {
protected* _getIterator(): IterableIterator<E> {
for (let i = 0; i < this.elements.length; i++) {
yield this.elements[i];
}

View file

@ -138,7 +138,7 @@ export class Trie extends IterableElementBase<string> {
* @param{string} word - The word to delete.
* @returns {boolean} True if the word was successfully removed.
*/
delete(word: string) {
delete(word: string): boolean {
word = this._caseProcess(word);
let isDeleted = false;
const dfs = (cur: TrieNode, i: number): boolean => {
@ -184,7 +184,7 @@ export class Trie extends IterableElementBase<string> {
* Space Complexity: O(1) - Constant space.
*
*/
getHeight() {
getHeight(): number {
const beginRoot = this.root;
let maxDepth = 0;
if (beginRoot) {
@ -371,12 +371,12 @@ export class Trie extends IterableElementBase<string> {
* specific object as the context for the `predicate` function. If `thisArg` is provided, it will be
* @returns The `filter` method is returning an array of strings (`string[]`).
*/
filter(predicate: ElementCallback<string, boolean>, thisArg?: any): string[] {
const results: string[] = [];
filter(predicate: ElementCallback<string, boolean>, thisArg?: any): Trie {
const results: Trie = new Trie();
let index = 0;
for (const word of this) {
if (predicate.call(thisArg, word, index, this)) {
results.push(word);
results.add(word);
}
index++;
}
@ -411,10 +411,6 @@ export class Trie extends IterableElementBase<string> {
return newTrie;
}
print() {
console.log([...this]);
}
protected* _getIterator(): IterableIterator<string> {
function* _dfs(node: TrieNode, path: string): IterableIterator<string> {
if (node.isEnd) {

View file

@ -47,23 +47,23 @@ if (isCompetitor) {
}
suite
.add(`SRC PQ ${TEN_THOUSAND.toLocaleString()} add & pop`, () => {
.add(`SRC PQ ${TEN_THOUSAND.toLocaleString()} add & poll`, () => {
const pq = new SRCPriorityQueue<number>([], { comparator: (a, b) => b - a });
for (let i = 0; i < TEN_THOUSAND; i++) pq.add(i);
for (let i = 0; i < TEN_THOUSAND; i++) pq.pop();
for (let i = 0; i < TEN_THOUSAND; i++) pq.poll();
})
.add(`CJS PQ ${TEN_THOUSAND.toLocaleString()} add & pop`, () => {
.add(`CJS PQ ${TEN_THOUSAND.toLocaleString()} add & poll`, () => {
const pq = new CJSPriorityQueue<number>([], { comparator: (a, b) => b - a });
for (let i = 0; i < TEN_THOUSAND; i++) pq.add(i);
for (let i = 0; i < TEN_THOUSAND; i++) pq.pop();
for (let i = 0; i < TEN_THOUSAND; i++) pq.poll();
})
.add(`MJS PQ ${TEN_THOUSAND.toLocaleString()} add & pop`, () => {
.add(`MJS PQ ${TEN_THOUSAND.toLocaleString()} add & poll`, () => {
const pq = new MJSPriorityQueue<number>([], { comparator: (a, b) => b - a });
for (let i = 0; i < TEN_THOUSAND; i++) pq.add(i);
for (let i = 0; i < TEN_THOUSAND; i++) pq.pop();
for (let i = 0; i < TEN_THOUSAND; i++) pq.poll();
});

View file

@ -6,7 +6,7 @@ const suite = new Benchmark.Suite();
const { HUNDRED_THOUSAND, TEN_THOUSAND } = magnitude;
suite
.add(`${HUNDRED_THOUSAND.toLocaleString()} add & pop`, () => {
.add(`${HUNDRED_THOUSAND.toLocaleString()} add & poll`, () => {
const heap = new Heap<number>([], { comparator: (a, b) => b - a });
for (let i = 0; i < HUNDRED_THOUSAND; i++) {
@ -14,7 +14,7 @@ suite
}
for (let i = 0; i < HUNDRED_THOUSAND; i++) {
heap.pop();
heap.poll();
}
})
.add(`${HUNDRED_THOUSAND.toLocaleString()} add & dfs`, () => {

View file

@ -55,7 +55,7 @@ suite
list.shift();
}
})
.add(`${LINEAR.toLocaleString()} insertBefore`, () => {
.add(`${LINEAR.toLocaleString()} addBefore`, () => {
const doublyList = new DoublyLinkedList<number>();
let midNode: DoublyLinkedListNode | undefined;
const midIndex = Math.floor(LINEAR / 2);
@ -64,7 +64,7 @@ suite
if (i === midIndex) {
midNode = doublyList.getNode(i);
} else if (i > midIndex && midNode) {
doublyList.insertBefore(midNode, i);
doublyList.addBefore(midNode, i);
}
}
});

View file

@ -28,7 +28,7 @@ suite
list.pop();
}
})
.add(`${TEN_THOUSAND.toLocaleString()} insertBefore`, () => {
.add(`${TEN_THOUSAND.toLocaleString()} addBefore`, () => {
const singlyList = new SinglyLinkedList<number>();
let midSinglyNode: SinglyLinkedListNode | undefined;
const midIndex = Math.floor(TEN_THOUSAND / 2);
@ -37,7 +37,7 @@ suite
if (i === midIndex) {
midSinglyNode = singlyList.getNode(i);
} else if (i > midIndex && midSinglyNode) {
singlyList.insertBefore(midSinglyNode.value, i);
singlyList.addBefore(midSinglyNode.value, i);
}
}
});

View file

@ -7,7 +7,7 @@ import { isCompetitor } from '../../../config';
const suite = new Benchmark.Suite();
const { HUNDRED_THOUSAND } = magnitude;
suite.add(`${HUNDRED_THOUSAND.toLocaleString()} add & pop`, () => {
suite.add(`${HUNDRED_THOUSAND.toLocaleString()} add & poll`, () => {
const pq = new PriorityQueue<number>([], { comparator: (a, b) => b - a });
for (let i = 0; i < HUNDRED_THOUSAND; i++) {
@ -15,7 +15,7 @@ suite.add(`${HUNDRED_THOUSAND.toLocaleString()} add & pop`, () => {
}
for (let i = 0; i < HUNDRED_THOUSAND; i++) {
pq.pop();
pq.poll();
}
});
if (isCompetitor) {

View file

@ -1,8 +1,8 @@
import { BinaryTree, BinaryTreeNode, FamilyPosition, IterationType } from '../../../../src';
import { getRandomIntArray } from '../../../utils';
import { isDebugTest } from '../../../config';
// import { isDebugTest } from '../../../config';
const isDebug = isDebugTest;
// const isDebug = isDebugTest;
describe('BinaryTreeNode', () => {
it('should create an instance of BinaryTreeNode', () => {

View file

@ -453,7 +453,7 @@ describe('LinkedHashMap Test2', () => {
expect(hashMap.last).toEqual([key, value]);
expect(hashMap.reverseBegin().next().value).toEqual([key, value]);
} else if (index <= 1000) {
expect(hashMap.getAt(index)).toEqual([key, value]);
expect(hashMap.getAt(index)).toBe(value);
}
expect(hashMap.get(key)).toEqual(value);
index++;
@ -502,7 +502,7 @@ describe('LinkedHashMap Test2', () => {
test('should get element at specific index', () => {
hashMap.set('key1', 'value1');
hashMap.set('key2', 'value2');
expect(hashMap.getAt(1)).toEqual(['key2', 'value2']);
expect(hashMap.getAt(1)).toBe('value2');
});
});

View file

@ -5,7 +5,7 @@ import { logBigOMetricsWrap } from '../../../utils';
describe('Heap Operation Test', () => {
it('should numeric heap work well', function () {
const minNumHeap = new MinHeap<number>();
minNumHeap.add(1).add(6).add(2).add(0).add(5).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);

View file

@ -55,7 +55,7 @@ describe('MinHeap', () => {
it('should push & dfs', () => {
for (let i = 0; i < n; i++) {
minHeap.push(i);
minHeap.add(i);
}
expect(minHeap.dfs()[0]).toBe(0)
expect(minHeap.dfs()[999]).toBe(4126)

View file

@ -19,11 +19,11 @@ describe('DoublyLinkedList Operation Test', () => {
it('should out of bound index', () => {
expect(list.getNodeAt(-1)).toBe(undefined);
expect(list.getNodeAt(5)).toBe(undefined);
expect(list.insertAt(5, 6)).toBe(true);
expect(list.addAt(5, 6)).toBe(true);
});
it('should insertBefore', () => {
expect(list.insertBefore(1, 0)).toBe(true);
it('should addBefore', () => {
expect(list.addBefore(1, 0)).toBe(true);
});
it('should deleteAt', () => {
@ -49,11 +49,11 @@ describe('DoublyLinkedList Operation Test', () => {
expect(list.findBackward(value => value === 0)).toBe(undefined);
});
it('should insertAfter tail', () => {
expect(list.insertAfter(list.tail!, 6)).toBe(true);
it('should addAfter tail', () => {
expect(list.addAfter(list.tail!, 6)).toBe(true);
});
it('should insertAfter tail', () => {
it('should addAfter tail', () => {
expect([...list]).toEqual([1, 2, 3, 4, 5]);
});
});
@ -68,7 +68,7 @@ describe('DoublyLinkedList Operation Test', () => {
});
it('should initialize an empty list', () => {
expect(list.length).toBe(0);
expect(list.size).toBe(0);
expect(list.head).toBe(undefined);
expect(list.tail).toBe(undefined);
});
@ -77,7 +77,7 @@ describe('DoublyLinkedList Operation Test', () => {
list.push(1);
list.push(2);
list.push(3);
expect(list.length).toBe(3);
expect(list.size).toBe(3);
expect(list.head!.value).toBe(1);
expect(list.tail!.value).toBe(3);
});
@ -87,7 +87,7 @@ describe('DoublyLinkedList Operation Test', () => {
list.push(2);
const poppedValue = list.pop();
expect(poppedValue).toBe(2);
expect(list.length).toBe(1);
expect(list.size).toBe(1);
expect(list.head!.value).toBe(1);
expect(list.tail!.value).toBe(1);
});
@ -97,20 +97,20 @@ describe('DoublyLinkedList Operation Test', () => {
list.push(3);
// Inserting at the beginning
list.insertAt(0, 0);
expect(list.length).toBe(4);
list.addAt(0, 0);
expect(list.size).toBe(4);
expect(list.getAt(0)).toBe(0);
expect(list.getAt(1)).toBe(1);
// Inserting in the middle
list.insertAt(2, 1.5);
expect(list.length).toBe(5);
list.addAt(2, 1.5);
expect(list.size).toBe(5);
expect(list.getAt(2)).toBe(1.5);
expect(list.getAt(3)).toBe(2);
// Inserting at the end
list.insertAt(5, 4);
expect(list.length).toBe(6);
list.addAt(5, 4);
expect(list.size).toBe(6);
expect(list.getAt(5)).toBe(4);
expect(list.tail!.value).toBe(4);
});
@ -122,18 +122,18 @@ describe('DoublyLinkedList Operation Test', () => {
// Deleting from the beginning
const deletedValue = list.deleteAt(0);
expect(deletedValue).toBe(1);
expect(list.length).toBe(2);
expect(deletedValue).toBe(true);
expect(list.size).toBe(2);
expect(list.head!.value).toBe(2);
// Deleting from the middle
list.deleteAt(0); // Deleting the second element
expect(list.length).toBe(1);
expect(list.size).toBe(1);
expect(list.head!.value).toBe(3);
// Deleting from the end
list.deleteAt(0);
expect(list.length).toBe(0);
expect(list.size).toBe(0);
expect(list.head).toBe(undefined);
expect(list.tail).toBe(undefined);
});
@ -144,16 +144,16 @@ describe('DoublyLinkedList Operation Test', () => {
list.push(3);
list.delete(2);
expect(list.length).toBe(2);
expect(list.size).toBe(2);
expect(list.head!.value).toBe(1);
expect(list.tail!.value).toBe(3);
list.delete(1);
expect(list.length).toBe(1);
expect(list.size).toBe(1);
expect(list.head!.value).toBe(3);
list.delete(3);
expect(list.length).toBe(0);
expect(list.size).toBe(0);
expect(list.head).toBe(undefined);
expect(list.tail).toBe(undefined);
});
@ -206,7 +206,7 @@ describe('DoublyLinkedList Operation Test', () => {
list.push(2);
list.push(3);
list.insertAfter(2, 2.5);
list.addAfter(2, 2.5);
expect(list.toArray()).toEqual([1, 2, 2.5, 3]);
});
@ -216,7 +216,7 @@ describe('DoublyLinkedList Operation Test', () => {
list.push(2);
list.push(3);
list.insertBefore(2, 1.5);
list.addBefore(2, 1.5);
expect(list.toArray()).toEqual([1, 1.5, 2, 3]);
});
@ -258,7 +258,7 @@ describe('DoublyLinkedList Operation Test', () => {
list.clear();
expect(list.length).toBe(0);
expect(list.size).toBe(0);
expect(list.head).toBe(undefined);
expect(list.tail).toBe(undefined);
});
@ -334,7 +334,7 @@ describe('DoublyLinkedList Operation Test', () => {
list.push(2);
list.push(3);
const success = list.insertAfter(2, 4);
const success = list.addAfter(2, 4);
expect(success).toBe(true);
expect(list.toArray()).toEqual([1, 2, 4, 3]);
});
@ -344,7 +344,7 @@ describe('DoublyLinkedList Operation Test', () => {
list.push(2);
list.push(3);
const success = list.insertBefore(2, 0);
const success = list.addBefore(2, 0);
expect(success).toBe(true);
expect(list.toArray()).toEqual([1, 0, 2, 3]);
});
@ -354,7 +354,7 @@ describe('DoublyLinkedList Operation Test', () => {
list.push(2);
list.push(3);
const success = list.insertAfter(4, 5);
const success = list.addAfter(4, 5);
expect(success).toBe(false);
expect(list.toArray()).toEqual([1, 2, 3]);
});
@ -364,7 +364,7 @@ describe('DoublyLinkedList Operation Test', () => {
list.push(2);
list.push(3);
const success = list.insertBefore(4, 0);
const success = list.addBefore(4, 0);
expect(success).toBe(false);
expect(list.toArray()).toEqual([1, 2, 3]);
});
@ -381,7 +381,7 @@ describe('DoublyLinkedList Operation Test', () => {
expect(objectList.toArray()).toEqual([obj1, obj2, obj3]);
const newObj = { keyA: 25 }; // Corrected newObj value
const insertSuccess = objectList.insertBefore(obj2, newObj);
const insertSuccess = objectList.addBefore(obj2, newObj);
expect(insertSuccess).toBe(true);
const getNode = objectList.getNode(newObj); // Use newObj instead of obj2

View file

@ -2,7 +2,7 @@
// import {bigO, magnitude} from '../../../utils';
describe('LinkedList Performance Test', () => {
it('should DoublyLinkedList insertBefore faster than SinglyLinkedList', () => {
it('should DoublyLinkedList addBefore faster than SinglyLinkedList', () => {
expect(1).toBe(1);
});
});

View file

@ -84,12 +84,12 @@ describe('SinglyLinkedList Operation Test', () => {
});
});
describe('insertAfter', () => {
describe('addAfter', () => {
it('should insert an element after an existing value', () => {
list.push(1);
list.push(2);
list.push(3);
list.insertAfter(2, 4);
list.addAfter(2, 4);
expect(list.toArray()).toEqual([1, 2, 4, 3]);
});
@ -97,7 +97,7 @@ describe('SinglyLinkedList Operation Test', () => {
list.push(1);
list.push(2);
list.push(3);
const result = list.insertAfter(5, 4);
const result = list.addAfter(5, 4);
expect(result).toBe(false);
expect(list.toArray()).toEqual([1, 2, 3]);
});
@ -164,7 +164,7 @@ describe('SinglyLinkedList Operation Test', () => {
list.push(3);
list.clear();
expect(list.toArray()).toEqual([]);
expect(list.length).toBe(0);
expect(list.size).toBe(0);
expect(list.isEmpty()).toBe(true);
});
});
@ -223,19 +223,19 @@ describe('SinglyLinkedList Operation Test', () => {
});
});
describe('insertBefore', () => {
describe('addBefore', () => {
it('should insert an element before an existing value', () => {
list.push(1);
list.push(2);
list.push(3);
list.insertBefore(2, 4);
list.addBefore(2, 4);
expect(list.toArray()).toEqual([1, 4, 2, 3]);
});
it('should insert an element at the beginning', () => {
list.push(1);
list.push(2);
list.insertBefore(1, 3);
list.addBefore(1, 3);
expect(list.toArray()).toEqual([3, 1, 2]);
});
@ -243,7 +243,7 @@ describe('SinglyLinkedList Operation Test', () => {
list.push(1);
list.push(2);
list.push(3);
const result = list.insertBefore(5, 4);
const result = list.addBefore(5, 4);
expect(result).toBe(false);
expect(list.toArray()).toEqual([1, 2, 3]);
});
@ -251,10 +251,10 @@ describe('SinglyLinkedList Operation Test', () => {
describe('getLength', () => {
it('should return the correct length of the list', () => {
expect(list.length).toBe(0);
expect(list.size).toBe(0);
list.push(1);
list.push(2);
expect(list.length).toBe(2);
expect(list.size).toBe(2);
});
});
@ -264,21 +264,21 @@ describe('SinglyLinkedList Operation Test', () => {
list.push(2);
list.push(3);
const removed = list.deleteAt(1);
expect(removed).toBe(2);
expect(removed).toBe(true);
expect(list.toArray()).toEqual([1, 3]);
});
it('should return undefined for an out-of-bounds index', () => {
list.push(1);
const removed = list.deleteAt(1);
expect(removed).toBeUndefined();
expect(removed).toBe(false);
});
it('should delete and return the first element', () => {
list.push(1);
list.push(2);
const removed = list.deleteAt(0);
expect(removed).toBe(1);
expect(removed).toBe(true);
expect(list.toArray()).toEqual([2]);
});
@ -286,7 +286,7 @@ describe('SinglyLinkedList Operation Test', () => {
list.push(1);
list.push(2);
const removed = list.deleteAt(1);
expect(removed).toBe(2);
expect(removed).toBe(true);
expect(list.toArray()).toEqual([1]);
});
});
@ -313,9 +313,9 @@ describe('SinglyLinkedList Operation Test', () => {
describe('insert and toArray', () => {
it('should insert elements and return array correctly', () => {
list.insertAt(0, 1);
list.insertAt(1, 3);
list.insertAt(1, 2);
list.addAt(0, 1);
list.addAt(1, 3);
list.addAt(1, 2);
expect(list.toArray()).toEqual([1, 2, 3]);
});
});
@ -377,7 +377,7 @@ describe('SinglyLinkedList Operation Test', () => {
expect(objectList.toArray()).toEqual([obj1, obj2, obj3]);
const newObj = { keyA: 2.5 }; // Corrected newObj value
const insertSuccess = objectList.insertBefore(obj2, newObj);
const insertSuccess = objectList.addBefore(obj2, newObj);
expect(insertSuccess).toBe(true);
const getNode = objectList.getNode(newObj); // Use newObj instead of obj2
@ -404,7 +404,7 @@ describe('SinglyLinkedList', () => {
it('should initialize an empty list', () => {
expect(list.head).toBe(undefined);
expect(list.tail).toBe(undefined);
expect(list.length).toBe(0);
expect(list.size).toBe(0);
});
it('should push elements to the end of the list', () => {
@ -412,7 +412,7 @@ describe('SinglyLinkedList', () => {
list.push(2);
expect(list.head!.value).toBe(1);
expect(list.tail!.value).toBe(2);
expect(list.length).toBe(2);
expect(list.size).toBe(2);
});
it('should pop elements from the end of the list', () => {
@ -422,7 +422,7 @@ describe('SinglyLinkedList', () => {
expect(popped).toBe(2);
expect(list.head!.value).toBe(1);
expect(list.tail!.value).toBe(1);
expect(list.length).toBe(1);
expect(list.size).toBe(1);
});
it('should reverse the list', () => {

View file

@ -66,11 +66,11 @@ describe('SkipList', () => {
});
it('getFirst() should return the getFirst element', () => {
expect(skipList.getFirst()).toBe('One');
expect(skipList.first).toBe('One');
});
it('getLast() should return the getLast element', () => {
expect(skipList.getLast()).toBe('Four');
expect(skipList.last).toBe('Four');
});
it('higher(key) should return the getFirst element greater than the given key', () => {

View file

@ -1,7 +1,7 @@
import { Deque } from '../../../../src';
import { isDebugTest } from '../../../config';
// import { isDebugTest } from '../../../config';
const isDebug = isDebugTest;
// const isDebug = isDebugTest;
describe('Deque - Basic Operations', () => {
let deque: Deque<number>;
@ -57,10 +57,10 @@ describe('Deque - Complex Operations', () => {
deque = new Deque<number>();
});
test('insertAt should insert elements at the specified position', () => {
test('addAt should insert elements at the specified position', () => {
deque.push(1);
deque.push(3);
deque.insertAt(1, 2);
deque.addAt(1, 2);
expect(deque.toArray()).toEqual([1, 2, 3]);
});
@ -111,7 +111,7 @@ describe('Deque - Complex Operations', () => {
deque.push(1);
deque.push(2);
deque.sort((a, b) => a - b);
expect(deque.toArray()).toEqual([1, 2, 3]);
expect([...deque]).toEqual([1, 2, 3]);
});
test('shrinkToFit should reduce the memory footprint', () => {

View file

@ -1,7 +1,7 @@
import { LinkedListQueue, Queue } from '../../../../src';
import { isDebugTest } from '../../../config';
// import { isDebugTest } from '../../../config';
const isDebug = isDebugTest;
// const isDebug = isDebugTest;
describe('Queue', () => {
let queue: Queue<number>;
@ -224,7 +224,7 @@ describe('LinkedListQueue', () => {
queue.enqueue('A');
queue.enqueue('B');
expect(queue.peek()).toBe('A');
expect(queue.length).toBe(2);
expect(queue.size).toBe(2);
});
it('should dequeue elements from the front of the queue', () => {
@ -233,7 +233,7 @@ describe('LinkedListQueue', () => {
const dequeued = queue.dequeue();
expect(dequeued).toBe('A');
expect(queue.peek()).toBe('B');
expect(queue.length).toBe(1);
expect(queue.size).toBe(1);
});
it('should peek at the front of the queue', () => {

View file

@ -843,7 +843,7 @@ describe('Trie class', () => {
test('filter should return words that satisfy the predicate', () => {
const filteredWords = trie.filter(word => word.startsWith('ba'));
expect(filteredWords).toEqual(['banana', 'band', 'bandana']);
expect([...filteredWords]).toEqual(['banana', 'band', 'bandana']);
});
test('map should apply a function to each word', () => {