feat: Add pushMany, addMany, unshiftMany, or addMany methods to all data structures.

This commit is contained in:
Revone 2024-11-23 21:36:05 +13:00
parent ca7e60e465
commit f1fecd828a
7 changed files with 162 additions and 84 deletions

View file

@ -207,12 +207,7 @@ export class Heap<E = any, R = any> extends IterableElementBase<E, R, Heap<E, R>
if (comparator) this._comparator = comparator;
}
if (elements) {
for (const el of elements) {
if (this.toElementFn) this.add(this.toElementFn(el as R));
else this.add(el as E);
}
}
this.addMany(elements);
}
protected _elements: E[] = [];
@ -254,14 +249,24 @@ export class Heap<E = any, R = any> extends IterableElementBase<E, R, Heap<E, R>
* Time Complexity: O(log n)
* Space Complexity: O(1)
*
* Insert an element into the heap and maintain the heap properties.
* @param element - The element to be inserted.
*/
add(element: E): boolean {
this._elements.push(element);
this._elements.push(element as E);
return this._bubbleUp(this.elements.length - 1);
}
addMany(elements: Iterable<E> | Iterable<R>): boolean[] {
const ans: boolean[] = [];
for (const el of elements) {
if (this._toElementFn) {
ans.push(this.add(this._toElementFn(el as R)));
continue;
}
ans.push(this.add(el as E));
}
return ans;
}
/**
* Time Complexity: O(log n)
* Space Complexity: O(1)

View file

@ -524,18 +524,15 @@ export class DoublyLinkedList<E = any, R = any> extends IterableElementBase<E, R
* `DoublyLinkedListOptions<E, R>`. It is an optional parameter that allows you to pass additional
* configuration options to customize the behavior of the DoublyLinkedList.
*/
constructor(elements: Iterable<E> | Iterable<R> = [], options?: DoublyLinkedListOptions<E, R>) {
constructor(
elements: Iterable<E> | Iterable<R> | Iterable<DoublyLinkedListNode<E>> = [],
options?: DoublyLinkedListOptions<E, R>
) {
super(options);
this._head = undefined;
this._tail = undefined;
this._size = 0;
if (elements) {
for (const el of elements) {
if (this.toElementFn) {
this.push(this.toElementFn(el as R));
} else this.push(el as E);
}
}
this.pushMany(elements);
}
protected _head: DoublyLinkedListNode<E> | undefined;
@ -700,6 +697,30 @@ export class DoublyLinkedList<E = any, R = any> extends IterableElementBase<E, R
return true;
}
pushMany(elements: Iterable<E> | Iterable<R> | Iterable<DoublyLinkedListNode<E>>) {
const ans: boolean[] = [];
for (const el of elements) {
if (this.toElementFn) {
ans.push(this.push(this.toElementFn(el as R)));
continue;
}
ans.push(this.push(el as E | DoublyLinkedListNode<E>));
}
return ans;
}
unshiftMany(elements: Iterable<E> | Iterable<R> | Iterable<DoublyLinkedListNode<E>>) {
const ans: boolean[] = [];
for (const el of elements) {
if (this.toElementFn) {
ans.push(this.unshift(this.toElementFn(el as R)));
continue;
}
ans.push(this.unshift(el as E | DoublyLinkedListNode<E>));
}
return ans;
}
/**
* Time Complexity: O(n)
* Space Complexity: O(1)

View file

@ -60,17 +60,12 @@ export class SinglyLinkedListNode<E = any> {
}
export class SinglyLinkedList<E = any, R = any> extends IterableElementBase<E, R, SinglyLinkedList<E, R>> {
constructor(elements: Iterable<E> | Iterable<R> = [], options?: SinglyLinkedListOptions<E, R>) {
constructor(
elements: Iterable<E> | Iterable<R> | Iterable<SinglyLinkedListNode<E>> = [],
options?: SinglyLinkedListOptions<E, R>
) {
super(options);
if (elements) {
for (const el of elements) {
if (this.toElementFn) {
this.push(this.toElementFn(el as R));
} else {
this.push(el as E);
}
}
}
this.pushMany(elements);
}
protected _head: SinglyLinkedListNode<E> | undefined;
@ -211,6 +206,30 @@ export class SinglyLinkedList<E = any, R = any> extends IterableElementBase<E, R
return true;
}
pushMany(elements: Iterable<E> | Iterable<R> | Iterable<SinglyLinkedListNode<E>>) {
const ans: boolean[] = [];
for (const el of elements) {
if (this.toElementFn) {
ans.push(this.push(this.toElementFn(el as R)));
continue;
}
ans.push(this.push(el as E | SinglyLinkedListNode<E>));
}
return ans;
}
unshiftMany(elements: Iterable<E> | Iterable<R> | Iterable<SinglyLinkedListNode<E>>) {
const ans: boolean[] = [];
for (const el of elements) {
if (this.toElementFn) {
ans.push(this.unshift(this.toElementFn(el as R)));
continue;
}
ans.push(this.unshift(el as E | SinglyLinkedListNode<E>));
}
return ans;
}
/**
* Time Complexity: O(n)
* Space Complexity: O(1)

View file

@ -53,14 +53,7 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
const needBucketNum = calcMinUnitsRequired(_size, this._bucketSize);
this._bucketFirst = this._bucketLast = (this._bucketCount >> 1) - (needBucketNum >> 1);
this._firstInBucket = this._lastInBucket = (this._bucketSize - (_size % this._bucketSize)) >> 1;
for (const el of elements) {
if (this.toElementFn) {
this.push(this.toElementFn(el as R));
} else {
this.push(el as E);
}
}
this.pushMany(elements);
}
protected _bucketSize: number = 1 << 12;
@ -230,6 +223,33 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
return element;
}
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*
* The `shift()` function removes and returns the first element from a data structure, updating the
* internal state variables accordingly.
* @returns The element that is being removed from the beginning of the data structure is being
* returned.
*/
shift(): E | undefined {
if (this._size === 0) return;
const element = this._buckets[this._bucketFirst][this._firstInBucket];
if (this._size !== 1) {
if (this._firstInBucket < this._bucketSize - 1) {
this._firstInBucket += 1;
} else if (this._bucketFirst < this._bucketCount - 1) {
this._bucketFirst += 1;
this._firstInBucket = 0;
} else {
this._bucketFirst = 0;
this._firstInBucket = 0;
}
}
this._size -= 1;
return element;
}
/**
* Time Complexity: Amortized O(1)
* Space Complexity: O(n)
@ -259,31 +279,28 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
return true;
}
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*
* The `shift()` function removes and returns the first element from a data structure, updating the
* internal state variables accordingly.
* @returns The element that is being removed from the beginning of the data structure is being
* returned.
*/
shift(): E | undefined {
if (this._size === 0) return;
const element = this._buckets[this._bucketFirst][this._firstInBucket];
if (this._size !== 1) {
if (this._firstInBucket < this._bucketSize - 1) {
this._firstInBucket += 1;
} else if (this._bucketFirst < this._bucketCount - 1) {
this._bucketFirst += 1;
this._firstInBucket = 0;
pushMany(elements: IterableWithSizeOrLength<E> | IterableWithSizeOrLength<R>) {
const ans: boolean[] = [];
for (const el of elements) {
if (this.toElementFn) {
ans.push(this.push(this.toElementFn(el as R)));
} else {
this._bucketFirst = 0;
this._firstInBucket = 0;
ans.push(this.push(el as E));
}
}
this._size -= 1;
return element;
return ans;
}
unshiftMany(elements: IterableWithSizeOrLength<E> | IterableWithSizeOrLength<R> = []) {
const ans: boolean[] = [];
for (const el of elements) {
if (this.toElementFn) {
ans.push(this.unshift(this.toElementFn(el as R)));
} else {
ans.push(this.unshift(el as E));
}
}
return ans;
}
/**

View file

@ -25,12 +25,7 @@ export class Queue<E = any, R = any> extends IterableElementBase<E, R, Queue<E,
this._autoCompactRatio = autoCompactRatio;
}
if (elements) {
for (const el of elements) {
if (this.toElementFn) this.push(this.toElementFn(el as R));
else this.push(el as E);
}
}
this.pushMany(elements);
}
protected _elements: E[] = [];
@ -131,6 +126,15 @@ export class Queue<E = any, R = any> extends IterableElementBase<E, R, Queue<E,
return true;
}
pushMany(elements: Iterable<E> | Iterable<R>) {
const ans: boolean[] = [];
for (const el of elements) {
if (this.toElementFn) ans.push(this.push(this.toElementFn(el as R)));
else ans.push(this.push(el as E));
}
return ans;
}
/**
* Time Complexity: O(1)
* Space Complexity: O(1)

View file

@ -19,15 +19,7 @@ import { IterableElementBase } from '../base';
export class Stack<E = any, R = any> extends IterableElementBase<E, R, Stack<E, R>> {
constructor(elements: Iterable<E> | Iterable<R> = [], options?: StackOptions<E, R>) {
super(options);
if (elements) {
for (const el of elements) {
if (this.toElementFn) {
this.push(this.toElementFn(el as R));
} else {
this.push(el as E);
}
}
}
this.pushMany(elements);
}
protected _elements: E[] = [];
@ -48,11 +40,6 @@ export class Stack<E = any, R = any> extends IterableElementBase<E, R, Stack<E,
return this.elements.length;
}
/**
* Time Complexity: O(n)
* Space Complexity: O(n)
*/
/**
* Time Complexity: O(n)
* Space Complexity: O(n)
@ -67,6 +54,9 @@ export class Stack<E = any, R = any> extends IterableElementBase<E, R, Stack<E,
}
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*
* The function checks if an array is empty and returns a boolean value.
* @returns A boolean value indicating whether the `_elements` array is empty or not.
*/
@ -115,9 +105,29 @@ export class Stack<E = any, R = any> extends IterableElementBase<E, R, Stack<E,
}
/**
* The delete function removes an element from the stack.
* @param element: E Specify the element to be deleted
* @return A boolean value indicating whether the element was successfully deleted or not
* Time Complexity: O(k)
* Space Complexity: O(1)
*
*
*/
pushMany(elements: Iterable<E> | Iterable<R>) {
const ans: boolean[] = [];
for (const el of elements) {
if (this.toElementFn) {
ans.push(this.push(this.toElementFn(el as R)));
} else {
ans.push(this.push(el as E));
}
}
return ans;
}
/**
* Time Complexity: O(n)
* Space Complexity: O(1)
*
* The toArray function returns a copy of the elements in an array.
* @returns An array of type E.
*/
delete(element: E): boolean {
const index = this.elements.indexOf(element);
@ -125,9 +135,11 @@ export class Stack<E = any, R = any> extends IterableElementBase<E, R, Stack<E,
}
/**
* The deleteAt function deletes the element at a given index.
* @param index: number Determine the index of the element to be deleted
* @return A boolean value
* Time Complexity: O(n)
* Space Complexity: O(1)
*
* The toArray function returns a copy of the elements in an array.
* @returns An array of type E.
*/
deleteAt(index: number): boolean {
const spliced = this.elements.splice(index, 1);

View file

@ -268,7 +268,7 @@ export class Trie<R = any> extends IterableElementBase<string, R, Trie<R>> {
* @returns The `addMany` method returns an array of boolean values indicating whether each word in
* the input iterable was successfully added to the data structure.
*/
addMany(words: Iterable<string> | Iterable<R> = []): boolean[] {
addMany(words: Iterable<string> | Iterable<R>): boolean[] {
const ans: boolean[] = [];
for (const word of words) {
if (this.toElementFn) {