UNPKG

doubly-linked-list-typed

Version:
245 lines (244 loc) 8.82 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SkipList = exports.SkipListNode = void 0; class SkipListNode { constructor(key, value, level) { this.key = key; this.value = value; this.forward = new Array(level); } } exports.SkipListNode = SkipListNode; /** * */ class SkipList { /** * The constructor function initializes a SkipLinkedList object with optional options and elements. * @param elements - The `elements` parameter is an iterable containing key-value pairs `[K, V]`. It * is used to initialize the SkipLinkedList with the given key-value pairs. If no elements are * provided, the SkipLinkedList will be empty. * @param {SkipLinkedListOptions} [options] - The `options` parameter is an optional object that can * contain two properties: */ constructor(elements = [], options) { this._head = new SkipListNode(undefined, undefined, this.maxLevel); this._level = 0; this._maxLevel = 16; this._probability = 0.5; if (options) { const { maxLevel, probability } = options; if (typeof maxLevel === 'number') this._maxLevel = maxLevel; if (typeof probability === 'number') this._probability = probability; } if (elements) { for (const [key, value] of elements) this.add(key, value); } } /** * The function returns the head node of a SkipList. * @returns The method is returning a SkipListNode object with generic key type K and value type V. */ get head() { return this._head; } /** * The function returns the value of the protected variable _level. * @returns The level property of the object. */ get level() { return this._level; } /** * The function returns the maximum level. * @returns The value of the variable `_maxLevel` is being returned. */ get maxLevel() { return this._maxLevel; } /** * The function returns the probability value. * @returns The probability value stored in the protected variable `_probability` is being returned. */ get probability() { return this._probability; } /** * Time Complexity: O(1) * Space Complexity: O(1) * * Get the value of the first element (the smallest element) in the Skip List. * @returns The value of the first element, or undefined if the Skip List is empty. */ get first() { const firstNode = this.head.forward[0]; return firstNode ? firstNode.value : undefined; } /** * Time Complexity: O(log n) * Space Complexity: O(1) * * Get the value of the last element (the largest element) in the Skip List. * @returns The value of the last element, or undefined if the Skip List is empty. */ get last() { let current = this.head; for (let i = this.level - 1; i >= 0; i--) { while (current.forward[i]) { current = current.forward[i]; } } return current.value; } /** * Time Complexity: O(log n) * Space Complexity: O(1) * * The add function adds a new node with a given key and value to a Skip List data structure. * @param {K} key - The key parameter represents the key of the node that needs to be added to the skip list. * @param {V} value - The "value" parameter represents the value associated with the key that is being added to the Skip * List. */ add(key, value) { const newNode = new SkipListNode(key, value, this._randomLevel()); const update = new Array(this.maxLevel).fill(this.head); let current = this.head; for (let i = this.level - 1; i >= 0; i--) { while (current.forward[i] && current.forward[i].key < key) { current = current.forward[i]; } update[i] = current; } for (let i = 0; i < newNode.forward.length; i++) { newNode.forward[i] = update[i].forward[i]; update[i].forward[i] = newNode; } if (!newNode.forward[0]) { this._level = Math.max(this.level, newNode.forward.length); } } /** * Time Complexity: O(log n) * Space Complexity: O(1) * * The function `get` retrieves the value associated with a given key from a skip list data structure. * @param {K} key - The `key` parameter is the key of the element that we want to retrieve from the data structure. * @returns The method `get(key: K)` returns the value associated with the given key if it exists in the data structure, * otherwise it returns `undefined`. */ get(key) { let current = this.head; for (let i = this.level - 1; i >= 0; i--) { while (current.forward[i] && current.forward[i].key < key) { current = current.forward[i]; } } current = current.forward[0]; if (current && current.key === key) { return current.value; } return undefined; } /** * Time Complexity: O(log n) * Space Complexity: O(1) * * The function checks if a key exists in a data structure. * @param {K} key - The parameter "key" is of type K, which represents the type of the key being * checked. * @returns a boolean value. */ has(key) { return this.get(key) !== undefined; } /** * Time Complexity: O(log n) * Space Complexity: O(1) * * The `delete` function removes a node with a specific key from a Skip List data structure. * @param {K} key - The key parameter represents the key of the node that needs to be removed from the skip list. * @returns The `delete` method returns a boolean value. It returns `true` if the key was successfully removed from the * skip list, and `false` if the key was not found in the skip list. */ delete(key) { const update = new Array(this.maxLevel).fill(this.head); let current = this.head; for (let i = this.level - 1; i >= 0; i--) { while (current.forward[i] && current.forward[i].key < key) { current = current.forward[i]; } update[i] = current; } current = current.forward[0]; if (current && current.key === key) { for (let i = 0; i < this.level; i++) { if (update[i].forward[i] !== current) { break; } update[i].forward[i] = current.forward[i]; } while (this.level > 0 && !this.head.forward[this.level - 1]) { this._level--; } return true; } return false; } /** * Time Complexity: O(log n) * Space Complexity: O(1) * * Get the value of the first element in the Skip List that is greater than the given key. * @param key - the given key. * @returns The value of the first element greater than the given key, or undefined if there is no such element. */ higher(key) { let current = this.head; for (let i = this.level - 1; i >= 0; i--) { while (current.forward[i] && current.forward[i].key <= key) { current = current.forward[i]; } } const nextNode = current.forward[0]; return nextNode ? nextNode.value : undefined; } /** * Time Complexity: O(log n) * Space Complexity: O(1) * * Get the value of the last element in the Skip List that is less than the given key. * @param key - the given key. * @returns The value of the last element less than the given key, or undefined if there is no such element. */ lower(key) { let current = this.head; let lastLess = undefined; for (let i = this.level - 1; i >= 0; i--) { while (current.forward[i] && current.forward[i].key < key) { current = current.forward[i]; } if (current.key < key) { lastLess = current; } } return lastLess ? lastLess.value : undefined; } /** * Time Complexity: O(maxLevel) * Space Complexity: O(1) * * The function "_randomLevel" generates a random level based on a given probability and maximum level. * @returns the level, which is a number. */ _randomLevel() { let level = 1; while (Math.random() < this.probability && level < this.maxLevel) { level++; } return level; } } exports.SkipList = SkipList;