list-toolkit 2.2.5 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +40 -36
- package/llms-full.txt +743 -0
- package/llms.txt +100 -0
- package/package.json +40 -32
- package/src/cache/cache-fifo.d.ts +6 -0
- package/src/cache/cache-fifo.js +7 -4
- package/src/cache/cache-lfu.d.ts +18 -0
- package/src/cache/cache-lfu.js +18 -6
- package/src/cache/cache-lru.d.ts +74 -0
- package/src/cache/cache-lru.js +60 -5
- package/src/cache/cache-random.d.ts +20 -0
- package/src/cache/cache-random.js +17 -6
- package/src/cache/decorator.d.ts +46 -0
- package/src/cache/decorator.js +26 -2
- package/src/cache.d.ts +13 -0
- package/src/cache.js +7 -2
- package/src/ext-list.d.ts +3 -0
- package/src/ext-list.js +0 -2
- package/src/ext-slist.d.ts +3 -0
- package/src/ext-slist.js +0 -2
- package/src/ext-value-list.d.ts +3 -0
- package/src/ext-value-list.js +0 -2
- package/src/ext-value-slist.d.ts +3 -0
- package/src/ext-value-slist.js +0 -2
- package/src/heap/basics.d.ts +89 -0
- package/src/heap/basics.js +42 -5
- package/src/heap/leftist-heap.d.ts +107 -0
- package/src/heap/leftist-heap.js +54 -2
- package/src/heap/min-heap.d.ts +270 -0
- package/src/heap/min-heap.js +186 -2
- package/src/heap/skew-heap.d.ts +105 -0
- package/src/heap/skew-heap.js +54 -2
- package/src/heap.d.ts +3 -0
- package/src/heap.js +0 -2
- package/src/list/basics.d.ts +43 -0
- package/src/list/basics.js +26 -8
- package/src/list/core.d.ts +271 -0
- package/src/list/core.js +162 -7
- package/src/list/ext-value.d.ts +253 -0
- package/src/list/ext-value.js +40 -6
- package/src/list/ext.d.ts +242 -0
- package/src/list/ext.js +148 -10
- package/src/list/nodes.d.ts +336 -0
- package/src/list/nodes.js +141 -3
- package/src/list/ptr.d.ts +72 -0
- package/src/list/ptr.js +44 -2
- package/src/list/value.d.ts +292 -0
- package/src/list/value.js +47 -6
- package/src/list-helpers.d.ts +44 -0
- package/src/list-helpers.js +36 -3
- package/src/list-utils.d.ts +141 -0
- package/src/list-utils.js +89 -3
- package/src/list.d.ts +3 -0
- package/src/list.js +0 -2
- package/src/meta-utils.d.ts +212 -0
- package/src/meta-utils.js +152 -1
- package/src/nt-utils.d.ts +91 -0
- package/src/nt-utils.js +65 -4
- package/src/queue.d.ts +74 -0
- package/src/queue.js +28 -2
- package/src/slist/basics.d.ts +47 -0
- package/src/slist/basics.js +23 -8
- package/src/slist/core.d.ts +251 -0
- package/src/slist/core.js +151 -6
- package/src/slist/ext-value.d.ts +188 -0
- package/src/slist/ext-value.js +35 -6
- package/src/slist/ext.d.ts +182 -0
- package/src/slist/ext.js +114 -12
- package/src/slist/nodes.d.ts +361 -0
- package/src/slist/nodes.js +156 -3
- package/src/slist/ptr.d.ts +73 -0
- package/src/slist/ptr.js +45 -2
- package/src/slist/value.d.ts +246 -0
- package/src/slist/value.js +38 -6
- package/src/slist.d.ts +3 -0
- package/src/slist.js +0 -2
- package/src/stack.d.ts +59 -0
- package/src/stack.js +29 -3
- package/src/tree/splay-tree.d.ts +151 -0
- package/src/tree/splay-tree.js +94 -3
- package/src/value-list.d.ts +3 -0
- package/src/value-list.js +0 -2
- package/src/value-slist.d.ts +3 -0
- package/src/value-slist.js +0 -2
- package/cjs/cache/cache-fifo.js +0 -37
- package/cjs/cache/cache-lfu.js +0 -76
- package/cjs/cache/cache-lru.js +0 -100
- package/cjs/cache/cache-random.js +0 -77
- package/cjs/cache/decorator.js +0 -47
- package/cjs/cache.js +0 -27
- package/cjs/ext-list.js +0 -21
- package/cjs/ext-slist.js +0 -21
- package/cjs/ext-value-list.js +0 -21
- package/cjs/ext-value-slist.js +0 -21
- package/cjs/heap/basics.js +0 -63
- package/cjs/heap/leftist-heap.js +0 -124
- package/cjs/heap/min-heap.js +0 -294
- package/cjs/heap/skew-heap.js +0 -114
- package/cjs/heap.js +0 -21
- package/cjs/list/basics.js +0 -88
- package/cjs/list/core.js +0 -305
- package/cjs/list/ext-value.js +0 -88
- package/cjs/list/ext.js +0 -356
- package/cjs/list/nodes.js +0 -240
- package/cjs/list/ptr.js +0 -61
- package/cjs/list/value.js +0 -99
- package/cjs/list-helpers.js +0 -91
- package/cjs/list-utils.js +0 -141
- package/cjs/list.js +0 -21
- package/cjs/meta-utils.js +0 -171
- package/cjs/nt-utils.js +0 -132
- package/cjs/package.json +0 -1
- package/cjs/queue.js +0 -58
- package/cjs/slist/basics.js +0 -71
- package/cjs/slist/core.js +0 -362
- package/cjs/slist/ext-value.js +0 -82
- package/cjs/slist/ext.js +0 -336
- package/cjs/slist/nodes.js +0 -276
- package/cjs/slist/ptr.js +0 -87
- package/cjs/slist/value.js +0 -90
- package/cjs/slist.js +0 -21
- package/cjs/stack.js +0 -55
- package/cjs/tree/splay-tree.js +0 -362
- package/cjs/value-list.js +0 -21
- package/cjs/value-slist.js +0 -21
package/src/cache/decorator.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Wrap a function with caching. The first argument is used as the cache key.
|
|
3
|
+
* @param {Function} fn - Function to wrap.
|
|
4
|
+
* @param {object} cache - Cache instance with `has`, `get`, and `set` methods.
|
|
5
|
+
* @returns {Function} The wrapped function with `.fn` and `.cache` properties.
|
|
6
|
+
*/
|
|
3
7
|
export const decorateFn = (fn, cache) => {
|
|
4
8
|
if (typeof fn !== 'function') throw new TypeError('Not a function');
|
|
5
9
|
const wrapped = function (...args) {
|
|
@@ -15,6 +19,13 @@ export const decorateFn = (fn, cache) => {
|
|
|
15
19
|
return wrapped;
|
|
16
20
|
};
|
|
17
21
|
|
|
22
|
+
/**
|
|
23
|
+
* Replace a property descriptor's value with a cached version.
|
|
24
|
+
* @param {object} object - Object owning the property.
|
|
25
|
+
* @param {string} key - Property name.
|
|
26
|
+
* @param {object} cache - Cache instance.
|
|
27
|
+
* @returns {Function} The wrapped function.
|
|
28
|
+
*/
|
|
18
29
|
export const decorate = (object, key, cache) => {
|
|
19
30
|
const descriptor = Object.getOwnPropertyDescriptor(object, key);
|
|
20
31
|
if (!descriptor) throw new Error('Missing property: ' + key);
|
|
@@ -29,6 +40,13 @@ export const decorate = (object, key, cache) => {
|
|
|
29
40
|
return wrapped;
|
|
30
41
|
};
|
|
31
42
|
|
|
43
|
+
/**
|
|
44
|
+
* Replace a method on an object with a cached version.
|
|
45
|
+
* @param {object} object - Object owning the method.
|
|
46
|
+
* @param {string} key - Method name.
|
|
47
|
+
* @param {object} cache - Cache instance.
|
|
48
|
+
* @returns {Function} The wrapped function.
|
|
49
|
+
*/
|
|
32
50
|
export const decorateMethod = (object, key, cache) => {
|
|
33
51
|
const fn = object[key],
|
|
34
52
|
wrapped = decorateFn(fn, cache);
|
|
@@ -36,6 +54,12 @@ export const decorateMethod = (object, key, cache) => {
|
|
|
36
54
|
return wrapped;
|
|
37
55
|
};
|
|
38
56
|
|
|
57
|
+
/**
|
|
58
|
+
* Retrieve the cache instance from a decorated property.
|
|
59
|
+
* @param {object} object - Object owning the property.
|
|
60
|
+
* @param {string} key - Property name.
|
|
61
|
+
* @returns {object} The cache instance.
|
|
62
|
+
*/
|
|
39
63
|
export const getCache = (object, key) => {
|
|
40
64
|
const descriptor = Object.getOwnPropertyDescriptor(object, key);
|
|
41
65
|
if (!descriptor) throw new Error('Missing property: ' + key);
|
package/src/cache.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export * from './cache/cache-lru.js';
|
|
2
|
+
import Cache from './cache/cache-lru.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Convenience wrapper around the cache decorator.
|
|
6
|
+
* @param object - Object owning the method.
|
|
7
|
+
* @param key - Method name.
|
|
8
|
+
* @param cache - Cache instance (default: new CacheLRU).
|
|
9
|
+
* @returns The wrapped function.
|
|
10
|
+
*/
|
|
11
|
+
export function cacheDecorator(object: object, key: PropertyKey, cache?: Cache): object;
|
|
12
|
+
|
|
13
|
+
export default Cache;
|
package/src/cache.js
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
1
|
export * from './cache/cache-lru.js';
|
|
4
2
|
import Cache from './cache/cache-lru.js';
|
|
5
3
|
import decorator from './cache/decorator.js';
|
|
6
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Convenience decorator that wraps a property with LRU caching.
|
|
7
|
+
* @param {object} object - Object owning the property.
|
|
8
|
+
* @param {string} key - Property name.
|
|
9
|
+
* @param {object} [cache] - Cache instance (default: new CacheLRU).
|
|
10
|
+
* @returns {Function} The wrapped function.
|
|
11
|
+
*/
|
|
7
12
|
export const cacheDecorator = (object, key, cache = new Cache()) => decorator(object, key, cache);
|
|
8
13
|
|
|
9
14
|
export default Cache;
|
package/src/ext-list.js
CHANGED
package/src/ext-slist.js
CHANGED
package/src/ext-value-list.js
CHANGED
package/src/ext-value-slist.js
CHANGED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/** Options for configuring heap ordering. */
|
|
2
|
+
export interface HeapOptions<T = unknown> {
|
|
3
|
+
/** Returns `true` if `a` should be ordered before `b`. */
|
|
4
|
+
less?: (a: T, b: T) => boolean;
|
|
5
|
+
/** Returns `true` if `a` and `b` are considered equal. */
|
|
6
|
+
equal?: (a: T, b: T) => boolean;
|
|
7
|
+
/** Comparison function returning negative, zero, or positive. Overrides `less`/`equal` when set. */
|
|
8
|
+
compare?: ((a: T, b: T) => number) | null;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/** Abstract base class for heap implementations. */
|
|
12
|
+
export class HeapBase<T = unknown> {
|
|
13
|
+
/** Returns `true` if `a` should be ordered before `b`. */
|
|
14
|
+
less: (a: T, b: T) => boolean;
|
|
15
|
+
/** Returns `true` if `a` and `b` are considered equal. */
|
|
16
|
+
equal: (a: T, b: T) => boolean;
|
|
17
|
+
/** Comparison function, or `null` if using `less`/`equal`. */
|
|
18
|
+
compare: ((a: T, b: T) => number) | null;
|
|
19
|
+
|
|
20
|
+
/** @param options - Ordering functions. */
|
|
21
|
+
constructor(options?: HeapOptions<T>);
|
|
22
|
+
|
|
23
|
+
/** Whether the heap has no elements. */
|
|
24
|
+
get isEmpty(): boolean;
|
|
25
|
+
|
|
26
|
+
/** The minimum element without removing it. */
|
|
27
|
+
get top(): T | undefined;
|
|
28
|
+
|
|
29
|
+
/** Alias for {@link top}. */
|
|
30
|
+
peek(): T | undefined;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Remove and return the minimum element.
|
|
34
|
+
* @returns The minimum element, or `undefined` if empty.
|
|
35
|
+
*/
|
|
36
|
+
pop(): T | undefined;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Insert a value into the heap.
|
|
40
|
+
* @param value - Value to insert.
|
|
41
|
+
* @returns `this` for chaining.
|
|
42
|
+
*/
|
|
43
|
+
push(value: T): this;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Remove all elements.
|
|
47
|
+
* @returns `this` for chaining.
|
|
48
|
+
*/
|
|
49
|
+
clear(): this;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Push a value then immediately pop the minimum.
|
|
53
|
+
* @param value - Value to push.
|
|
54
|
+
* @returns The minimum element after the push.
|
|
55
|
+
*/
|
|
56
|
+
pushPop(value: T): T;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Pop the minimum then push a new value.
|
|
60
|
+
* @param value - Value to push after popping.
|
|
61
|
+
* @returns The old minimum element.
|
|
62
|
+
*/
|
|
63
|
+
replaceTop(value: T): T | undefined;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Merge other heaps or iterables into this heap.
|
|
67
|
+
* @param args - Heaps or iterables to merge.
|
|
68
|
+
* @returns `this` for chaining.
|
|
69
|
+
*/
|
|
70
|
+
merge(...args: Array<HeapBase<T> | Iterable<T>>): this;
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Create a deep copy of this heap.
|
|
74
|
+
* @returns A new heap with the same elements.
|
|
75
|
+
*/
|
|
76
|
+
clone(): HeapBase<T>;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Create a new empty heap with the same options.
|
|
80
|
+
* @param args - Additional constructor arguments.
|
|
81
|
+
* @returns A new heap.
|
|
82
|
+
*/
|
|
83
|
+
make(...args: any[]): HeapBase<T>;
|
|
84
|
+
|
|
85
|
+
/** Default ordering functions. */
|
|
86
|
+
static defaults: HeapOptions;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export default HeapBase;
|
package/src/heap/basics.js
CHANGED
|
@@ -1,53 +1,90 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
1
|
import {copyOptions} from '../meta-utils.js';
|
|
4
2
|
|
|
5
3
|
const defaultLess = (a, b) => a < b;
|
|
6
4
|
const defaultEqual = (a, b) => a === b;
|
|
7
5
|
|
|
6
|
+
/** Abstract base class for heap implementations. */
|
|
8
7
|
export class HeapBase {
|
|
8
|
+
/** @param {object} [options] - Ordering options (`less`, `equal`, `compare`). */
|
|
9
9
|
constructor(options) {
|
|
10
10
|
copyOptions(this, HeapBase.defaults, options);
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
/** Whether the heap has no elements. */
|
|
14
14
|
get isEmpty() {
|
|
15
15
|
throw new Error('Not implemented');
|
|
16
16
|
}
|
|
17
|
+
/** The minimum element without removing it. */
|
|
17
18
|
get top() {
|
|
18
19
|
throw new Error('Not implemented');
|
|
19
20
|
}
|
|
21
|
+
/** Alias for {@link HeapBase#top|top}. */
|
|
20
22
|
peek() {
|
|
21
23
|
return this.top;
|
|
22
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* Remove and return the minimum element.
|
|
27
|
+
* @returns {*} The removed element.
|
|
28
|
+
*/
|
|
23
29
|
pop() {
|
|
24
30
|
throw new Error('Not implemented');
|
|
25
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* Add an element to the heap.
|
|
34
|
+
* @param {*} value - Element to add.
|
|
35
|
+
* @returns {HeapBase} `this` for chaining.
|
|
36
|
+
*/
|
|
26
37
|
push() {
|
|
27
38
|
throw new Error('Not implemented');
|
|
28
39
|
}
|
|
40
|
+
/**
|
|
41
|
+
* Remove all elements.
|
|
42
|
+
* @returns {HeapBase} `this` for chaining.
|
|
43
|
+
*/
|
|
29
44
|
clear() {
|
|
30
45
|
throw new Error('Not implemented');
|
|
31
46
|
}
|
|
32
47
|
|
|
33
|
-
|
|
48
|
+
/**
|
|
49
|
+
* Push then pop in one operation (more efficient than separate calls).
|
|
50
|
+
* @param {*} value - Element to push.
|
|
51
|
+
* @returns {*} The popped element.
|
|
52
|
+
*/
|
|
34
53
|
pushPop(value) {
|
|
35
54
|
this.push(value);
|
|
36
55
|
return this.pop();
|
|
37
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* Pop then push in one operation (more efficient than separate calls).
|
|
59
|
+
* @param {*} value - Element to push.
|
|
60
|
+
* @returns {*} The popped element.
|
|
61
|
+
*/
|
|
38
62
|
replaceTop(value) {
|
|
39
63
|
const z = this.pop();
|
|
40
64
|
this.push(value);
|
|
41
65
|
return z;
|
|
42
66
|
}
|
|
43
67
|
|
|
44
|
-
|
|
68
|
+
/**
|
|
69
|
+
* Merge one or more iterables or heaps into this heap.
|
|
70
|
+
* @param {...Iterable} args - Arrays or heaps to merge.
|
|
71
|
+
* @returns {HeapBase} `this` for chaining.
|
|
72
|
+
*/
|
|
45
73
|
merge(...args) {
|
|
46
74
|
throw new Error('Not implemented');
|
|
47
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* Create a shallow copy of this heap.
|
|
78
|
+
* @returns {HeapBase} A new heap with the same elements.
|
|
79
|
+
*/
|
|
48
80
|
clone() {
|
|
49
81
|
throw new Error('Not implemented');
|
|
50
82
|
}
|
|
83
|
+
/**
|
|
84
|
+
* Create an empty heap with the same options.
|
|
85
|
+
* @param {...*} args - Additional arguments for the constructor.
|
|
86
|
+
* @returns {HeapBase} A new heap.
|
|
87
|
+
*/
|
|
51
88
|
make(...args) {
|
|
52
89
|
return new this.constructor(this, ...args);
|
|
53
90
|
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import HeapBase, {HeapOptions} from './basics.js';
|
|
2
|
+
|
|
3
|
+
/** Node used internally by {@link LeftistHeap}. */
|
|
4
|
+
export class LeftistHeapNode<T = unknown> {
|
|
5
|
+
/** The stored value. */
|
|
6
|
+
value: T;
|
|
7
|
+
/** Left child, or `null`. */
|
|
8
|
+
left: LeftistHeapNode<T> | null;
|
|
9
|
+
/** Right child, or `null`. */
|
|
10
|
+
right: LeftistHeapNode<T> | null;
|
|
11
|
+
/** S-value (rank) of this node. */
|
|
12
|
+
s: number;
|
|
13
|
+
|
|
14
|
+
/** @param value - Value to store. */
|
|
15
|
+
constructor(value: T);
|
|
16
|
+
|
|
17
|
+
/** Reset children to `null` and s-value to 1. */
|
|
18
|
+
clear(): void;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Create a deep copy of this subtree.
|
|
22
|
+
* @returns A new LeftistHeapNode tree.
|
|
23
|
+
*/
|
|
24
|
+
clone(): LeftistHeapNode<T>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Merge-based leftist heap. */
|
|
28
|
+
export class LeftistHeap<T = unknown> extends HeapBase<T> {
|
|
29
|
+
/** Root node, or `null` if empty. */
|
|
30
|
+
root: LeftistHeapNode<T> | null;
|
|
31
|
+
/** Number of elements. */
|
|
32
|
+
size: number;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @param options - Ordering functions.
|
|
36
|
+
* @param args - Initial heaps to merge.
|
|
37
|
+
*/
|
|
38
|
+
constructor(options?: HeapOptions<T>, ...args: LeftistHeap<T>[]);
|
|
39
|
+
|
|
40
|
+
/** Whether the heap has no elements. */
|
|
41
|
+
get isEmpty(): boolean;
|
|
42
|
+
|
|
43
|
+
/** Number of elements. */
|
|
44
|
+
get length(): number;
|
|
45
|
+
|
|
46
|
+
/** The minimum element without removing it. */
|
|
47
|
+
get top(): T | undefined;
|
|
48
|
+
|
|
49
|
+
/** Alias for {@link top}. */
|
|
50
|
+
peek(): T | undefined;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Insert a value into the heap.
|
|
54
|
+
* @param value - Value to insert.
|
|
55
|
+
* @returns `this` for chaining.
|
|
56
|
+
*/
|
|
57
|
+
push(value: T): this;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Remove and return the minimum element.
|
|
61
|
+
* @returns The minimum element, or `undefined` if empty.
|
|
62
|
+
*/
|
|
63
|
+
pop(): T | undefined;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Push a value then immediately pop the minimum.
|
|
67
|
+
* @param value - Value to push.
|
|
68
|
+
* @returns The minimum element after the push.
|
|
69
|
+
*/
|
|
70
|
+
pushPop(value: T): T;
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Pop the minimum then push a new value.
|
|
74
|
+
* @param value - Value to push after popping.
|
|
75
|
+
* @returns The old minimum element, or `undefined` if was empty.
|
|
76
|
+
*/
|
|
77
|
+
replaceTop(value: T): T | undefined;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Remove all elements.
|
|
81
|
+
* @returns `this` for chaining.
|
|
82
|
+
*/
|
|
83
|
+
clear(): this;
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Merge other leftist heaps into this one, consuming them.
|
|
87
|
+
* @param args - Heaps to merge (they are cleared).
|
|
88
|
+
* @returns `this` for chaining.
|
|
89
|
+
*/
|
|
90
|
+
merge(...args: LeftistHeap<T>[]): this;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Create a deep copy of this heap.
|
|
94
|
+
* @returns A new LeftistHeap with the same elements.
|
|
95
|
+
*/
|
|
96
|
+
clone(): LeftistHeap<T>;
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Build a LeftistHeap from an iterable.
|
|
100
|
+
* @param array - Iterable of values.
|
|
101
|
+
* @param options - Ordering functions.
|
|
102
|
+
* @returns A new LeftistHeap.
|
|
103
|
+
*/
|
|
104
|
+
static from<T = unknown>(array: Iterable<T>, options?: HeapOptions<T>): LeftistHeap<T>;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export default LeftistHeap;
|
package/src/heap/leftist-heap.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
1
|
import HeapBase from './basics.js';
|
|
4
2
|
|
|
5
3
|
const defaultLess = (a, b) => a < b;
|
|
@@ -24,16 +22,23 @@ const merge = (a, b, less) => {
|
|
|
24
22
|
return a;
|
|
25
23
|
};
|
|
26
24
|
|
|
25
|
+
/** Node for a leftist heap. */
|
|
27
26
|
export class LeftistHeapNode {
|
|
27
|
+
/** @param {*} value - Value to store. */
|
|
28
28
|
constructor(value) {
|
|
29
29
|
this.value = value;
|
|
30
30
|
this.right = this.left = null;
|
|
31
31
|
this.s = 1;
|
|
32
32
|
}
|
|
33
|
+
/** Reset child links and rank. */
|
|
33
34
|
clear() {
|
|
34
35
|
this.left = this.right = null;
|
|
35
36
|
this.s = 1;
|
|
36
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* Deep-clone this node and its subtree.
|
|
40
|
+
* @returns {LeftistHeapNode} A new node tree.
|
|
41
|
+
*/
|
|
37
42
|
clone() {
|
|
38
43
|
const node = new LeftistHeapNode(this.value);
|
|
39
44
|
node.left = this.left && this.left.clone();
|
|
@@ -42,7 +47,12 @@ export class LeftistHeapNode {
|
|
|
42
47
|
}
|
|
43
48
|
}
|
|
44
49
|
|
|
50
|
+
/** Leftist heap — a merge-based min-heap using node ranks. */
|
|
45
51
|
export class LeftistHeap extends HeapBase {
|
|
52
|
+
/**
|
|
53
|
+
* @param {object} [options] - Ordering options (`less`, `compare`).
|
|
54
|
+
* @param {...LeftistHeap} args - Initial heaps to merge.
|
|
55
|
+
*/
|
|
46
56
|
constructor(options, ...args) {
|
|
47
57
|
super(options);
|
|
48
58
|
if (typeof this.compare == 'function') {
|
|
@@ -52,23 +62,36 @@ export class LeftistHeap extends HeapBase {
|
|
|
52
62
|
this.size = 0;
|
|
53
63
|
if (args.length) this.merge(...args);
|
|
54
64
|
}
|
|
65
|
+
/** Whether the heap has no elements. */
|
|
55
66
|
get isEmpty() {
|
|
56
67
|
return !this.root;
|
|
57
68
|
}
|
|
69
|
+
/** The number of elements. */
|
|
58
70
|
get length() {
|
|
59
71
|
return this.size;
|
|
60
72
|
}
|
|
73
|
+
/** The minimum element without removing it. */
|
|
61
74
|
get top() {
|
|
62
75
|
return this.root ? this.root.value : undefined;
|
|
63
76
|
}
|
|
77
|
+
/** Alias for {@link LeftistHeap#top|top}. */
|
|
64
78
|
peek() {
|
|
65
79
|
return this.root ? this.root.value : undefined;
|
|
66
80
|
}
|
|
81
|
+
/**
|
|
82
|
+
* Add an element.
|
|
83
|
+
* @param {*} value - Element to add.
|
|
84
|
+
* @returns {LeftistHeap} `this` for chaining.
|
|
85
|
+
*/
|
|
67
86
|
push(value) {
|
|
68
87
|
this.root = merge(this.root, new LeftistHeapNode(value), this.less);
|
|
69
88
|
++this.size;
|
|
70
89
|
return this;
|
|
71
90
|
}
|
|
91
|
+
/**
|
|
92
|
+
* Remove and return the minimum element.
|
|
93
|
+
* @returns {*} The removed element, or `undefined` if empty.
|
|
94
|
+
*/
|
|
72
95
|
pop() {
|
|
73
96
|
if (!this.root) return;
|
|
74
97
|
const z = this.root;
|
|
@@ -76,6 +99,11 @@ export class LeftistHeap extends HeapBase {
|
|
|
76
99
|
--this.size;
|
|
77
100
|
return z.value;
|
|
78
101
|
}
|
|
102
|
+
/**
|
|
103
|
+
* Push then pop in one operation.
|
|
104
|
+
* @param {*} value - Element to push.
|
|
105
|
+
* @returns {*} The popped element.
|
|
106
|
+
*/
|
|
79
107
|
pushPop(value) {
|
|
80
108
|
if (!this.root || this.less(value, this.root.value)) return value;
|
|
81
109
|
const z = this.root;
|
|
@@ -83,6 +111,11 @@ export class LeftistHeap extends HeapBase {
|
|
|
83
111
|
this.root = merge(this.root, z.right, this.less);
|
|
84
112
|
return z.value;
|
|
85
113
|
}
|
|
114
|
+
/**
|
|
115
|
+
* Pop then push in one operation.
|
|
116
|
+
* @param {*} value - Element to push.
|
|
117
|
+
* @returns {*} The previously minimum element, or `undefined` if was empty.
|
|
118
|
+
*/
|
|
86
119
|
replaceTop(value) {
|
|
87
120
|
if (!this.root) {
|
|
88
121
|
this.root = new LeftistHeapNode(value);
|
|
@@ -94,11 +127,20 @@ export class LeftistHeap extends HeapBase {
|
|
|
94
127
|
this.root = merge(this.root, z.right, this.less);
|
|
95
128
|
return z.value;
|
|
96
129
|
}
|
|
130
|
+
/**
|
|
131
|
+
* Remove all elements.
|
|
132
|
+
* @returns {LeftistHeap} `this` for chaining.
|
|
133
|
+
*/
|
|
97
134
|
clear() {
|
|
98
135
|
this.root = null;
|
|
99
136
|
this.size = 0;
|
|
100
137
|
return this;
|
|
101
138
|
}
|
|
139
|
+
/**
|
|
140
|
+
* Merge one or more heaps into this heap, consuming them.
|
|
141
|
+
* @param {...LeftistHeap} args - Heaps to merge.
|
|
142
|
+
* @returns {LeftistHeap} `this` for chaining.
|
|
143
|
+
*/
|
|
102
144
|
merge(...args) {
|
|
103
145
|
for (const other of args) {
|
|
104
146
|
this.root = merge(this.root, other.root, this.less);
|
|
@@ -108,6 +150,10 @@ export class LeftistHeap extends HeapBase {
|
|
|
108
150
|
}
|
|
109
151
|
return this;
|
|
110
152
|
}
|
|
153
|
+
/**
|
|
154
|
+
* Create a deep copy of this heap.
|
|
155
|
+
* @returns {LeftistHeap} A new LeftistHeap with cloned nodes.
|
|
156
|
+
*/
|
|
111
157
|
clone() {
|
|
112
158
|
const heap = new LeftistHeap(this);
|
|
113
159
|
heap.root = this.root && this.root.clone();
|
|
@@ -115,6 +161,12 @@ export class LeftistHeap extends HeapBase {
|
|
|
115
161
|
return heap;
|
|
116
162
|
}
|
|
117
163
|
|
|
164
|
+
/**
|
|
165
|
+
* Build a LeftistHeap from an iterable.
|
|
166
|
+
* @param {Iterable} array - Elements to insert.
|
|
167
|
+
* @param {object} [options] - Ordering options.
|
|
168
|
+
* @returns {LeftistHeap} A new LeftistHeap.
|
|
169
|
+
*/
|
|
118
170
|
static from(array, options = HeapBase.defaults) {
|
|
119
171
|
const heap = new LeftistHeap(options);
|
|
120
172
|
for (const value of array) heap.push(value);
|