UNPKG

heap-typed

Version:

Heap. Javascript & Typescript Data Structure.

216 lines (215 loc) 8.98 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Stack = void 0; const base_1 = require("../base"); /** * 1. Last In, First Out (LIFO): The core characteristic of a stack is its last in, first out nature, meaning the last element added to the stack will be the first to be removed. * 2. Uses: Stacks are commonly used for managing a series of tasks or elements that need to be processed in a last in, first out manner. They are widely used in various scenarios, such as in function calls in programming languages, evaluation of arithmetic expressions, and backtracking algorithms. * 3. Performance: Stack operations are typically O(1) in time complexity, meaning that regardless of the stack's size, adding, removing, and viewing the top element are very fast operations. * 4. Function Calls: In most modern programming languages, the records of function calls are managed through a stack. When a function is called, its record (including parameters, local variables, and return address) is 'pushed' into the stack. When the function returns, its record is 'popped' from the stack. * 5. Expression Evaluation: Used for the evaluation of arithmetic or logical expressions, especially when dealing with parenthesis matching and operator precedence. * 6. Backtracking Algorithms: In problems where multiple branches need to be explored but only one branch can be explored at a time, stacks can be used to save the state at each branching point. */ class Stack extends base_1.IterableElementBase { constructor(elements = [], options) { super(options); this._elements = []; if (elements) { for (const el of elements) { if (this.toElementFn) { this.push(this.toElementFn(el)); } else { this.push(el); } } } } /** * The elements function returns the elements of this set. * @return An array of elements */ get elements() { return this._elements; } /** * The size() function returns the number of elements in an array. * @returns The size of the elements array. */ get size() { return this.elements.length; } /** * Time Complexity: O(n) * Space Complexity: O(n) */ /** * Time Complexity: O(n) * Space Complexity: O(n) * * The function "fromArray" creates a new Stack object from an array of elements. * @param {E[]} elements - The `elements` parameter is an array of elements of type `E`. * @returns {Stack} The method is returning a new instance of the Stack class, initialized with the elements from the input * array. */ static fromArray(elements) { return new Stack(elements); } /** * 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. */ isEmpty() { return this.elements.length === 0; } /** * Time Complexity: O(1) * Space Complexity: O(1) * * The `peek` function returns the last element of an array, or undefined if the array is empty. * @returns The `peek()` function returns the last element of the `_elements` array, or `undefined` if the array is empty. */ peek() { if (this.isEmpty()) return undefined; return this.elements[this.elements.length - 1]; } /** * Time Complexity: O(1) * Space Complexity: O(1) * * The push function adds an element to the stack and returns the updated stack. * @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) { this.elements.push(element); return true; } /** * Time Complexity: O(1) * Space Complexity: O(1) * * The `pop` function removes and returns the last element from an array, or returns undefined if the array is empty. * @returns The `pop()` method is returning the last element of the array `_elements` if the array is not empty. If the * array is empty, it returns `undefined`. */ pop() { if (this.isEmpty()) return; return this.elements.pop(); } /** * 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 */ delete(element) { const index = this.elements.indexOf(element); return this.deleteAt(index); } /** * 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 */ deleteAt(index) { const spliced = this.elements.splice(index, 1); return spliced.length === 1; } /** * Time Complexity: O(n) * Space Complexity: O(n) * * The toArray function returns a copy of the elements in an array. * @returns An array of type E. */ toArray() { return this.elements.slice(); } /** * Time Complexity: O(1) * Space Complexity: O(1) * * The clear function clears the elements array. */ clear() { this._elements = []; } /** * Time Complexity: O(n) * Space Complexity: O(n) * * The `clone()` function returns a new `Stack` object with the same elements as the original stack. * @returns The `clone()` method is returning a new `Stack` object with a copy of the `_elements` array. */ clone() { return new Stack(this, { toElementFn: this.toElementFn }); } /** * Time Complexity: O(n) * Space Complexity: O(n) * * The `filter` function creates a new stack containing elements from the original stack that satisfy * a given predicate function. * @param predicate - The `predicate` parameter is a callback function that takes three arguments: * the current element being iterated over, the index of the current element, and the stack itself. * It should return a boolean value indicating whether the element should be included in the filtered * stack or not. * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value * to be used as `this` when executing the `predicate` function. If `thisArg` is provided, it will be * passed as the `this` value to the `predicate` function. If `thisArg` is * @returns The `filter` method is returning a new `Stack` object that contains the elements that * satisfy the given predicate function. */ filter(predicate, thisArg) { const newStack = new Stack([], { toElementFn: this.toElementFn }); let index = 0; for (const el of this) { if (predicate.call(thisArg, el, index, this)) { newStack.push(el); } index++; } return newStack; } /** * Time Complexity: O(n) * Space Complexity: O(n) * * The `map` function takes a callback function and applies it to each element in the stack, * returning a new stack with the results. * @param callback - The callback parameter is a function that will be called for each element in the * stack. It takes three arguments: the current element, the index of the element, and the stack * itself. It should return a new value that will be added to the new stack. * @param [toElementFn] - The `toElementFn` parameter is an optional function that can be used to * transform the raw element (`RM`) into a new element (`EM`) before pushing it into the new stack. * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to * specify the value of `this` within the callback function. It is used to set the context or scope * in which the callback function will be executed. If `thisArg` is provided, it will be used as the * value of * @returns a new Stack object with elements of type EM and raw elements of type RM. */ map(callback, toElementFn, thisArg) { const newStack = new Stack([], { toElementFn }); let index = 0; for (const el of this) { newStack.push(callback.call(thisArg, el, index, this)); index++; } return newStack; } /** * Time Complexity: O(n) * Space Complexity: O(n) * * Custom iterator for the Stack class. * @returns An iterator object. */ *_getIterator() { for (let i = 0; i < this.elements.length; i++) { yield this.elements[i]; } } } exports.Stack = Stack;