linked-list-typed 2.4.4 → 2.5.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 +14 -50
- package/dist/cjs/index.cjs +1537 -267
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs-legacy/index.cjs +1543 -264
- package/dist/cjs-legacy/index.cjs.map +1 -1
- package/dist/esm/index.mjs +1537 -268
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm-legacy/index.mjs +1543 -265
- package/dist/esm-legacy/index.mjs.map +1 -1
- package/dist/types/common/error.d.ts +23 -0
- package/dist/types/common/index.d.ts +1 -0
- package/dist/types/data-structures/base/iterable-element-base.d.ts +1 -1
- package/dist/types/data-structures/binary-tree/avl-tree.d.ts +128 -51
- package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +210 -164
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +439 -78
- package/dist/types/data-structures/binary-tree/bst.d.ts +311 -28
- package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +217 -31
- package/dist/types/data-structures/binary-tree/segment-tree.d.ts +218 -152
- package/dist/types/data-structures/binary-tree/tree-map.d.ts +1281 -5
- package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +1087 -201
- package/dist/types/data-structures/binary-tree/tree-multi-set.d.ts +858 -65
- package/dist/types/data-structures/binary-tree/tree-set.d.ts +1133 -5
- package/dist/types/data-structures/graph/abstract-graph.d.ts +44 -0
- package/dist/types/data-structures/graph/directed-graph.d.ts +220 -47
- package/dist/types/data-structures/graph/map-graph.d.ts +59 -1
- package/dist/types/data-structures/graph/undirected-graph.d.ts +218 -59
- package/dist/types/data-structures/hash/hash-map.d.ts +230 -77
- package/dist/types/data-structures/heap/heap.d.ts +287 -99
- package/dist/types/data-structures/heap/max-heap.d.ts +46 -0
- package/dist/types/data-structures/heap/min-heap.d.ts +59 -0
- package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +286 -44
- package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +278 -65
- package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +415 -12
- package/dist/types/data-structures/matrix/matrix.d.ts +331 -0
- package/dist/types/data-structures/priority-queue/max-priority-queue.d.ts +57 -0
- package/dist/types/data-structures/priority-queue/min-priority-queue.d.ts +60 -0
- package/dist/types/data-structures/priority-queue/priority-queue.d.ts +60 -0
- package/dist/types/data-structures/queue/deque.d.ts +313 -66
- package/dist/types/data-structures/queue/queue.d.ts +211 -42
- package/dist/types/data-structures/stack/stack.d.ts +174 -32
- package/dist/types/data-structures/trie/trie.d.ts +213 -43
- package/dist/types/types/data-structures/binary-tree/segment-tree.d.ts +1 -1
- package/dist/types/types/data-structures/linked-list/skip-linked-list.d.ts +1 -4
- package/dist/types/types/data-structures/queue/deque.d.ts +6 -0
- package/dist/umd/linked-list-typed.js +1540 -262
- package/dist/umd/linked-list-typed.js.map +1 -1
- package/dist/umd/linked-list-typed.min.js +1 -1
- package/dist/umd/linked-list-typed.min.js.map +1 -1
- package/package.json +2 -2
- package/src/common/error.ts +60 -0
- package/src/common/index.ts +2 -0
- package/src/data-structures/base/iterable-element-base.ts +2 -2
- package/src/data-structures/binary-tree/avl-tree.ts +134 -51
- package/src/data-structures/binary-tree/binary-indexed-tree.ts +303 -247
- package/src/data-structures/binary-tree/binary-tree.ts +542 -121
- package/src/data-structures/binary-tree/bst.ts +346 -37
- package/src/data-structures/binary-tree/red-black-tree.ts +309 -96
- package/src/data-structures/binary-tree/segment-tree.ts +372 -248
- package/src/data-structures/binary-tree/tree-map.ts +1292 -13
- package/src/data-structures/binary-tree/tree-multi-map.ts +1098 -215
- package/src/data-structures/binary-tree/tree-multi-set.ts +863 -69
- package/src/data-structures/binary-tree/tree-set.ts +1143 -15
- package/src/data-structures/graph/abstract-graph.ts +106 -1
- package/src/data-structures/graph/directed-graph.ts +223 -47
- package/src/data-structures/graph/map-graph.ts +59 -1
- package/src/data-structures/graph/undirected-graph.ts +299 -59
- package/src/data-structures/hash/hash-map.ts +243 -79
- package/src/data-structures/heap/heap.ts +291 -102
- package/src/data-structures/heap/max-heap.ts +48 -3
- package/src/data-structures/heap/min-heap.ts +59 -0
- package/src/data-structures/linked-list/doubly-linked-list.ts +286 -44
- package/src/data-structures/linked-list/singly-linked-list.ts +278 -65
- package/src/data-structures/linked-list/skip-linked-list.ts +689 -90
- package/src/data-structures/matrix/matrix.ts +425 -22
- package/src/data-structures/priority-queue/max-priority-queue.ts +59 -3
- package/src/data-structures/priority-queue/min-priority-queue.ts +60 -0
- package/src/data-structures/priority-queue/priority-queue.ts +60 -0
- package/src/data-structures/queue/deque.ts +343 -68
- package/src/data-structures/queue/queue.ts +211 -42
- package/src/data-structures/stack/stack.ts +174 -32
- package/src/data-structures/trie/trie.ts +215 -44
- package/src/types/data-structures/binary-tree/segment-tree.ts +1 -1
- package/src/types/data-structures/linked-list/skip-linked-list.ts +2 -1
- package/src/types/data-structures/queue/deque.ts +7 -0
- package/src/utils/utils.ts +4 -2
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
|
+
var __typeError = (msg) => {
|
|
5
|
+
throw TypeError(msg);
|
|
6
|
+
};
|
|
4
7
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
5
8
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
6
9
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
10
|
+
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
11
|
+
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
12
|
+
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
13
|
+
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
|
|
7
14
|
|
|
8
15
|
// src/data-structures/base/iterable-element-base.ts
|
|
9
16
|
var _IterableElementBase = class _IterableElementBase {
|
|
@@ -721,11 +728,37 @@ var _SinglyLinkedList = class _SinglyLinkedList extends LinearLinkedBase {
|
|
|
721
728
|
return list;
|
|
722
729
|
}
|
|
723
730
|
/**
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
731
|
+
* Append an element/node to the tail.
|
|
732
|
+
* @remarks Time O(1), Space O(1)
|
|
733
|
+
* @param elementOrNode - Element or node to append.
|
|
734
|
+
* @returns True when appended.
|
|
735
|
+
|
|
736
|
+
|
|
737
|
+
|
|
738
|
+
|
|
739
|
+
|
|
740
|
+
|
|
741
|
+
|
|
742
|
+
|
|
743
|
+
|
|
744
|
+
|
|
745
|
+
|
|
746
|
+
* @example
|
|
747
|
+
* // basic SinglyLinkedList creation and push operation
|
|
748
|
+
* // Create a simple SinglyLinkedList with initial values
|
|
749
|
+
* const list = new SinglyLinkedList([1, 2, 3, 4, 5]);
|
|
750
|
+
*
|
|
751
|
+
* // Verify the list maintains insertion order
|
|
752
|
+
* console.log([...list]); // [1, 2, 3, 4, 5];
|
|
753
|
+
*
|
|
754
|
+
* // Check length
|
|
755
|
+
* console.log(list.length); // 5;
|
|
756
|
+
*
|
|
757
|
+
* // Push a new element to the end
|
|
758
|
+
* list.push(6);
|
|
759
|
+
* console.log(list.length); // 6;
|
|
760
|
+
* console.log([...list]); // [1, 2, 3, 4, 5, 6];
|
|
761
|
+
*/
|
|
729
762
|
push(elementOrNode) {
|
|
730
763
|
const newNode = this._ensureNode(elementOrNode);
|
|
731
764
|
if (!this.head) {
|
|
@@ -739,10 +772,36 @@ var _SinglyLinkedList = class _SinglyLinkedList extends LinearLinkedBase {
|
|
|
739
772
|
return true;
|
|
740
773
|
}
|
|
741
774
|
/**
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
775
|
+
* Remove and return the tail element.
|
|
776
|
+
* @remarks Time O(N), Space O(1)
|
|
777
|
+
* @returns Removed element or undefined.
|
|
778
|
+
|
|
779
|
+
|
|
780
|
+
|
|
781
|
+
|
|
782
|
+
|
|
783
|
+
|
|
784
|
+
|
|
785
|
+
|
|
786
|
+
|
|
787
|
+
|
|
788
|
+
|
|
789
|
+
* @example
|
|
790
|
+
* // SinglyLinkedList pop and shift operations
|
|
791
|
+
* const list = new SinglyLinkedList<number>([10, 20, 30, 40, 50]);
|
|
792
|
+
*
|
|
793
|
+
* // Pop removes from the end
|
|
794
|
+
* const last = list.pop();
|
|
795
|
+
* console.log(last); // 50;
|
|
796
|
+
*
|
|
797
|
+
* // Shift removes from the beginning
|
|
798
|
+
* const first = list.shift();
|
|
799
|
+
* console.log(first); // 10;
|
|
800
|
+
*
|
|
801
|
+
* // Verify remaining elements
|
|
802
|
+
* console.log([...list]); // [20, 30, 40];
|
|
803
|
+
* console.log(list.length); // 3;
|
|
804
|
+
*/
|
|
746
805
|
pop() {
|
|
747
806
|
var _a;
|
|
748
807
|
if (!this.head) return void 0;
|
|
@@ -762,10 +821,26 @@ var _SinglyLinkedList = class _SinglyLinkedList extends LinearLinkedBase {
|
|
|
762
821
|
return value;
|
|
763
822
|
}
|
|
764
823
|
/**
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
824
|
+
* Remove and return the head element.
|
|
825
|
+
* @remarks Time O(1), Space O(1)
|
|
826
|
+
* @returns Removed element or undefined.
|
|
827
|
+
|
|
828
|
+
|
|
829
|
+
|
|
830
|
+
|
|
831
|
+
|
|
832
|
+
|
|
833
|
+
|
|
834
|
+
|
|
835
|
+
|
|
836
|
+
|
|
837
|
+
|
|
838
|
+
* @example
|
|
839
|
+
* // Remove from the front
|
|
840
|
+
* const list = new SinglyLinkedList<number>([10, 20, 30]);
|
|
841
|
+
* console.log(list.shift()); // 10;
|
|
842
|
+
* console.log(list.length); // 2;
|
|
843
|
+
*/
|
|
769
844
|
shift() {
|
|
770
845
|
if (!this.head) return void 0;
|
|
771
846
|
const removed = this.head;
|
|
@@ -775,11 +850,42 @@ var _SinglyLinkedList = class _SinglyLinkedList extends LinearLinkedBase {
|
|
|
775
850
|
return removed.value;
|
|
776
851
|
}
|
|
777
852
|
/**
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
853
|
+
* Prepend an element/node to the head.
|
|
854
|
+
* @remarks Time O(1), Space O(1)
|
|
855
|
+
* @param elementOrNode - Element or node to prepend.
|
|
856
|
+
* @returns True when prepended.
|
|
857
|
+
|
|
858
|
+
|
|
859
|
+
|
|
860
|
+
|
|
861
|
+
|
|
862
|
+
|
|
863
|
+
|
|
864
|
+
|
|
865
|
+
|
|
866
|
+
|
|
867
|
+
|
|
868
|
+
* @example
|
|
869
|
+
* // SinglyLinkedList unshift and forward traversal
|
|
870
|
+
* const list = new SinglyLinkedList<number>([20, 30, 40]);
|
|
871
|
+
*
|
|
872
|
+
* // Unshift adds to the beginning
|
|
873
|
+
* list.unshift(10);
|
|
874
|
+
* console.log([...list]); // [10, 20, 30, 40];
|
|
875
|
+
*
|
|
876
|
+
* // Access elements (forward traversal only for singly linked)
|
|
877
|
+
* const second = list.at(1);
|
|
878
|
+
* console.log(second); // 20;
|
|
879
|
+
*
|
|
880
|
+
* // SinglyLinkedList allows forward iteration only
|
|
881
|
+
* const elements: number[] = [];
|
|
882
|
+
* for (const item of list) {
|
|
883
|
+
* elements.push(item);
|
|
884
|
+
* }
|
|
885
|
+
* console.log(elements); // [10, 20, 30, 40];
|
|
886
|
+
*
|
|
887
|
+
* console.log(list.length); // 4;
|
|
888
|
+
*/
|
|
783
889
|
unshift(elementOrNode) {
|
|
784
890
|
const newNode = this._ensureNode(elementOrNode);
|
|
785
891
|
if (!this.head) {
|
|
@@ -835,11 +941,28 @@ var _SinglyLinkedList = class _SinglyLinkedList extends LinearLinkedBase {
|
|
|
835
941
|
return void 0;
|
|
836
942
|
}
|
|
837
943
|
/**
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
944
|
+
* Get the element at a given index.
|
|
945
|
+
* @remarks Time O(N), Space O(1)
|
|
946
|
+
* @param index - Zero-based index.
|
|
947
|
+
* @returns Element or undefined.
|
|
948
|
+
|
|
949
|
+
|
|
950
|
+
|
|
951
|
+
|
|
952
|
+
|
|
953
|
+
|
|
954
|
+
|
|
955
|
+
|
|
956
|
+
|
|
957
|
+
|
|
958
|
+
|
|
959
|
+
* @example
|
|
960
|
+
* // Access element by index
|
|
961
|
+
* const list = new SinglyLinkedList<string>(['a', 'b', 'c', 'd']);
|
|
962
|
+
* console.log(list.at(0)); // 'a';
|
|
963
|
+
* console.log(list.at(2)); // 'c';
|
|
964
|
+
* console.log(list.at(3)); // 'd';
|
|
965
|
+
*/
|
|
843
966
|
at(index) {
|
|
844
967
|
if (index < 0 || index >= this._length) return void 0;
|
|
845
968
|
let current = this.head;
|
|
@@ -856,11 +979,23 @@ var _SinglyLinkedList = class _SinglyLinkedList extends LinearLinkedBase {
|
|
|
856
979
|
return elementNodeOrPredicate instanceof SinglyLinkedListNode;
|
|
857
980
|
}
|
|
858
981
|
/**
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
982
|
+
* Get the node reference at a given index.
|
|
983
|
+
* @remarks Time O(N), Space O(1)
|
|
984
|
+
* @param index - Zero-based index.
|
|
985
|
+
* @returns Node or undefined.
|
|
986
|
+
|
|
987
|
+
|
|
988
|
+
|
|
989
|
+
|
|
990
|
+
|
|
991
|
+
|
|
992
|
+
|
|
993
|
+
|
|
994
|
+
* @example
|
|
995
|
+
* // Get node at index
|
|
996
|
+
* const list = new SinglyLinkedList<string>(['a', 'b', 'c']);
|
|
997
|
+
* console.log(list.getNodeAt(1)?.value); // 'b';
|
|
998
|
+
*/
|
|
864
999
|
getNodeAt(index) {
|
|
865
1000
|
if (index < 0 || index >= this._length) return void 0;
|
|
866
1001
|
let current = this.head;
|
|
@@ -868,11 +1003,24 @@ var _SinglyLinkedList = class _SinglyLinkedList extends LinearLinkedBase {
|
|
|
868
1003
|
return current;
|
|
869
1004
|
}
|
|
870
1005
|
/**
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
1006
|
+
* Delete the element at an index.
|
|
1007
|
+
* @remarks Time O(N), Space O(1)
|
|
1008
|
+
* @param index - Zero-based index.
|
|
1009
|
+
* @returns Removed element or undefined.
|
|
1010
|
+
|
|
1011
|
+
|
|
1012
|
+
|
|
1013
|
+
|
|
1014
|
+
|
|
1015
|
+
|
|
1016
|
+
|
|
1017
|
+
|
|
1018
|
+
* @example
|
|
1019
|
+
* // Remove by index
|
|
1020
|
+
* const list = new SinglyLinkedList<string>(['a', 'b', 'c']);
|
|
1021
|
+
* list.deleteAt(1);
|
|
1022
|
+
* console.log(list.toArray()); // ['a', 'c'];
|
|
1023
|
+
*/
|
|
876
1024
|
deleteAt(index) {
|
|
877
1025
|
if (index < 0 || index >= this._length) return void 0;
|
|
878
1026
|
if (index === 0) return this.shift();
|
|
@@ -885,11 +1033,24 @@ var _SinglyLinkedList = class _SinglyLinkedList extends LinearLinkedBase {
|
|
|
885
1033
|
return value;
|
|
886
1034
|
}
|
|
887
1035
|
/**
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
1036
|
+
* Delete the first match by value/node.
|
|
1037
|
+
* @remarks Time O(N), Space O(1)
|
|
1038
|
+
* @param [elementOrNode] - Element or node to remove; if omitted/undefined, nothing happens.
|
|
1039
|
+
* @returns True if removed.
|
|
1040
|
+
|
|
1041
|
+
|
|
1042
|
+
|
|
1043
|
+
|
|
1044
|
+
|
|
1045
|
+
|
|
1046
|
+
|
|
1047
|
+
|
|
1048
|
+
* @example
|
|
1049
|
+
* // Remove first occurrence
|
|
1050
|
+
* const list = new SinglyLinkedList<number>([1, 2, 3, 2]);
|
|
1051
|
+
* list.delete(2);
|
|
1052
|
+
* console.log(list.toArray()); // [1, 3, 2];
|
|
1053
|
+
*/
|
|
893
1054
|
delete(elementOrNode) {
|
|
894
1055
|
if (elementOrNode === void 0 || !this.head) return false;
|
|
895
1056
|
const node = this.isNode(elementOrNode) ? elementOrNode : this.getNode(elementOrNode);
|
|
@@ -906,12 +1067,25 @@ var _SinglyLinkedList = class _SinglyLinkedList extends LinearLinkedBase {
|
|
|
906
1067
|
return true;
|
|
907
1068
|
}
|
|
908
1069
|
/**
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
1070
|
+
* Insert a new element/node at an index, shifting following nodes.
|
|
1071
|
+
* @remarks Time O(N), Space O(1)
|
|
1072
|
+
* @param index - Zero-based index.
|
|
1073
|
+
* @param newElementOrNode - Element or node to insert.
|
|
1074
|
+
* @returns True if inserted.
|
|
1075
|
+
|
|
1076
|
+
|
|
1077
|
+
|
|
1078
|
+
|
|
1079
|
+
|
|
1080
|
+
|
|
1081
|
+
|
|
1082
|
+
|
|
1083
|
+
* @example
|
|
1084
|
+
* // Insert at index
|
|
1085
|
+
* const list = new SinglyLinkedList<number>([1, 3]);
|
|
1086
|
+
* list.addAt(1, 2);
|
|
1087
|
+
* console.log(list.toArray()); // [1, 2, 3];
|
|
1088
|
+
*/
|
|
915
1089
|
addAt(index, newElementOrNode) {
|
|
916
1090
|
if (index < 0 || index > this._length) return false;
|
|
917
1091
|
if (index === 0) return this.unshift(newElementOrNode);
|
|
@@ -937,28 +1111,70 @@ var _SinglyLinkedList = class _SinglyLinkedList extends LinearLinkedBase {
|
|
|
937
1111
|
return true;
|
|
938
1112
|
}
|
|
939
1113
|
/**
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
1114
|
+
* Check whether the list is empty.
|
|
1115
|
+
* @remarks Time O(1), Space O(1)
|
|
1116
|
+
* @returns True if length is 0.
|
|
1117
|
+
|
|
1118
|
+
|
|
1119
|
+
|
|
1120
|
+
|
|
1121
|
+
|
|
1122
|
+
|
|
1123
|
+
|
|
1124
|
+
|
|
1125
|
+
|
|
1126
|
+
* @example
|
|
1127
|
+
* // Check empty
|
|
1128
|
+
* console.log(new SinglyLinkedList().isEmpty()); // true;
|
|
1129
|
+
*/
|
|
944
1130
|
isEmpty() {
|
|
945
1131
|
return this._length === 0;
|
|
946
1132
|
}
|
|
947
1133
|
/**
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
1134
|
+
* Remove all nodes and reset length.
|
|
1135
|
+
* @remarks Time O(N), Space O(1)
|
|
1136
|
+
* @returns void
|
|
1137
|
+
|
|
1138
|
+
|
|
1139
|
+
|
|
1140
|
+
|
|
1141
|
+
|
|
1142
|
+
|
|
1143
|
+
|
|
1144
|
+
|
|
1145
|
+
|
|
1146
|
+
* @example
|
|
1147
|
+
* // Remove all
|
|
1148
|
+
* const list = new SinglyLinkedList<number>([1, 2, 3]);
|
|
1149
|
+
* list.clear();
|
|
1150
|
+
* console.log(list.isEmpty()); // true;
|
|
1151
|
+
*/
|
|
952
1152
|
clear() {
|
|
953
1153
|
this._head = void 0;
|
|
954
1154
|
this._tail = void 0;
|
|
955
1155
|
this._length = 0;
|
|
956
1156
|
}
|
|
957
1157
|
/**
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
1158
|
+
* Reverse the list in place.
|
|
1159
|
+
* @remarks Time O(N), Space O(1)
|
|
1160
|
+
* @returns This list.
|
|
1161
|
+
|
|
1162
|
+
|
|
1163
|
+
|
|
1164
|
+
|
|
1165
|
+
|
|
1166
|
+
|
|
1167
|
+
|
|
1168
|
+
|
|
1169
|
+
|
|
1170
|
+
|
|
1171
|
+
|
|
1172
|
+
* @example
|
|
1173
|
+
* // Reverse the list in-place
|
|
1174
|
+
* const list = new SinglyLinkedList<number>([1, 2, 3, 4]);
|
|
1175
|
+
* list.reverse();
|
|
1176
|
+
* console.log([...list]); // [4, 3, 2, 1];
|
|
1177
|
+
*/
|
|
962
1178
|
reverse() {
|
|
963
1179
|
if (!this.head || this.head === this.tail) return this;
|
|
964
1180
|
let prev;
|
|
@@ -1133,22 +1349,64 @@ var _SinglyLinkedList = class _SinglyLinkedList extends LinearLinkedBase {
|
|
|
1133
1349
|
return false;
|
|
1134
1350
|
}
|
|
1135
1351
|
/**
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1352
|
+
* Deep clone this list (values are copied by reference).
|
|
1353
|
+
* @remarks Time O(N), Space O(N)
|
|
1354
|
+
* @returns A new list with the same element sequence.
|
|
1355
|
+
|
|
1356
|
+
|
|
1357
|
+
|
|
1358
|
+
|
|
1359
|
+
|
|
1360
|
+
|
|
1361
|
+
|
|
1362
|
+
|
|
1363
|
+
|
|
1364
|
+
* @example
|
|
1365
|
+
* // Deep copy
|
|
1366
|
+
* const list = new SinglyLinkedList<number>([1, 2, 3]);
|
|
1367
|
+
* const copy = list.clone();
|
|
1368
|
+
* copy.pop();
|
|
1369
|
+
* console.log(list.length); // 3;
|
|
1370
|
+
* console.log(copy.length); // 2;
|
|
1371
|
+
*/
|
|
1140
1372
|
clone() {
|
|
1141
1373
|
const out = this._createInstance();
|
|
1142
1374
|
for (const v of this) out.push(v);
|
|
1143
1375
|
return out;
|
|
1144
1376
|
}
|
|
1145
1377
|
/**
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1378
|
+
* Filter values into a new list of the same class.
|
|
1379
|
+
* @remarks Time O(N), Space O(N)
|
|
1380
|
+
* @param callback - Predicate (value, index, list) → boolean to keep value.
|
|
1381
|
+
* @param [thisArg] - Value for `this` inside the callback.
|
|
1382
|
+
* @returns A new list with kept values.
|
|
1383
|
+
|
|
1384
|
+
|
|
1385
|
+
|
|
1386
|
+
|
|
1387
|
+
|
|
1388
|
+
|
|
1389
|
+
|
|
1390
|
+
|
|
1391
|
+
|
|
1392
|
+
|
|
1393
|
+
|
|
1394
|
+
* @example
|
|
1395
|
+
* // SinglyLinkedList filter and map operations
|
|
1396
|
+
* const list = new SinglyLinkedList<number>([1, 2, 3, 4, 5]);
|
|
1397
|
+
*
|
|
1398
|
+
* // Filter even numbers
|
|
1399
|
+
* const filtered = list.filter(value => value % 2 === 0);
|
|
1400
|
+
* console.log(filtered.length); // 2;
|
|
1401
|
+
*
|
|
1402
|
+
* // Map to double values
|
|
1403
|
+
* const doubled = list.map(value => value * 2);
|
|
1404
|
+
* console.log(doubled.length); // 5;
|
|
1405
|
+
*
|
|
1406
|
+
* // Use reduce to sum
|
|
1407
|
+
* const sum = list.reduce((acc, value) => acc + value, 0);
|
|
1408
|
+
* console.log(sum); // 15;
|
|
1409
|
+
*/
|
|
1152
1410
|
filter(callback, thisArg) {
|
|
1153
1411
|
const out = this._createInstance();
|
|
1154
1412
|
let index = 0;
|
|
@@ -1172,15 +1430,31 @@ var _SinglyLinkedList = class _SinglyLinkedList extends LinearLinkedBase {
|
|
|
1172
1430
|
return out;
|
|
1173
1431
|
}
|
|
1174
1432
|
/**
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1433
|
+
* Map values into a new list (possibly different element type).
|
|
1434
|
+
* @remarks Time O(N), Space O(N)
|
|
1435
|
+
* @template EM
|
|
1436
|
+
* @template RM
|
|
1437
|
+
* @param callback - Mapping function (value, index, list) → newElement.
|
|
1438
|
+
* @param [options] - Options for the output list (e.g., maxLen, toElementFn).
|
|
1439
|
+
* @param [thisArg] - Value for `this` inside the callback.
|
|
1440
|
+
* @returns A new SinglyLinkedList with mapped values.
|
|
1441
|
+
|
|
1442
|
+
|
|
1443
|
+
|
|
1444
|
+
|
|
1445
|
+
|
|
1446
|
+
|
|
1447
|
+
|
|
1448
|
+
|
|
1449
|
+
|
|
1450
|
+
|
|
1451
|
+
|
|
1452
|
+
* @example
|
|
1453
|
+
* // Transform elements
|
|
1454
|
+
* const list = new SinglyLinkedList<number>([1, 2, 3]);
|
|
1455
|
+
* const doubled = list.map(n => n * 2);
|
|
1456
|
+
* console.log([...doubled]); // [2, 4, 6];
|
|
1457
|
+
*/
|
|
1184
1458
|
map(callback, options, thisArg) {
|
|
1185
1459
|
const out = this._createLike([], { ...options != null ? options : {}, maxLen: this._maxLen });
|
|
1186
1460
|
let index = 0;
|
|
@@ -1456,11 +1730,37 @@ var _DoublyLinkedList = class _DoublyLinkedList extends LinearLinkedBase {
|
|
|
1456
1730
|
return elementNodeOrPredicate instanceof DoublyLinkedListNode;
|
|
1457
1731
|
}
|
|
1458
1732
|
/**
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1733
|
+
* Append an element/node to the tail.
|
|
1734
|
+
* @remarks Time O(1), Space O(1)
|
|
1735
|
+
* @param elementOrNode - Element or node to append.
|
|
1736
|
+
* @returns True when appended.
|
|
1737
|
+
|
|
1738
|
+
|
|
1739
|
+
|
|
1740
|
+
|
|
1741
|
+
|
|
1742
|
+
|
|
1743
|
+
|
|
1744
|
+
|
|
1745
|
+
|
|
1746
|
+
|
|
1747
|
+
|
|
1748
|
+
* @example
|
|
1749
|
+
* // basic DoublyLinkedList creation and push operation
|
|
1750
|
+
* // Create a simple DoublyLinkedList with initial values
|
|
1751
|
+
* const list = new DoublyLinkedList([1, 2, 3, 4, 5]);
|
|
1752
|
+
*
|
|
1753
|
+
* // Verify the list maintains insertion order
|
|
1754
|
+
* console.log([...list]); // [1, 2, 3, 4, 5];
|
|
1755
|
+
*
|
|
1756
|
+
* // Check length
|
|
1757
|
+
* console.log(list.length); // 5;
|
|
1758
|
+
*
|
|
1759
|
+
* // Push a new element to the end
|
|
1760
|
+
* list.push(6);
|
|
1761
|
+
* console.log(list.length); // 6;
|
|
1762
|
+
* console.log([...list]); // [1, 2, 3, 4, 5, 6];
|
|
1763
|
+
*/
|
|
1464
1764
|
push(elementOrNode) {
|
|
1465
1765
|
const newNode = this._ensureNode(elementOrNode);
|
|
1466
1766
|
if (!this.head) {
|
|
@@ -1476,10 +1776,36 @@ var _DoublyLinkedList = class _DoublyLinkedList extends LinearLinkedBase {
|
|
|
1476
1776
|
return true;
|
|
1477
1777
|
}
|
|
1478
1778
|
/**
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1779
|
+
* Remove and return the tail element.
|
|
1780
|
+
* @remarks Time O(1), Space O(1)
|
|
1781
|
+
* @returns Removed element or undefined.
|
|
1782
|
+
|
|
1783
|
+
|
|
1784
|
+
|
|
1785
|
+
|
|
1786
|
+
|
|
1787
|
+
|
|
1788
|
+
|
|
1789
|
+
|
|
1790
|
+
|
|
1791
|
+
|
|
1792
|
+
|
|
1793
|
+
* @example
|
|
1794
|
+
* // DoublyLinkedList pop and shift operations
|
|
1795
|
+
* const list = new DoublyLinkedList<number>([10, 20, 30, 40, 50]);
|
|
1796
|
+
*
|
|
1797
|
+
* // Pop removes from the end
|
|
1798
|
+
* const last = list.pop();
|
|
1799
|
+
* console.log(last); // 50;
|
|
1800
|
+
*
|
|
1801
|
+
* // Shift removes from the beginning
|
|
1802
|
+
* const first = list.shift();
|
|
1803
|
+
* console.log(first); // 10;
|
|
1804
|
+
*
|
|
1805
|
+
* // Verify remaining elements
|
|
1806
|
+
* console.log([...list]); // [20, 30, 40];
|
|
1807
|
+
* console.log(list.length); // 3;
|
|
1808
|
+
*/
|
|
1483
1809
|
pop() {
|
|
1484
1810
|
if (!this.tail) return void 0;
|
|
1485
1811
|
const removed = this.tail;
|
|
@@ -1494,10 +1820,26 @@ var _DoublyLinkedList = class _DoublyLinkedList extends LinearLinkedBase {
|
|
|
1494
1820
|
return removed.value;
|
|
1495
1821
|
}
|
|
1496
1822
|
/**
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1823
|
+
* Remove and return the head element.
|
|
1824
|
+
* @remarks Time O(1), Space O(1)
|
|
1825
|
+
* @returns Removed element or undefined.
|
|
1826
|
+
|
|
1827
|
+
|
|
1828
|
+
|
|
1829
|
+
|
|
1830
|
+
|
|
1831
|
+
|
|
1832
|
+
|
|
1833
|
+
|
|
1834
|
+
|
|
1835
|
+
|
|
1836
|
+
|
|
1837
|
+
* @example
|
|
1838
|
+
* // Remove from the front
|
|
1839
|
+
* const list = new DoublyLinkedList<number>([10, 20, 30]);
|
|
1840
|
+
* console.log(list.shift()); // 10;
|
|
1841
|
+
* console.log(list.first); // 20;
|
|
1842
|
+
*/
|
|
1501
1843
|
shift() {
|
|
1502
1844
|
if (!this.head) return void 0;
|
|
1503
1845
|
const removed = this.head;
|
|
@@ -1512,11 +1854,27 @@ var _DoublyLinkedList = class _DoublyLinkedList extends LinearLinkedBase {
|
|
|
1512
1854
|
return removed.value;
|
|
1513
1855
|
}
|
|
1514
1856
|
/**
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1857
|
+
* Prepend an element/node to the head.
|
|
1858
|
+
* @remarks Time O(1), Space O(1)
|
|
1859
|
+
* @param elementOrNode - Element or node to prepend.
|
|
1860
|
+
* @returns True when prepended.
|
|
1861
|
+
|
|
1862
|
+
|
|
1863
|
+
|
|
1864
|
+
|
|
1865
|
+
|
|
1866
|
+
|
|
1867
|
+
|
|
1868
|
+
|
|
1869
|
+
|
|
1870
|
+
|
|
1871
|
+
|
|
1872
|
+
* @example
|
|
1873
|
+
* // Add to the front
|
|
1874
|
+
* const list = new DoublyLinkedList<number>([2, 3]);
|
|
1875
|
+
* list.unshift(1);
|
|
1876
|
+
* console.log([...list]); // [1, 2, 3];
|
|
1877
|
+
*/
|
|
1520
1878
|
unshift(elementOrNode) {
|
|
1521
1879
|
const newNode = this._ensureNode(elementOrNode);
|
|
1522
1880
|
if (!this.head) {
|
|
@@ -1560,11 +1918,27 @@ var _DoublyLinkedList = class _DoublyLinkedList extends LinearLinkedBase {
|
|
|
1560
1918
|
return ans;
|
|
1561
1919
|
}
|
|
1562
1920
|
/**
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1921
|
+
* Get the element at a given index.
|
|
1922
|
+
* @remarks Time O(N), Space O(1)
|
|
1923
|
+
* @param index - Zero-based index.
|
|
1924
|
+
* @returns Element or undefined.
|
|
1925
|
+
|
|
1926
|
+
|
|
1927
|
+
|
|
1928
|
+
|
|
1929
|
+
|
|
1930
|
+
|
|
1931
|
+
|
|
1932
|
+
|
|
1933
|
+
|
|
1934
|
+
|
|
1935
|
+
|
|
1936
|
+
* @example
|
|
1937
|
+
* // Access by index
|
|
1938
|
+
* const list = new DoublyLinkedList<string>(['a', 'b', 'c']);
|
|
1939
|
+
* console.log(list.at(1)); // 'b';
|
|
1940
|
+
* console.log(list.at(2)); // 'c';
|
|
1941
|
+
*/
|
|
1568
1942
|
at(index) {
|
|
1569
1943
|
if (index < 0 || index >= this._length) return void 0;
|
|
1570
1944
|
let current = this.head;
|
|
@@ -1572,11 +1946,23 @@ var _DoublyLinkedList = class _DoublyLinkedList extends LinearLinkedBase {
|
|
|
1572
1946
|
return current == null ? void 0 : current.value;
|
|
1573
1947
|
}
|
|
1574
1948
|
/**
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1949
|
+
* Get the node reference at a given index.
|
|
1950
|
+
* @remarks Time O(N), Space O(1)
|
|
1951
|
+
* @param index - Zero-based index.
|
|
1952
|
+
* @returns Node or undefined.
|
|
1953
|
+
|
|
1954
|
+
|
|
1955
|
+
|
|
1956
|
+
|
|
1957
|
+
|
|
1958
|
+
|
|
1959
|
+
|
|
1960
|
+
|
|
1961
|
+
* @example
|
|
1962
|
+
* // Get node at index
|
|
1963
|
+
* const list = new DoublyLinkedList<string>(['a', 'b', 'c']);
|
|
1964
|
+
* console.log(list.getNodeAt(1)?.value); // 'b';
|
|
1965
|
+
*/
|
|
1580
1966
|
getNodeAt(index) {
|
|
1581
1967
|
if (index < 0 || index >= this._length) return void 0;
|
|
1582
1968
|
let current = this.head;
|
|
@@ -1615,12 +2001,25 @@ var _DoublyLinkedList = class _DoublyLinkedList extends LinearLinkedBase {
|
|
|
1615
2001
|
return void 0;
|
|
1616
2002
|
}
|
|
1617
2003
|
/**
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
2004
|
+
* Insert a new element/node at an index, shifting following nodes.
|
|
2005
|
+
* @remarks Time O(N), Space O(1)
|
|
2006
|
+
* @param index - Zero-based index.
|
|
2007
|
+
* @param newElementOrNode - Element or node to insert.
|
|
2008
|
+
* @returns True if inserted.
|
|
2009
|
+
|
|
2010
|
+
|
|
2011
|
+
|
|
2012
|
+
|
|
2013
|
+
|
|
2014
|
+
|
|
2015
|
+
|
|
2016
|
+
|
|
2017
|
+
* @example
|
|
2018
|
+
* // Insert at position
|
|
2019
|
+
* const list = new DoublyLinkedList<number>([1, 3]);
|
|
2020
|
+
* list.addAt(1, 2);
|
|
2021
|
+
* console.log(list.toArray()); // [1, 2, 3];
|
|
2022
|
+
*/
|
|
1624
2023
|
addAt(index, newElementOrNode) {
|
|
1625
2024
|
if (index < 0 || index > this._length) return false;
|
|
1626
2025
|
if (index === 0) return this.unshift(newElementOrNode);
|
|
@@ -1687,11 +2086,24 @@ var _DoublyLinkedList = class _DoublyLinkedList extends LinearLinkedBase {
|
|
|
1687
2086
|
return true;
|
|
1688
2087
|
}
|
|
1689
2088
|
/**
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
2089
|
+
* Delete the element at an index.
|
|
2090
|
+
* @remarks Time O(N), Space O(1)
|
|
2091
|
+
* @param index - Zero-based index.
|
|
2092
|
+
* @returns Removed element or undefined.
|
|
2093
|
+
|
|
2094
|
+
|
|
2095
|
+
|
|
2096
|
+
|
|
2097
|
+
|
|
2098
|
+
|
|
2099
|
+
|
|
2100
|
+
|
|
2101
|
+
* @example
|
|
2102
|
+
* // Remove by index
|
|
2103
|
+
* const list = new DoublyLinkedList<string>(['a', 'b', 'c']);
|
|
2104
|
+
* list.deleteAt(1);
|
|
2105
|
+
* console.log(list.toArray()); // ['a', 'c'];
|
|
2106
|
+
*/
|
|
1695
2107
|
deleteAt(index) {
|
|
1696
2108
|
if (index < 0 || index >= this._length) return;
|
|
1697
2109
|
if (index === 0) return this.shift();
|
|
@@ -1705,11 +2117,24 @@ var _DoublyLinkedList = class _DoublyLinkedList extends LinearLinkedBase {
|
|
|
1705
2117
|
return removedNode.value;
|
|
1706
2118
|
}
|
|
1707
2119
|
/**
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
2120
|
+
* Delete the first match by value/node.
|
|
2121
|
+
* @remarks Time O(N), Space O(1)
|
|
2122
|
+
* @param [elementOrNode] - Element or node to remove.
|
|
2123
|
+
* @returns True if removed.
|
|
2124
|
+
|
|
2125
|
+
|
|
2126
|
+
|
|
2127
|
+
|
|
2128
|
+
|
|
2129
|
+
|
|
2130
|
+
|
|
2131
|
+
|
|
2132
|
+
* @example
|
|
2133
|
+
* // Remove first occurrence
|
|
2134
|
+
* const list = new DoublyLinkedList<number>([1, 2, 3, 2]);
|
|
2135
|
+
* list.delete(2);
|
|
2136
|
+
* console.log(list.toArray()); // [1, 3, 2];
|
|
2137
|
+
*/
|
|
1713
2138
|
delete(elementOrNode) {
|
|
1714
2139
|
const node = this.getNode(elementOrNode);
|
|
1715
2140
|
if (!node) return false;
|
|
@@ -1725,29 +2150,68 @@ var _DoublyLinkedList = class _DoublyLinkedList extends LinearLinkedBase {
|
|
|
1725
2150
|
return true;
|
|
1726
2151
|
}
|
|
1727
2152
|
/**
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
2153
|
+
* Check whether the list is empty.
|
|
2154
|
+
* @remarks Time O(1), Space O(1)
|
|
2155
|
+
* @returns True if length is 0.
|
|
2156
|
+
|
|
2157
|
+
|
|
2158
|
+
|
|
2159
|
+
|
|
2160
|
+
|
|
2161
|
+
|
|
2162
|
+
|
|
2163
|
+
|
|
2164
|
+
|
|
2165
|
+
* @example
|
|
2166
|
+
* // Check empty
|
|
2167
|
+
* console.log(new DoublyLinkedList().isEmpty()); // true;
|
|
2168
|
+
*/
|
|
1732
2169
|
isEmpty() {
|
|
1733
2170
|
return this._length === 0;
|
|
1734
2171
|
}
|
|
1735
2172
|
/**
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
2173
|
+
* Remove all nodes and reset length.
|
|
2174
|
+
* @remarks Time O(N), Space O(1)
|
|
2175
|
+
* @returns void
|
|
2176
|
+
|
|
2177
|
+
|
|
2178
|
+
|
|
2179
|
+
|
|
2180
|
+
|
|
2181
|
+
|
|
2182
|
+
|
|
2183
|
+
|
|
2184
|
+
|
|
2185
|
+
* @example
|
|
2186
|
+
* // Remove all
|
|
2187
|
+
* const list = new DoublyLinkedList<number>([1, 2]);
|
|
2188
|
+
* list.clear();
|
|
2189
|
+
* console.log(list.isEmpty()); // true;
|
|
2190
|
+
*/
|
|
1740
2191
|
clear() {
|
|
1741
2192
|
this._head = void 0;
|
|
1742
2193
|
this._tail = void 0;
|
|
1743
2194
|
this._length = 0;
|
|
1744
2195
|
}
|
|
1745
2196
|
/**
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
2197
|
+
* Find the first value matching a predicate scanning forward.
|
|
2198
|
+
* @remarks Time O(N), Space O(1)
|
|
2199
|
+
* @param elementNodeOrPredicate - Element, node, or predicate to match.
|
|
2200
|
+
* @returns Matched value or undefined.
|
|
2201
|
+
|
|
2202
|
+
|
|
2203
|
+
|
|
2204
|
+
|
|
2205
|
+
|
|
2206
|
+
|
|
2207
|
+
|
|
2208
|
+
|
|
2209
|
+
* @example
|
|
2210
|
+
* // Search with predicate
|
|
2211
|
+
* const list = new DoublyLinkedList<number>([10, 20, 30]);
|
|
2212
|
+
* const found = list.search(node => node.value > 15);
|
|
2213
|
+
* console.log(found); // 20;
|
|
2214
|
+
*/
|
|
1751
2215
|
search(elementNodeOrPredicate) {
|
|
1752
2216
|
const predicate = this._ensurePredicate(elementNodeOrPredicate);
|
|
1753
2217
|
let current = this.head;
|
|
@@ -1758,11 +2222,25 @@ var _DoublyLinkedList = class _DoublyLinkedList extends LinearLinkedBase {
|
|
|
1758
2222
|
return void 0;
|
|
1759
2223
|
}
|
|
1760
2224
|
/**
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
2225
|
+
* Find the first value matching a predicate scanning backward.
|
|
2226
|
+
* @remarks Time O(N), Space O(1)
|
|
2227
|
+
* @param elementNodeOrPredicate - Element, node, or predicate to match.
|
|
2228
|
+
* @returns Matched value or undefined.
|
|
2229
|
+
|
|
2230
|
+
|
|
2231
|
+
|
|
2232
|
+
|
|
2233
|
+
|
|
2234
|
+
|
|
2235
|
+
|
|
2236
|
+
|
|
2237
|
+
* @example
|
|
2238
|
+
* // Find value scanning from tail
|
|
2239
|
+
* const list = new DoublyLinkedList<number>([1, 2, 3, 4]);
|
|
2240
|
+
* // getBackward scans from tail to head, returns first match
|
|
2241
|
+
* const found = list.getBackward(node => node.value < 4);
|
|
2242
|
+
* console.log(found); // 3;
|
|
2243
|
+
*/
|
|
1766
2244
|
getBackward(elementNodeOrPredicate) {
|
|
1767
2245
|
const predicate = this._ensurePredicate(elementNodeOrPredicate);
|
|
1768
2246
|
let current = this.tail;
|
|
@@ -1773,10 +2251,26 @@ var _DoublyLinkedList = class _DoublyLinkedList extends LinearLinkedBase {
|
|
|
1773
2251
|
return void 0;
|
|
1774
2252
|
}
|
|
1775
2253
|
/**
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
2254
|
+
* Reverse the list in place.
|
|
2255
|
+
* @remarks Time O(N), Space O(1)
|
|
2256
|
+
* @returns This list.
|
|
2257
|
+
|
|
2258
|
+
|
|
2259
|
+
|
|
2260
|
+
|
|
2261
|
+
|
|
2262
|
+
|
|
2263
|
+
|
|
2264
|
+
|
|
2265
|
+
|
|
2266
|
+
|
|
2267
|
+
|
|
2268
|
+
* @example
|
|
2269
|
+
* // Reverse in-place
|
|
2270
|
+
* const list = new DoublyLinkedList<number>([1, 2, 3]);
|
|
2271
|
+
* list.reverse();
|
|
2272
|
+
* console.log([...list]); // [3, 2, 1];
|
|
2273
|
+
*/
|
|
1780
2274
|
reverse() {
|
|
1781
2275
|
let current = this.head;
|
|
1782
2276
|
[this._head, this._tail] = [this.tail, this.head];
|
|
@@ -1798,22 +2292,53 @@ var _DoublyLinkedList = class _DoublyLinkedList extends LinearLinkedBase {
|
|
|
1798
2292
|
return this;
|
|
1799
2293
|
}
|
|
1800
2294
|
/**
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
2295
|
+
* Deep clone this list (values are copied by reference).
|
|
2296
|
+
* @remarks Time O(N), Space O(N)
|
|
2297
|
+
* @returns A new list with the same element sequence.
|
|
2298
|
+
|
|
2299
|
+
|
|
2300
|
+
|
|
2301
|
+
|
|
2302
|
+
|
|
2303
|
+
|
|
2304
|
+
|
|
2305
|
+
|
|
2306
|
+
|
|
2307
|
+
* @example
|
|
2308
|
+
* // Deep copy
|
|
2309
|
+
* const list = new DoublyLinkedList<number>([1, 2, 3]);
|
|
2310
|
+
* const copy = list.clone();
|
|
2311
|
+
* copy.pop();
|
|
2312
|
+
* console.log(list.length); // 3;
|
|
2313
|
+
*/
|
|
1805
2314
|
clone() {
|
|
1806
2315
|
const out = this._createInstance({ toElementFn: this._toElementFn, maxLen: this._maxLen });
|
|
1807
2316
|
for (const v of this) out.push(v);
|
|
1808
2317
|
return out;
|
|
1809
2318
|
}
|
|
1810
2319
|
/**
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
2320
|
+
* Filter values into a new list of the same class.
|
|
2321
|
+
* @remarks Time O(N), Space O(N)
|
|
2322
|
+
* @param callback - Predicate (value, index, list) → boolean to keep value.
|
|
2323
|
+
* @param [thisArg] - Value for `this` inside the callback.
|
|
2324
|
+
* @returns A new list with kept values.
|
|
2325
|
+
|
|
2326
|
+
|
|
2327
|
+
|
|
2328
|
+
|
|
2329
|
+
|
|
2330
|
+
|
|
2331
|
+
|
|
2332
|
+
|
|
2333
|
+
|
|
2334
|
+
|
|
2335
|
+
|
|
2336
|
+
* @example
|
|
2337
|
+
* // Filter elements
|
|
2338
|
+
* const list = new DoublyLinkedList<number>([1, 2, 3, 4, 5]);
|
|
2339
|
+
* const evens = list.filter(n => n % 2 === 0);
|
|
2340
|
+
* console.log([...evens]); // [2, 4];
|
|
2341
|
+
*/
|
|
1817
2342
|
filter(callback, thisArg) {
|
|
1818
2343
|
const out = this._createInstance({ toElementFn: this._toElementFn, maxLen: this._maxLen });
|
|
1819
2344
|
let index = 0;
|
|
@@ -1837,15 +2362,40 @@ var _DoublyLinkedList = class _DoublyLinkedList extends LinearLinkedBase {
|
|
|
1837
2362
|
return out;
|
|
1838
2363
|
}
|
|
1839
2364
|
/**
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
2365
|
+
* Map values into a new list (possibly different element type).
|
|
2366
|
+
* @remarks Time O(N), Space O(N)
|
|
2367
|
+
* @template EM
|
|
2368
|
+
* @template RM
|
|
2369
|
+
* @param callback - Mapping function (value, index, list) → newElement.
|
|
2370
|
+
* @param [options] - Options for the output list (e.g., maxLen, toElementFn).
|
|
2371
|
+
* @param [thisArg] - Value for `this` inside the callback.
|
|
2372
|
+
* @returns A new DoublyLinkedList with mapped values.
|
|
2373
|
+
|
|
2374
|
+
|
|
2375
|
+
|
|
2376
|
+
|
|
2377
|
+
|
|
2378
|
+
|
|
2379
|
+
|
|
2380
|
+
|
|
2381
|
+
|
|
2382
|
+
|
|
2383
|
+
|
|
2384
|
+
* @example
|
|
2385
|
+
* // DoublyLinkedList for...of iteration and map operation
|
|
2386
|
+
* const list = new DoublyLinkedList<number>([1, 2, 3, 4, 5]);
|
|
2387
|
+
*
|
|
2388
|
+
* // Iterate through list
|
|
2389
|
+
* const doubled = list.map(value => value * 2);
|
|
2390
|
+
* console.log(doubled.length); // 5;
|
|
2391
|
+
*
|
|
2392
|
+
* // Use for...of loop
|
|
2393
|
+
* const result: number[] = [];
|
|
2394
|
+
* for (const item of list) {
|
|
2395
|
+
* result.push(item);
|
|
2396
|
+
* }
|
|
2397
|
+
* console.log(result); // [1, 2, 3, 4, 5];
|
|
2398
|
+
*/
|
|
1849
2399
|
map(callback, options, thisArg) {
|
|
1850
2400
|
const out = this._createLike([], { ...options != null ? options : {}, maxLen: this._maxLen });
|
|
1851
2401
|
let index = 0;
|
|
@@ -1936,6 +2486,235 @@ var _DoublyLinkedList = class _DoublyLinkedList extends LinearLinkedBase {
|
|
|
1936
2486
|
__name(_DoublyLinkedList, "DoublyLinkedList");
|
|
1937
2487
|
var DoublyLinkedList = _DoublyLinkedList;
|
|
1938
2488
|
|
|
2489
|
+
// src/common/error.ts
|
|
2490
|
+
var ERR = {
|
|
2491
|
+
// Range / index
|
|
2492
|
+
indexOutOfRange: /* @__PURE__ */ __name((index, min, max, ctx) => `${ctx ? ctx + ": " : ""}Index ${index} is out of range [${min}, ${max}].`, "indexOutOfRange"),
|
|
2493
|
+
invalidIndex: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Index must be an integer.`, "invalidIndex"),
|
|
2494
|
+
// Type / argument
|
|
2495
|
+
invalidArgument: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidArgument"),
|
|
2496
|
+
comparatorRequired: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Comparator is required for non-number/non-string/non-Date keys.`, "comparatorRequired"),
|
|
2497
|
+
invalidKey: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidKey"),
|
|
2498
|
+
notAFunction: /* @__PURE__ */ __name((name, ctx) => `${ctx ? ctx + ": " : ""}${name} must be a function.`, "notAFunction"),
|
|
2499
|
+
invalidEntry: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Each entry must be a [key, value] tuple.`, "invalidEntry"),
|
|
2500
|
+
invalidNaN: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}NaN is not a valid key.`, "invalidNaN"),
|
|
2501
|
+
invalidDate: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Invalid Date key.`, "invalidDate"),
|
|
2502
|
+
reduceEmpty: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Reduce of empty structure with no initial value.`, "reduceEmpty"),
|
|
2503
|
+
callbackReturnType: /* @__PURE__ */ __name((expected, got, ctx) => `${ctx ? ctx + ": " : ""}Callback must return ${expected}; got ${got}.`, "callbackReturnType"),
|
|
2504
|
+
// State / operation
|
|
2505
|
+
invalidOperation: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidOperation"),
|
|
2506
|
+
// Matrix
|
|
2507
|
+
matrixDimensionMismatch: /* @__PURE__ */ __name((op) => `Matrix: Dimensions must be compatible for ${op}.`, "matrixDimensionMismatch"),
|
|
2508
|
+
matrixSingular: /* @__PURE__ */ __name(() => "Matrix: Singular matrix, inverse does not exist.", "matrixSingular"),
|
|
2509
|
+
matrixNotSquare: /* @__PURE__ */ __name(() => "Matrix: Must be square for inversion.", "matrixNotSquare"),
|
|
2510
|
+
matrixNotRectangular: /* @__PURE__ */ __name(() => "Matrix: Must be rectangular for transposition.", "matrixNotRectangular"),
|
|
2511
|
+
matrixRowMismatch: /* @__PURE__ */ __name((expected, got) => `Matrix: Expected row length ${expected}, but got ${got}.`, "matrixRowMismatch")
|
|
2512
|
+
};
|
|
2513
|
+
|
|
2514
|
+
// src/common/index.ts
|
|
2515
|
+
var DFSOperation = /* @__PURE__ */ ((DFSOperation2) => {
|
|
2516
|
+
DFSOperation2[DFSOperation2["VISIT"] = 0] = "VISIT";
|
|
2517
|
+
DFSOperation2[DFSOperation2["PROCESS"] = 1] = "PROCESS";
|
|
2518
|
+
return DFSOperation2;
|
|
2519
|
+
})(DFSOperation || {});
|
|
2520
|
+
var _Range = class _Range {
|
|
2521
|
+
constructor(low, high, includeLow = true, includeHigh = true) {
|
|
2522
|
+
this.low = low;
|
|
2523
|
+
this.high = high;
|
|
2524
|
+
this.includeLow = includeLow;
|
|
2525
|
+
this.includeHigh = includeHigh;
|
|
2526
|
+
}
|
|
2527
|
+
// Determine whether a key is within the range
|
|
2528
|
+
isInRange(key, comparator) {
|
|
2529
|
+
const lowCheck = this.includeLow ? comparator(key, this.low) >= 0 : comparator(key, this.low) > 0;
|
|
2530
|
+
const highCheck = this.includeHigh ? comparator(key, this.high) <= 0 : comparator(key, this.high) < 0;
|
|
2531
|
+
return lowCheck && highCheck;
|
|
2532
|
+
}
|
|
2533
|
+
};
|
|
2534
|
+
__name(_Range, "Range");
|
|
2535
|
+
var Range = _Range;
|
|
2536
|
+
|
|
2537
|
+
// src/data-structures/base/iterable-entry-base.ts
|
|
2538
|
+
var _IterableEntryBase = class _IterableEntryBase {
|
|
2539
|
+
/**
|
|
2540
|
+
* Default iterator yielding `[key, value]` entries.
|
|
2541
|
+
* @returns Iterator of `[K, V]`.
|
|
2542
|
+
* @remarks Time O(n) to iterate, Space O(1)
|
|
2543
|
+
*/
|
|
2544
|
+
*[Symbol.iterator](...args) {
|
|
2545
|
+
yield* this._getIterator(...args);
|
|
2546
|
+
}
|
|
2547
|
+
/**
|
|
2548
|
+
* Iterate over `[key, value]` pairs (may yield `undefined` values).
|
|
2549
|
+
* @returns Iterator of `[K, V | undefined]`.
|
|
2550
|
+
* @remarks Time O(n), Space O(1)
|
|
2551
|
+
*/
|
|
2552
|
+
*entries() {
|
|
2553
|
+
for (const item of this) {
|
|
2554
|
+
yield item;
|
|
2555
|
+
}
|
|
2556
|
+
}
|
|
2557
|
+
/**
|
|
2558
|
+
* Iterate over keys only.
|
|
2559
|
+
* @returns Iterator of keys.
|
|
2560
|
+
* @remarks Time O(n), Space O(1)
|
|
2561
|
+
*/
|
|
2562
|
+
*keys() {
|
|
2563
|
+
for (const item of this) {
|
|
2564
|
+
yield item[0];
|
|
2565
|
+
}
|
|
2566
|
+
}
|
|
2567
|
+
/**
|
|
2568
|
+
* Iterate over values only.
|
|
2569
|
+
* @returns Iterator of values.
|
|
2570
|
+
* @remarks Time O(n), Space O(1)
|
|
2571
|
+
*/
|
|
2572
|
+
*values() {
|
|
2573
|
+
for (const item of this) {
|
|
2574
|
+
yield item[1];
|
|
2575
|
+
}
|
|
2576
|
+
}
|
|
2577
|
+
/**
|
|
2578
|
+
* Test whether all entries satisfy the predicate.
|
|
2579
|
+
* @param predicate - `(key, value, index, self) => boolean`.
|
|
2580
|
+
* @param thisArg - Optional `this` for callback.
|
|
2581
|
+
* @returns `true` if all pass; otherwise `false`.
|
|
2582
|
+
* @remarks Time O(n), Space O(1)
|
|
2583
|
+
*/
|
|
2584
|
+
every(predicate, thisArg) {
|
|
2585
|
+
let index = 0;
|
|
2586
|
+
for (const item of this) {
|
|
2587
|
+
if (!predicate.call(thisArg, item[1], item[0], index++, this)) {
|
|
2588
|
+
return false;
|
|
2589
|
+
}
|
|
2590
|
+
}
|
|
2591
|
+
return true;
|
|
2592
|
+
}
|
|
2593
|
+
/**
|
|
2594
|
+
* Test whether any entry satisfies the predicate.
|
|
2595
|
+
* @param predicate - `(key, value, index, self) => boolean`.
|
|
2596
|
+
* @param thisArg - Optional `this` for callback.
|
|
2597
|
+
* @returns `true` if any passes; otherwise `false`.
|
|
2598
|
+
* @remarks Time O(n), Space O(1)
|
|
2599
|
+
*/
|
|
2600
|
+
some(predicate, thisArg) {
|
|
2601
|
+
let index = 0;
|
|
2602
|
+
for (const item of this) {
|
|
2603
|
+
if (predicate.call(thisArg, item[1], item[0], index++, this)) {
|
|
2604
|
+
return true;
|
|
2605
|
+
}
|
|
2606
|
+
}
|
|
2607
|
+
return false;
|
|
2608
|
+
}
|
|
2609
|
+
/**
|
|
2610
|
+
* Visit each entry, left-to-right.
|
|
2611
|
+
* @param callbackfn - `(key, value, index, self) => void`.
|
|
2612
|
+
* @param thisArg - Optional `this` for callback.
|
|
2613
|
+
* @remarks Time O(n), Space O(1)
|
|
2614
|
+
*/
|
|
2615
|
+
forEach(callbackfn, thisArg) {
|
|
2616
|
+
let index = 0;
|
|
2617
|
+
for (const item of this) {
|
|
2618
|
+
const [key, value] = item;
|
|
2619
|
+
callbackfn.call(thisArg, value, key, index++, this);
|
|
2620
|
+
}
|
|
2621
|
+
}
|
|
2622
|
+
/**
|
|
2623
|
+
* Find the first entry that matches a predicate.
|
|
2624
|
+
* @param callbackfn - `(key, value, index, self) => boolean`.
|
|
2625
|
+
* @param thisArg - Optional `this` for callback.
|
|
2626
|
+
* @returns Matching `[key, value]` or `undefined`.
|
|
2627
|
+
* @remarks Time O(n), Space O(1)
|
|
2628
|
+
*/
|
|
2629
|
+
find(callbackfn, thisArg) {
|
|
2630
|
+
let index = 0;
|
|
2631
|
+
for (const item of this) {
|
|
2632
|
+
const [key, value] = item;
|
|
2633
|
+
if (callbackfn.call(thisArg, value, key, index++, this)) return item;
|
|
2634
|
+
}
|
|
2635
|
+
return;
|
|
2636
|
+
}
|
|
2637
|
+
/**
|
|
2638
|
+
* Whether the given key exists.
|
|
2639
|
+
* @param key - Key to test.
|
|
2640
|
+
* @returns `true` if found; otherwise `false`.
|
|
2641
|
+
* @remarks Time O(n) generic, Space O(1)
|
|
2642
|
+
*/
|
|
2643
|
+
has(key) {
|
|
2644
|
+
for (const item of this) {
|
|
2645
|
+
const [itemKey] = item;
|
|
2646
|
+
if (itemKey === key) return true;
|
|
2647
|
+
}
|
|
2648
|
+
return false;
|
|
2649
|
+
}
|
|
2650
|
+
/**
|
|
2651
|
+
* Whether there exists an entry with the given value.
|
|
2652
|
+
* @param value - Value to test.
|
|
2653
|
+
* @returns `true` if found; otherwise `false`.
|
|
2654
|
+
* @remarks Time O(n), Space O(1)
|
|
2655
|
+
*/
|
|
2656
|
+
hasValue(value) {
|
|
2657
|
+
for (const [, elementValue] of this) {
|
|
2658
|
+
if (elementValue === value) return true;
|
|
2659
|
+
}
|
|
2660
|
+
return false;
|
|
2661
|
+
}
|
|
2662
|
+
/**
|
|
2663
|
+
* Get the value under a key.
|
|
2664
|
+
* @param key - Key to look up.
|
|
2665
|
+
* @returns Value or `undefined`.
|
|
2666
|
+
* @remarks Time O(n) generic, Space O(1)
|
|
2667
|
+
*/
|
|
2668
|
+
get(key) {
|
|
2669
|
+
for (const item of this) {
|
|
2670
|
+
const [itemKey, value] = item;
|
|
2671
|
+
if (itemKey === key) return value;
|
|
2672
|
+
}
|
|
2673
|
+
return;
|
|
2674
|
+
}
|
|
2675
|
+
/**
|
|
2676
|
+
* Reduce entries into a single accumulator.
|
|
2677
|
+
* @param callbackfn - `(acc, value, key, index, self) => acc`.
|
|
2678
|
+
* @param initialValue - Initial accumulator.
|
|
2679
|
+
* @returns Final accumulator.
|
|
2680
|
+
* @remarks Time O(n), Space O(1)
|
|
2681
|
+
*/
|
|
2682
|
+
reduce(callbackfn, initialValue) {
|
|
2683
|
+
let accumulator = initialValue;
|
|
2684
|
+
let index = 0;
|
|
2685
|
+
for (const item of this) {
|
|
2686
|
+
const [key, value] = item;
|
|
2687
|
+
accumulator = callbackfn(accumulator, value, key, index++, this);
|
|
2688
|
+
}
|
|
2689
|
+
return accumulator;
|
|
2690
|
+
}
|
|
2691
|
+
/**
|
|
2692
|
+
* Converts data structure to `[key, value]` pairs.
|
|
2693
|
+
* @returns Array of entries.
|
|
2694
|
+
* @remarks Time O(n), Space O(n)
|
|
2695
|
+
*/
|
|
2696
|
+
toArray() {
|
|
2697
|
+
return [...this];
|
|
2698
|
+
}
|
|
2699
|
+
/**
|
|
2700
|
+
* Visualize the iterable as an array of `[key, value]` pairs (or a custom string).
|
|
2701
|
+
* @returns Array of entries (default) or a string.
|
|
2702
|
+
* @remarks Time O(n), Space O(n)
|
|
2703
|
+
*/
|
|
2704
|
+
toVisual() {
|
|
2705
|
+
return [...this];
|
|
2706
|
+
}
|
|
2707
|
+
/**
|
|
2708
|
+
* Print a human-friendly representation to the console.
|
|
2709
|
+
* @remarks Time O(n), Space O(n)
|
|
2710
|
+
*/
|
|
2711
|
+
print() {
|
|
2712
|
+
console.log(this.toVisual());
|
|
2713
|
+
}
|
|
2714
|
+
};
|
|
2715
|
+
__name(_IterableEntryBase, "IterableEntryBase");
|
|
2716
|
+
var IterableEntryBase = _IterableEntryBase;
|
|
2717
|
+
|
|
1939
2718
|
// src/data-structures/linked-list/skip-linked-list.ts
|
|
1940
2719
|
var _SkipListNode = class _SkipListNode {
|
|
1941
2720
|
constructor(key, value, level) {
|
|
@@ -1944,31 +2723,69 @@ var _SkipListNode = class _SkipListNode {
|
|
|
1944
2723
|
__publicField(this, "forward");
|
|
1945
2724
|
this.key = key;
|
|
1946
2725
|
this.value = value;
|
|
1947
|
-
this.forward = new Array(level);
|
|
2726
|
+
this.forward = new Array(level).fill(void 0);
|
|
1948
2727
|
}
|
|
1949
2728
|
};
|
|
1950
2729
|
__name(_SkipListNode, "SkipListNode");
|
|
1951
2730
|
var SkipListNode = _SkipListNode;
|
|
1952
|
-
var
|
|
1953
|
-
|
|
1954
|
-
|
|
2731
|
+
var _comparator, _isDefaultComparator;
|
|
2732
|
+
var _SkipList = class _SkipList extends IterableEntryBase {
|
|
2733
|
+
constructor(entries = [], options = {}) {
|
|
2734
|
+
super();
|
|
2735
|
+
__privateAdd(this, _comparator);
|
|
2736
|
+
__privateAdd(this, _isDefaultComparator);
|
|
2737
|
+
// ─── Internal state ──────────────────────────────────────────
|
|
2738
|
+
__publicField(this, "_head");
|
|
1955
2739
|
__publicField(this, "_level", 0);
|
|
2740
|
+
__publicField(this, "_size", 0);
|
|
1956
2741
|
__publicField(this, "_maxLevel", 16);
|
|
1957
2742
|
__publicField(this, "_probability", 0.5);
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
2743
|
+
const { comparator, toEntryFn, maxLevel, probability } = options;
|
|
2744
|
+
if (typeof maxLevel === "number" && maxLevel > 0) this._maxLevel = maxLevel;
|
|
2745
|
+
if (typeof probability === "number" && probability > 0 && probability < 1) this._probability = probability;
|
|
2746
|
+
__privateSet(this, _isDefaultComparator, comparator === void 0);
|
|
2747
|
+
__privateSet(this, _comparator, comparator != null ? comparator : _SkipList.createDefaultComparator());
|
|
2748
|
+
this._head = new SkipListNode(void 0, void 0, this._maxLevel);
|
|
2749
|
+
for (const item of entries) {
|
|
2750
|
+
let k;
|
|
2751
|
+
let v;
|
|
2752
|
+
if (toEntryFn) {
|
|
2753
|
+
[k, v] = toEntryFn(item);
|
|
2754
|
+
} else {
|
|
2755
|
+
if (!Array.isArray(item) || item.length < 2) {
|
|
2756
|
+
throw new TypeError(ERR.invalidEntry("SkipList"));
|
|
2757
|
+
}
|
|
2758
|
+
[k, v] = item;
|
|
2759
|
+
}
|
|
2760
|
+
this.set(k, v);
|
|
1965
2761
|
}
|
|
1966
2762
|
}
|
|
1967
|
-
|
|
1968
|
-
|
|
2763
|
+
/**
|
|
2764
|
+
* Creates a default comparator supporting number, string, Date, and bigint.
|
|
2765
|
+
*/
|
|
2766
|
+
static createDefaultComparator() {
|
|
2767
|
+
return (a, b) => {
|
|
2768
|
+
if (typeof a === "number" && typeof b === "number") {
|
|
2769
|
+
if (Number.isNaN(a) || Number.isNaN(b)) throw new TypeError(ERR.invalidNaN("SkipList"));
|
|
2770
|
+
return a - b;
|
|
2771
|
+
}
|
|
2772
|
+
if (typeof a === "string" && typeof b === "string") {
|
|
2773
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
2774
|
+
}
|
|
2775
|
+
if (a instanceof Date && b instanceof Date) {
|
|
2776
|
+
const ta = a.getTime(), tb = b.getTime();
|
|
2777
|
+
if (Number.isNaN(ta) || Number.isNaN(tb)) throw new TypeError(ERR.invalidDate("SkipList"));
|
|
2778
|
+
return ta - tb;
|
|
2779
|
+
}
|
|
2780
|
+
if (typeof a === "bigint" && typeof b === "bigint") {
|
|
2781
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
2782
|
+
}
|
|
2783
|
+
throw new TypeError(ERR.comparatorRequired("SkipList"));
|
|
2784
|
+
};
|
|
1969
2785
|
}
|
|
1970
|
-
|
|
1971
|
-
|
|
2786
|
+
// ─── Size & lifecycle ────────────────────────────────────────
|
|
2787
|
+
get size() {
|
|
2788
|
+
return this._size;
|
|
1972
2789
|
}
|
|
1973
2790
|
get maxLevel() {
|
|
1974
2791
|
return this._maxLevel;
|
|
@@ -1976,133 +2793,594 @@ var _SkipList = class _SkipList {
|
|
|
1976
2793
|
get probability() {
|
|
1977
2794
|
return this._probability;
|
|
1978
2795
|
}
|
|
1979
|
-
get
|
|
1980
|
-
|
|
1981
|
-
|
|
2796
|
+
get comparator() {
|
|
2797
|
+
return __privateGet(this, _comparator);
|
|
2798
|
+
}
|
|
2799
|
+
/**
|
|
2800
|
+
* Check if empty
|
|
2801
|
+
|
|
2802
|
+
|
|
2803
|
+
|
|
2804
|
+
|
|
2805
|
+
|
|
2806
|
+
|
|
2807
|
+
|
|
2808
|
+
|
|
2809
|
+
* @example
|
|
2810
|
+
* // Check if empty
|
|
2811
|
+
* const sl = new SkipList<number, string>();
|
|
2812
|
+
* console.log(sl.isEmpty()); // true;
|
|
2813
|
+
*/
|
|
2814
|
+
isEmpty() {
|
|
2815
|
+
return this._size === 0;
|
|
2816
|
+
}
|
|
2817
|
+
/**
|
|
2818
|
+
* Remove all entries
|
|
2819
|
+
|
|
2820
|
+
|
|
2821
|
+
|
|
2822
|
+
|
|
2823
|
+
|
|
2824
|
+
|
|
2825
|
+
|
|
2826
|
+
|
|
2827
|
+
* @example
|
|
2828
|
+
* // Remove all entries
|
|
2829
|
+
* const sl = new SkipList<number, string>([[1, 'a'], [2, 'b']]);
|
|
2830
|
+
* sl.clear();
|
|
2831
|
+
* console.log(sl.isEmpty()); // true;
|
|
2832
|
+
*/
|
|
2833
|
+
clear() {
|
|
2834
|
+
this._head = new SkipListNode(void 0, void 0, this._maxLevel);
|
|
2835
|
+
this._level = 0;
|
|
2836
|
+
this._size = 0;
|
|
2837
|
+
}
|
|
2838
|
+
/**
|
|
2839
|
+
* Create independent copy
|
|
2840
|
+
|
|
2841
|
+
|
|
2842
|
+
|
|
2843
|
+
|
|
2844
|
+
|
|
2845
|
+
|
|
2846
|
+
|
|
2847
|
+
|
|
2848
|
+
* @example
|
|
2849
|
+
* // Create independent copy
|
|
2850
|
+
* const sl = new SkipList<number, string>([[1, 'a'], [2, 'b']]);
|
|
2851
|
+
* const copy = sl.clone();
|
|
2852
|
+
* copy.delete(1);
|
|
2853
|
+
* console.log(sl.has(1)); // true;
|
|
2854
|
+
*/
|
|
2855
|
+
clone() {
|
|
2856
|
+
return new _SkipList(this, {
|
|
2857
|
+
comparator: __privateGet(this, _isDefaultComparator) ? void 0 : __privateGet(this, _comparator),
|
|
2858
|
+
maxLevel: this._maxLevel,
|
|
2859
|
+
probability: this._probability
|
|
2860
|
+
});
|
|
2861
|
+
}
|
|
2862
|
+
// ─── Core CRUD ───────────────────────────────────────────────
|
|
2863
|
+
/**
|
|
2864
|
+
* Insert or update a key-value pair. Returns `this` for chaining.
|
|
2865
|
+
* Unique keys only — if key exists, value is updated in place.
|
|
2866
|
+
|
|
2867
|
+
|
|
2868
|
+
|
|
2869
|
+
|
|
2870
|
+
|
|
2871
|
+
|
|
2872
|
+
|
|
2873
|
+
|
|
2874
|
+
|
|
2875
|
+
|
|
2876
|
+
|
|
2877
|
+
* @example
|
|
2878
|
+
* // In-memory sorted key-value store
|
|
2879
|
+
* const store = new SkipList<number, string>();
|
|
2880
|
+
*
|
|
2881
|
+
* store.set(3, 'three');
|
|
2882
|
+
* store.set(1, 'one');
|
|
2883
|
+
* store.set(5, 'five');
|
|
2884
|
+
* store.set(2, 'two');
|
|
2885
|
+
*
|
|
2886
|
+
* console.log(store.get(3)); // 'three';
|
|
2887
|
+
* console.log(store.get(1)); // 'one';
|
|
2888
|
+
* console.log(store.get(5)); // 'five';
|
|
2889
|
+
*
|
|
2890
|
+
* // Update existing key
|
|
2891
|
+
* store.set(3, 'THREE');
|
|
2892
|
+
* console.log(store.get(3)); // 'THREE';
|
|
2893
|
+
*/
|
|
2894
|
+
set(key, value) {
|
|
2895
|
+
const cmp = __privateGet(this, _comparator);
|
|
2896
|
+
const update = this._findUpdate(key);
|
|
2897
|
+
const existing = update[0].forward[0];
|
|
2898
|
+
if (existing && cmp(existing.key, key) === 0) {
|
|
2899
|
+
existing.value = value;
|
|
2900
|
+
return this;
|
|
2901
|
+
}
|
|
2902
|
+
const newLevel = this._randomLevel();
|
|
2903
|
+
const newNode = new SkipListNode(key, value, newLevel);
|
|
2904
|
+
if (newLevel > this._level) {
|
|
2905
|
+
for (let i = this._level; i < newLevel; i++) {
|
|
2906
|
+
update[i] = this._head;
|
|
2907
|
+
}
|
|
2908
|
+
this._level = newLevel;
|
|
2909
|
+
}
|
|
2910
|
+
for (let i = 0; i < newLevel; i++) {
|
|
2911
|
+
newNode.forward[i] = update[i].forward[i];
|
|
2912
|
+
update[i].forward[i] = newNode;
|
|
2913
|
+
}
|
|
2914
|
+
this._size++;
|
|
2915
|
+
return this;
|
|
1982
2916
|
}
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
2917
|
+
/**
|
|
2918
|
+
* Get the value for a key, or `undefined` if not found.
|
|
2919
|
+
* Overrides base O(n) with O(log n) skip-list search.
|
|
2920
|
+
|
|
2921
|
+
|
|
2922
|
+
|
|
2923
|
+
|
|
2924
|
+
|
|
2925
|
+
|
|
2926
|
+
|
|
2927
|
+
|
|
2928
|
+
|
|
2929
|
+
|
|
2930
|
+
|
|
2931
|
+
* @example
|
|
2932
|
+
* // Building a sorted index
|
|
2933
|
+
* type Product = { id: number; name: string; price: number };
|
|
2934
|
+
* const products: Product[] = [
|
|
2935
|
+
* { id: 1, name: 'Widget', price: 25 },
|
|
2936
|
+
* { id: 2, name: 'Gadget', price: 50 },
|
|
2937
|
+
* { id: 3, name: 'Doohickey', price: 15 }
|
|
2938
|
+
* ];
|
|
2939
|
+
*
|
|
2940
|
+
* const index = new SkipList<number, Product>(products as any, {
|
|
2941
|
+
* toEntryFn: (p: any) => [p.price, p]
|
|
2942
|
+
* });
|
|
2943
|
+
*
|
|
2944
|
+
* // Iterate in sorted order by price
|
|
2945
|
+
* const names = [...index.values()].map(p => p!.name);
|
|
2946
|
+
* console.log(names); // ['Doohickey', 'Widget', 'Gadget'];
|
|
2947
|
+
*
|
|
2948
|
+
* // Range search: products between $20 and $60
|
|
2949
|
+
* const range = index.rangeSearch([20, 60]);
|
|
2950
|
+
* console.log(range.map(([, p]) => p!.name)); // ['Widget', 'Gadget'];
|
|
2951
|
+
*/
|
|
2952
|
+
get(key) {
|
|
2953
|
+
const node = this._findNode(key);
|
|
2954
|
+
return node ? node.value : void 0;
|
|
2955
|
+
}
|
|
2956
|
+
/**
|
|
2957
|
+
* Check if a key exists.
|
|
2958
|
+
* Overrides base O(n) with O(log n) skip-list search.
|
|
2959
|
+
|
|
2960
|
+
|
|
2961
|
+
|
|
2962
|
+
|
|
2963
|
+
|
|
2964
|
+
|
|
2965
|
+
|
|
2966
|
+
|
|
2967
|
+
|
|
2968
|
+
|
|
2969
|
+
|
|
2970
|
+
* @example
|
|
2971
|
+
* // Check key existence
|
|
2972
|
+
* const sl = new SkipList<number, string>([[1, 'a'], [3, 'c'], [5, 'e']]);
|
|
2973
|
+
* console.log(sl.has(3)); // true;
|
|
2974
|
+
* console.log(sl.has(4)); // false;
|
|
2975
|
+
*/
|
|
2976
|
+
has(key) {
|
|
2977
|
+
return this._findNode(key) !== void 0;
|
|
2978
|
+
}
|
|
2979
|
+
/**
|
|
2980
|
+
* Delete a key. Returns `true` if the key was found and removed.
|
|
2981
|
+
|
|
2982
|
+
|
|
2983
|
+
|
|
2984
|
+
|
|
2985
|
+
|
|
2986
|
+
|
|
2987
|
+
|
|
2988
|
+
|
|
2989
|
+
|
|
2990
|
+
|
|
2991
|
+
|
|
2992
|
+
* @example
|
|
2993
|
+
* // Fast lookup with deletion
|
|
2994
|
+
* const cache = new SkipList<string, number>();
|
|
2995
|
+
*
|
|
2996
|
+
* cache.set('alpha', 1);
|
|
2997
|
+
* cache.set('beta', 2);
|
|
2998
|
+
* cache.set('gamma', 3);
|
|
2999
|
+
*
|
|
3000
|
+
* console.log(cache.has('beta')); // true;
|
|
3001
|
+
* cache.delete('beta');
|
|
3002
|
+
* console.log(cache.has('beta')); // false;
|
|
3003
|
+
* console.log(cache.size); // 2;
|
|
3004
|
+
*/
|
|
3005
|
+
delete(key) {
|
|
3006
|
+
const cmp = __privateGet(this, _comparator);
|
|
3007
|
+
const update = this._findUpdate(key);
|
|
3008
|
+
const target = update[0].forward[0];
|
|
3009
|
+
if (!target || cmp(target.key, key) !== 0) return false;
|
|
3010
|
+
for (let i = 0; i < this._level; i++) {
|
|
3011
|
+
if (update[i].forward[i] !== target) break;
|
|
3012
|
+
update[i].forward[i] = target.forward[i];
|
|
3013
|
+
}
|
|
3014
|
+
while (this._level > 0 && !this._head.forward[this._level - 1]) {
|
|
3015
|
+
this._level--;
|
|
3016
|
+
}
|
|
3017
|
+
this._size--;
|
|
3018
|
+
return true;
|
|
3019
|
+
}
|
|
3020
|
+
// ─── Navigation ──────────────────────────────────────────────
|
|
3021
|
+
/**
|
|
3022
|
+
* Returns the first (smallest key) entry, or `undefined` if empty.
|
|
3023
|
+
|
|
3024
|
+
|
|
3025
|
+
|
|
3026
|
+
|
|
3027
|
+
|
|
3028
|
+
|
|
3029
|
+
|
|
3030
|
+
|
|
3031
|
+
|
|
3032
|
+
|
|
3033
|
+
|
|
3034
|
+
* @example
|
|
3035
|
+
* // Access the minimum entry
|
|
3036
|
+
* const sl = new SkipList<number, string>([[5, 'e'], [1, 'a'], [3, 'c']]);
|
|
3037
|
+
* console.log(sl.first()); // [1, 'a'];
|
|
3038
|
+
*/
|
|
3039
|
+
first() {
|
|
3040
|
+
const node = this._head.forward[0];
|
|
3041
|
+
return node ? [node.key, node.value] : void 0;
|
|
3042
|
+
}
|
|
3043
|
+
/**
|
|
3044
|
+
* Returns the last (largest key) entry, or `undefined` if empty.
|
|
3045
|
+
|
|
3046
|
+
|
|
3047
|
+
|
|
3048
|
+
|
|
3049
|
+
|
|
3050
|
+
|
|
3051
|
+
|
|
3052
|
+
|
|
3053
|
+
|
|
3054
|
+
|
|
3055
|
+
|
|
3056
|
+
* @example
|
|
3057
|
+
* // Access the maximum entry
|
|
3058
|
+
* const sl = new SkipList<number, string>([[5, 'e'], [1, 'a'], [3, 'c']]);
|
|
3059
|
+
* console.log(sl.last()); // [5, 'e'];
|
|
3060
|
+
*/
|
|
3061
|
+
last() {
|
|
3062
|
+
let current = this._head;
|
|
3063
|
+
for (let i = this._level - 1; i >= 0; i--) {
|
|
1986
3064
|
while (current.forward[i]) {
|
|
1987
3065
|
current = current.forward[i];
|
|
1988
3066
|
}
|
|
1989
3067
|
}
|
|
1990
|
-
return current.value;
|
|
1991
|
-
}
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
3068
|
+
return current === this._head ? void 0 : [current.key, current.value];
|
|
3069
|
+
}
|
|
3070
|
+
/**
|
|
3071
|
+
* Remove and return the first (smallest key) entry.
|
|
3072
|
+
|
|
3073
|
+
|
|
3074
|
+
|
|
3075
|
+
|
|
3076
|
+
|
|
3077
|
+
|
|
3078
|
+
|
|
3079
|
+
|
|
3080
|
+
* @example
|
|
3081
|
+
* // Remove and return smallest
|
|
3082
|
+
* const sl = new SkipList<number, string>([[1, 'a'], [2, 'b'], [3, 'c']]);
|
|
3083
|
+
* console.log(sl.pollFirst()); // [1, 'a'];
|
|
3084
|
+
* console.log(sl.size); // 2;
|
|
3085
|
+
*/
|
|
3086
|
+
pollFirst() {
|
|
3087
|
+
const entry = this.first();
|
|
3088
|
+
if (!entry) return void 0;
|
|
3089
|
+
this.delete(entry[0]);
|
|
3090
|
+
return entry;
|
|
3091
|
+
}
|
|
3092
|
+
/**
|
|
3093
|
+
* Remove and return the last (largest key) entry.
|
|
3094
|
+
|
|
3095
|
+
|
|
3096
|
+
|
|
3097
|
+
|
|
3098
|
+
|
|
3099
|
+
|
|
3100
|
+
|
|
3101
|
+
|
|
3102
|
+
* @example
|
|
3103
|
+
* // Remove and return largest
|
|
3104
|
+
* const sl = new SkipList<number, string>([[1, 'a'], [2, 'b'], [3, 'c']]);
|
|
3105
|
+
* console.log(sl.pollLast()); // [3, 'c'];
|
|
3106
|
+
* console.log(sl.size); // 2;
|
|
3107
|
+
*/
|
|
3108
|
+
pollLast() {
|
|
3109
|
+
const entry = this.last();
|
|
3110
|
+
if (!entry) return void 0;
|
|
3111
|
+
this.delete(entry[0]);
|
|
3112
|
+
return entry;
|
|
3113
|
+
}
|
|
3114
|
+
/**
|
|
3115
|
+
* Least entry ≥ key, or `undefined`.
|
|
3116
|
+
|
|
3117
|
+
|
|
3118
|
+
|
|
3119
|
+
|
|
3120
|
+
|
|
3121
|
+
|
|
3122
|
+
|
|
3123
|
+
|
|
3124
|
+
|
|
3125
|
+
|
|
3126
|
+
|
|
3127
|
+
* @example
|
|
3128
|
+
* // Least entry ≥ key
|
|
3129
|
+
* const sl = new SkipList<number, string>([[10, 'a'], [20, 'b'], [30, 'c']]);
|
|
3130
|
+
* console.log(sl.ceiling(15)); // [20, 'b'];
|
|
3131
|
+
* console.log(sl.ceiling(20)); // [20, 'b'];
|
|
3132
|
+
*/
|
|
3133
|
+
ceiling(key) {
|
|
3134
|
+
const cmp = __privateGet(this, _comparator);
|
|
3135
|
+
let current = this._head;
|
|
3136
|
+
for (let i = this._level - 1; i >= 0; i--) {
|
|
3137
|
+
while (current.forward[i] && cmp(current.forward[i].key, key) < 0) {
|
|
1998
3138
|
current = current.forward[i];
|
|
1999
3139
|
}
|
|
2000
|
-
update[i] = current;
|
|
2001
3140
|
}
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
3141
|
+
const node = current.forward[0];
|
|
3142
|
+
return node ? [node.key, node.value] : void 0;
|
|
3143
|
+
}
|
|
3144
|
+
/**
|
|
3145
|
+
* Greatest entry ≤ key, or `undefined`.
|
|
3146
|
+
|
|
3147
|
+
|
|
3148
|
+
|
|
3149
|
+
|
|
3150
|
+
|
|
3151
|
+
|
|
3152
|
+
|
|
3153
|
+
|
|
3154
|
+
|
|
3155
|
+
|
|
3156
|
+
|
|
3157
|
+
* @example
|
|
3158
|
+
* // Greatest entry ≤ key
|
|
3159
|
+
* const sl = new SkipList<number, string>([[10, 'a'], [20, 'b'], [30, 'c']]);
|
|
3160
|
+
* console.log(sl.floor(25)); // [20, 'b'];
|
|
3161
|
+
* console.log(sl.floor(5)); // undefined;
|
|
3162
|
+
*/
|
|
3163
|
+
floor(key) {
|
|
3164
|
+
const cmp = __privateGet(this, _comparator);
|
|
3165
|
+
let current = this._head;
|
|
3166
|
+
for (let i = this._level - 1; i >= 0; i--) {
|
|
3167
|
+
while (current.forward[i] && cmp(current.forward[i].key, key) <= 0) {
|
|
3168
|
+
current = current.forward[i];
|
|
3169
|
+
}
|
|
2008
3170
|
}
|
|
3171
|
+
const result = current === this._head ? void 0 : current;
|
|
3172
|
+
if (result && cmp(result.key, key) <= 0) return [result.key, result.value];
|
|
3173
|
+
return void 0;
|
|
2009
3174
|
}
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
3175
|
+
/**
|
|
3176
|
+
* Least entry strictly > key, or `undefined`.
|
|
3177
|
+
|
|
3178
|
+
|
|
3179
|
+
|
|
3180
|
+
|
|
3181
|
+
|
|
3182
|
+
|
|
3183
|
+
|
|
3184
|
+
|
|
3185
|
+
* @example
|
|
3186
|
+
* // Strictly greater entry
|
|
3187
|
+
* const sl = new SkipList<number, string>([[10, 'a'], [20, 'b'], [30, 'c']]);
|
|
3188
|
+
* console.log(sl.higher(15)); // [20, 'b'];
|
|
3189
|
+
* console.log(sl.higher(30)); // undefined;
|
|
3190
|
+
*/
|
|
3191
|
+
higher(key) {
|
|
3192
|
+
const cmp = __privateGet(this, _comparator);
|
|
3193
|
+
let current = this._head;
|
|
3194
|
+
for (let i = this._level - 1; i >= 0; i--) {
|
|
3195
|
+
while (current.forward[i] && cmp(current.forward[i].key, key) <= 0) {
|
|
2014
3196
|
current = current.forward[i];
|
|
2015
3197
|
}
|
|
2016
3198
|
}
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
3199
|
+
const node = current.forward[0];
|
|
3200
|
+
return node ? [node.key, node.value] : void 0;
|
|
3201
|
+
}
|
|
3202
|
+
/**
|
|
3203
|
+
* Greatest entry strictly < key, or `undefined`.
|
|
3204
|
+
|
|
3205
|
+
|
|
3206
|
+
|
|
3207
|
+
|
|
3208
|
+
|
|
3209
|
+
|
|
3210
|
+
|
|
3211
|
+
|
|
3212
|
+
* @example
|
|
3213
|
+
* // Strictly less entry
|
|
3214
|
+
* const sl = new SkipList<number, string>([[10, 'a'], [20, 'b'], [30, 'c']]);
|
|
3215
|
+
* console.log(sl.lower(25)); // [20, 'b'];
|
|
3216
|
+
* console.log(sl.lower(10)); // undefined;
|
|
3217
|
+
*/
|
|
3218
|
+
lower(key) {
|
|
3219
|
+
const cmp = __privateGet(this, _comparator);
|
|
3220
|
+
let current = this._head;
|
|
3221
|
+
let result;
|
|
3222
|
+
for (let i = this._level - 1; i >= 0; i--) {
|
|
3223
|
+
while (current.forward[i] && cmp(current.forward[i].key, key) < 0) {
|
|
3224
|
+
current = current.forward[i];
|
|
3225
|
+
}
|
|
3226
|
+
if (current !== this._head && cmp(current.key, key) < 0) {
|
|
3227
|
+
result = current;
|
|
3228
|
+
}
|
|
2020
3229
|
}
|
|
2021
|
-
return void 0;
|
|
2022
|
-
}
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
3230
|
+
return result ? [result.key, result.value] : void 0;
|
|
3231
|
+
}
|
|
3232
|
+
/**
|
|
3233
|
+
* Returns entries within the given key range.
|
|
3234
|
+
|
|
3235
|
+
|
|
3236
|
+
|
|
3237
|
+
|
|
3238
|
+
|
|
3239
|
+
|
|
3240
|
+
|
|
3241
|
+
|
|
3242
|
+
|
|
3243
|
+
|
|
3244
|
+
|
|
3245
|
+
* @example
|
|
3246
|
+
* // Find entries in a range
|
|
3247
|
+
* const sl = new SkipList<number, string>([[1, 'a'], [2, 'b'], [3, 'c'], [4, 'd'], [5, 'e']]);
|
|
3248
|
+
* const result = sl.rangeSearch([2, 4]);
|
|
3249
|
+
* console.log(result); // [[2, 'b'], [3, 'c'], [4, 'd']];
|
|
3250
|
+
*/
|
|
3251
|
+
rangeSearch(range, options = {}) {
|
|
3252
|
+
const { lowInclusive = true, highInclusive = true } = options;
|
|
3253
|
+
const [low, high] = range;
|
|
3254
|
+
const cmp = __privateGet(this, _comparator);
|
|
3255
|
+
const out = [];
|
|
3256
|
+
let current = this._head;
|
|
3257
|
+
for (let i = this._level - 1; i >= 0; i--) {
|
|
3258
|
+
while (current.forward[i] && cmp(current.forward[i].key, low) < 0) {
|
|
2031
3259
|
current = current.forward[i];
|
|
2032
3260
|
}
|
|
2033
|
-
update[i] = current;
|
|
2034
3261
|
}
|
|
2035
3262
|
current = current.forward[0];
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
while (this.level > 0 && !this.head.forward[this.level - 1]) {
|
|
2044
|
-
this._level--;
|
|
3263
|
+
while (current) {
|
|
3264
|
+
const cmpHigh = cmp(current.key, high);
|
|
3265
|
+
if (cmpHigh > 0) break;
|
|
3266
|
+
if (cmpHigh === 0 && !highInclusive) break;
|
|
3267
|
+
const cmpLow = cmp(current.key, low);
|
|
3268
|
+
if (cmpLow > 0 || cmpLow === 0 && lowInclusive) {
|
|
3269
|
+
out.push([current.key, current.value]);
|
|
2045
3270
|
}
|
|
2046
|
-
|
|
3271
|
+
current = current.forward[0];
|
|
2047
3272
|
}
|
|
2048
|
-
return
|
|
3273
|
+
return out;
|
|
2049
3274
|
}
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
3275
|
+
// ─── Functional (overrides) ──────────────────────────────────
|
|
3276
|
+
/**
|
|
3277
|
+
* Creates a new SkipList with entries transformed by callback.
|
|
3278
|
+
|
|
3279
|
+
|
|
3280
|
+
|
|
3281
|
+
|
|
3282
|
+
|
|
3283
|
+
|
|
3284
|
+
|
|
3285
|
+
|
|
3286
|
+
* @example
|
|
3287
|
+
* // Transform entries
|
|
3288
|
+
* const sl = new SkipList<number, string>([[1, 'a'], [2, 'b']]);
|
|
3289
|
+
* const mapped = sl.map((v, k) => [k, v?.toUpperCase()] as [number, string]);
|
|
3290
|
+
* console.log([...mapped.values()]); // ['A', 'B'];
|
|
3291
|
+
*/
|
|
3292
|
+
map(callback, options) {
|
|
3293
|
+
const out = new _SkipList([], options != null ? options : {});
|
|
3294
|
+
let i = 0;
|
|
3295
|
+
for (const [k, v] of this) {
|
|
3296
|
+
const [nk, nv] = callback(v, k, i++, this);
|
|
3297
|
+
out.set(nk, nv);
|
|
3298
|
+
}
|
|
3299
|
+
return out;
|
|
3300
|
+
}
|
|
3301
|
+
/**
|
|
3302
|
+
* Creates a new SkipList with entries that pass the predicate.
|
|
3303
|
+
|
|
3304
|
+
|
|
3305
|
+
|
|
3306
|
+
|
|
3307
|
+
|
|
3308
|
+
|
|
3309
|
+
|
|
3310
|
+
|
|
3311
|
+
* @example
|
|
3312
|
+
* // Filter entries
|
|
3313
|
+
* const sl = new SkipList<number, string>([[1, 'a'], [2, 'b'], [3, 'c']]);
|
|
3314
|
+
* const result = sl.filter((v, k) => k > 1);
|
|
3315
|
+
* console.log(result.size); // 2;
|
|
3316
|
+
*/
|
|
3317
|
+
filter(callbackfn, thisArg) {
|
|
3318
|
+
const out = new _SkipList([], {
|
|
3319
|
+
comparator: __privateGet(this, _isDefaultComparator) ? void 0 : __privateGet(this, _comparator),
|
|
3320
|
+
maxLevel: this._maxLevel,
|
|
3321
|
+
probability: this._probability
|
|
3322
|
+
});
|
|
3323
|
+
let i = 0;
|
|
3324
|
+
for (const [k, v] of this) {
|
|
3325
|
+
const ok = callbackfn.call(thisArg, v, k, i++, this);
|
|
3326
|
+
if (ok) out.set(k, v);
|
|
3327
|
+
}
|
|
3328
|
+
return out;
|
|
3329
|
+
}
|
|
3330
|
+
// ─── Iterator (required by IterableEntryBase) ────────────────
|
|
3331
|
+
_getIterator() {
|
|
3332
|
+
const head = this._head;
|
|
3333
|
+
return (function* () {
|
|
3334
|
+
let node = head.forward[0];
|
|
3335
|
+
while (node) {
|
|
3336
|
+
yield [node.key, node.value];
|
|
3337
|
+
node = node.forward[0];
|
|
3338
|
+
}
|
|
3339
|
+
})();
|
|
3340
|
+
}
|
|
3341
|
+
// ─── Internal helpers ────────────────────────────────────────
|
|
3342
|
+
/**
|
|
3343
|
+
* Finds the update array (predecessors at each level) for a given key.
|
|
3344
|
+
*/
|
|
3345
|
+
_findUpdate(key) {
|
|
3346
|
+
const cmp = __privateGet(this, _comparator);
|
|
3347
|
+
const update = new Array(this._maxLevel).fill(this._head);
|
|
3348
|
+
let current = this._head;
|
|
3349
|
+
for (let i = this._level - 1; i >= 0; i--) {
|
|
3350
|
+
while (current.forward[i] && cmp(current.forward[i].key, key) < 0) {
|
|
2054
3351
|
current = current.forward[i];
|
|
2055
3352
|
}
|
|
3353
|
+
update[i] = current;
|
|
2056
3354
|
}
|
|
2057
|
-
|
|
2058
|
-
return nextNode ? nextNode.value : void 0;
|
|
3355
|
+
return update;
|
|
2059
3356
|
}
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
3357
|
+
/**
|
|
3358
|
+
* Finds the node for a given key, or undefined.
|
|
3359
|
+
*/
|
|
3360
|
+
_findNode(key) {
|
|
3361
|
+
const cmp = __privateGet(this, _comparator);
|
|
3362
|
+
let current = this._head;
|
|
3363
|
+
for (let i = this._level - 1; i >= 0; i--) {
|
|
3364
|
+
while (current.forward[i] && cmp(current.forward[i].key, key) < 0) {
|
|
2065
3365
|
current = current.forward[i];
|
|
2066
3366
|
}
|
|
2067
|
-
if (current.key < key) {
|
|
2068
|
-
lastLess = current;
|
|
2069
|
-
}
|
|
2070
3367
|
}
|
|
2071
|
-
|
|
3368
|
+
const candidate = current.forward[0];
|
|
3369
|
+
if (candidate && cmp(candidate.key, key) === 0) return candidate;
|
|
3370
|
+
return void 0;
|
|
2072
3371
|
}
|
|
2073
3372
|
_randomLevel() {
|
|
2074
3373
|
let level = 1;
|
|
2075
|
-
while (Math.random() < this.
|
|
3374
|
+
while (Math.random() < this._probability && level < this._maxLevel) {
|
|
2076
3375
|
level++;
|
|
2077
3376
|
}
|
|
2078
3377
|
return level;
|
|
2079
3378
|
}
|
|
2080
3379
|
};
|
|
3380
|
+
_comparator = new WeakMap();
|
|
3381
|
+
_isDefaultComparator = new WeakMap();
|
|
2081
3382
|
__name(_SkipList, "SkipList");
|
|
2082
3383
|
var SkipList = _SkipList;
|
|
2083
|
-
|
|
2084
|
-
// src/common/index.ts
|
|
2085
|
-
var DFSOperation = /* @__PURE__ */ ((DFSOperation2) => {
|
|
2086
|
-
DFSOperation2[DFSOperation2["VISIT"] = 0] = "VISIT";
|
|
2087
|
-
DFSOperation2[DFSOperation2["PROCESS"] = 1] = "PROCESS";
|
|
2088
|
-
return DFSOperation2;
|
|
2089
|
-
})(DFSOperation || {});
|
|
2090
|
-
var _Range = class _Range {
|
|
2091
|
-
constructor(low, high, includeLow = true, includeHigh = true) {
|
|
2092
|
-
this.low = low;
|
|
2093
|
-
this.high = high;
|
|
2094
|
-
this.includeLow = includeLow;
|
|
2095
|
-
this.includeHigh = includeHigh;
|
|
2096
|
-
}
|
|
2097
|
-
// Determine whether a key is within the range
|
|
2098
|
-
isInRange(key, comparator) {
|
|
2099
|
-
const lowCheck = this.includeLow ? comparator(key, this.low) >= 0 : comparator(key, this.low) > 0;
|
|
2100
|
-
const highCheck = this.includeHigh ? comparator(key, this.high) <= 0 : comparator(key, this.high) < 0;
|
|
2101
|
-
return lowCheck && highCheck;
|
|
2102
|
-
}
|
|
2103
|
-
};
|
|
2104
|
-
__name(_Range, "Range");
|
|
2105
|
-
var Range = _Range;
|
|
2106
3384
|
/**
|
|
2107
3385
|
* data-structure-typed
|
|
2108
3386
|
*
|
|
@@ -2114,6 +3392,7 @@ var Range = _Range;
|
|
|
2114
3392
|
exports.DFSOperation = DFSOperation;
|
|
2115
3393
|
exports.DoublyLinkedList = DoublyLinkedList;
|
|
2116
3394
|
exports.DoublyLinkedListNode = DoublyLinkedListNode;
|
|
3395
|
+
exports.ERR = ERR;
|
|
2117
3396
|
exports.Range = Range;
|
|
2118
3397
|
exports.SinglyLinkedList = SinglyLinkedList;
|
|
2119
3398
|
exports.SinglyLinkedListNode = SinglyLinkedListNode;
|