doubly-linked-list-typed
Version:
Doubly Linked List
245 lines (244 loc) • 8.82 kB
JavaScript
"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;