trie-typed 1.53.6 → 1.53.7
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 +90 -0
- package/dist/common/index.d.ts +12 -0
- package/dist/common/index.js +23 -0
- package/dist/data-structures/binary-tree/avl-tree-multi-map.js +7 -10
- package/dist/data-structures/binary-tree/avl-tree.js +2 -2
- package/dist/data-structures/binary-tree/binary-tree.d.ts +54 -19
- package/dist/data-structures/binary-tree/binary-tree.js +100 -66
- package/dist/data-structures/binary-tree/bst.d.ts +100 -36
- package/dist/data-structures/binary-tree/bst.js +185 -66
- package/dist/data-structures/binary-tree/rb-tree.d.ts +4 -0
- package/dist/data-structures/binary-tree/rb-tree.js +6 -2
- package/dist/data-structures/binary-tree/tree-multi-map.js +2 -2
- package/dist/data-structures/heap/heap.d.ts +6 -6
- package/dist/data-structures/heap/heap.js +6 -6
- package/dist/data-structures/linked-list/doubly-linked-list.d.ts +18 -8
- package/dist/data-structures/linked-list/doubly-linked-list.js +24 -10
- package/dist/data-structures/linked-list/singly-linked-list.d.ts +1 -1
- package/dist/data-structures/linked-list/singly-linked-list.js +1 -1
- package/dist/data-structures/trie/trie.d.ts +104 -4
- package/dist/data-structures/trie/trie.js +116 -12
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +1 -1
- package/dist/types/data-structures/binary-tree/bst.d.ts +3 -2
- package/dist/types/data-structures/binary-tree/rb-tree.d.ts +1 -1
- package/dist/types/utils/utils.d.ts +10 -6
- package/dist/utils/utils.js +4 -2
- package/package.json +2 -2
- package/src/common/index.ts +19 -0
- package/src/data-structures/binary-tree/avl-tree-multi-map.ts +7 -9
- package/src/data-structures/binary-tree/avl-tree.ts +3 -2
- package/src/data-structures/binary-tree/binary-tree.ts +108 -64
- package/src/data-structures/binary-tree/bst.ts +190 -69
- package/src/data-structures/binary-tree/rb-tree.ts +6 -2
- package/src/data-structures/binary-tree/tree-multi-map.ts +3 -3
- package/src/data-structures/heap/heap.ts +39 -39
- package/src/data-structures/linked-list/doubly-linked-list.ts +111 -97
- package/src/data-structures/linked-list/singly-linked-list.ts +1 -1
- package/src/data-structures/trie/trie.ts +116 -11
- package/src/index.ts +2 -1
- package/src/types/data-structures/binary-tree/binary-tree.ts +1 -1
- package/src/types/data-structures/binary-tree/bst.ts +3 -2
- package/src/types/data-structures/binary-tree/rb-tree.ts +1 -1
- package/src/types/utils/utils.ts +16 -10
- package/src/utils/utils.ts +4 -2
|
@@ -64,13 +64,13 @@ class DoublyLinkedListNode {
|
|
|
64
64
|
}
|
|
65
65
|
exports.DoublyLinkedListNode = DoublyLinkedListNode;
|
|
66
66
|
/**
|
|
67
|
-
*
|
|
67
|
+
*1. Node Structure: Each node contains three parts: a data field, a pointer (or reference) to the previous node, and a pointer to the next node. This structure allows traversal of the linked list in both directions.
|
|
68
68
|
* 2. Bidirectional Traversal: Unlike singly linked lists, doubly linked lists can be easily traversed forwards or backwards. This makes insertions and deletions in the list more flexible and efficient.
|
|
69
69
|
* 3. No Centralized Index: Unlike arrays, elements in a linked list are not stored contiguously, so there is no centralized index. Accessing elements in a linked list typically requires traversing from the head or tail node.
|
|
70
70
|
* 4. High Efficiency in Insertion and Deletion: Adding or removing elements in a linked list does not require moving other elements, making these operations more efficient than in arrays.
|
|
71
71
|
* @example
|
|
72
72
|
* // text editor operation history
|
|
73
|
-
*
|
|
73
|
+
* const actions = [
|
|
74
74
|
* { type: 'insert', content: 'first line of text' },
|
|
75
75
|
* { type: 'insert', content: 'second line of text' },
|
|
76
76
|
* { type: 'delete', content: 'delete the first line' }
|
|
@@ -82,7 +82,7 @@ exports.DoublyLinkedListNode = DoublyLinkedListNode;
|
|
|
82
82
|
* console.log(editorHistory.last?.type); // 'insert'
|
|
83
83
|
* @example
|
|
84
84
|
* // Browser history
|
|
85
|
-
*
|
|
85
|
+
* const browserHistory = new DoublyLinkedList<string>();
|
|
86
86
|
*
|
|
87
87
|
* browserHistory.push('home page');
|
|
88
88
|
* browserHistory.push('search page');
|
|
@@ -93,7 +93,7 @@ exports.DoublyLinkedListNode = DoublyLinkedListNode;
|
|
|
93
93
|
* console.log(browserHistory.last); // 'search page'
|
|
94
94
|
* @example
|
|
95
95
|
* // Use DoublyLinkedList to implement music player
|
|
96
|
-
*
|
|
96
|
+
* // Define the Song interface
|
|
97
97
|
* interface Song {
|
|
98
98
|
* title: string;
|
|
99
99
|
* artist: string;
|
|
@@ -218,7 +218,7 @@ exports.DoublyLinkedListNode = DoublyLinkedListNode;
|
|
|
218
218
|
* // ]
|
|
219
219
|
* @example
|
|
220
220
|
* // Use DoublyLinkedList to implement LRU cache
|
|
221
|
-
*
|
|
221
|
+
* interface CacheEntry<K, V> {
|
|
222
222
|
* key: K;
|
|
223
223
|
* value: V;
|
|
224
224
|
* }
|
|
@@ -380,7 +380,7 @@ exports.DoublyLinkedListNode = DoublyLinkedListNode;
|
|
|
380
380
|
* console.log(cache.isEmpty); // true
|
|
381
381
|
* @example
|
|
382
382
|
* // finding lyrics by timestamp in Coldplay's "Fix You"
|
|
383
|
-
*
|
|
383
|
+
* // Create a DoublyLinkedList to store song lyrics with timestamps
|
|
384
384
|
* const lyricsList = new DoublyLinkedList<{ time: number; text: string }>();
|
|
385
385
|
*
|
|
386
386
|
* // Detailed lyrics with precise timestamps (in milliseconds)
|
|
@@ -420,7 +420,7 @@ exports.DoublyLinkedListNode = DoublyLinkedListNode;
|
|
|
420
420
|
* console.log(lateTimeLyric?.text); // 'And I will try to fix you'
|
|
421
421
|
* @example
|
|
422
422
|
* // cpu process schedules
|
|
423
|
-
*
|
|
423
|
+
* class Process {
|
|
424
424
|
* constructor(
|
|
425
425
|
* public id: number,
|
|
426
426
|
* public priority: number
|
|
@@ -496,6 +496,16 @@ exports.DoublyLinkedListNode = DoublyLinkedListNode;
|
|
|
496
496
|
* console.log(scheduler.listProcesses()); // []
|
|
497
497
|
*/
|
|
498
498
|
class DoublyLinkedList extends base_1.IterableElementBase {
|
|
499
|
+
/**
|
|
500
|
+
* This TypeScript constructor initializes a DoublyLinkedList with optional elements and options.
|
|
501
|
+
* @param {Iterable<E> | Iterable<R>} elements - The `elements` parameter in the constructor is an
|
|
502
|
+
* iterable collection of elements of type `E` or `R`. It is used to initialize the DoublyLinkedList
|
|
503
|
+
* with the elements provided in the iterable. If no elements are provided, the default value is an
|
|
504
|
+
* empty iterable.
|
|
505
|
+
* @param [options] - The `options` parameter in the constructor is of type
|
|
506
|
+
* `DoublyLinkedListOptions<E, R>`. It is an optional parameter that allows you to pass additional
|
|
507
|
+
* configuration options to customize the behavior of the DoublyLinkedList.
|
|
508
|
+
*/
|
|
499
509
|
constructor(elements = [], options) {
|
|
500
510
|
super(options);
|
|
501
511
|
this._head = undefined;
|
|
@@ -784,7 +794,9 @@ class DoublyLinkedList extends base_1.IterableElementBase {
|
|
|
784
794
|
* node was not found.
|
|
785
795
|
*/
|
|
786
796
|
addBefore(existingElementOrNode, newElementOrNode) {
|
|
787
|
-
const existingNode = this.
|
|
797
|
+
const existingNode = this.isNode(existingElementOrNode)
|
|
798
|
+
? existingElementOrNode
|
|
799
|
+
: this.getNode(existingElementOrNode);
|
|
788
800
|
if (existingNode) {
|
|
789
801
|
const newNode = this._ensureNode(newElementOrNode);
|
|
790
802
|
newNode.prev = existingNode.prev;
|
|
@@ -818,7 +830,9 @@ class DoublyLinkedList extends base_1.IterableElementBase {
|
|
|
818
830
|
* was not found in the linked list.
|
|
819
831
|
*/
|
|
820
832
|
addAfter(existingElementOrNode, newElementOrNode) {
|
|
821
|
-
const existingNode = this.
|
|
833
|
+
const existingNode = this.isNode(existingElementOrNode)
|
|
834
|
+
? existingElementOrNode
|
|
835
|
+
: this.getNode(existingElementOrNode);
|
|
822
836
|
if (existingNode) {
|
|
823
837
|
const newNode = this._ensureNode(newElementOrNode);
|
|
824
838
|
newNode.next = existingNode.next;
|
|
@@ -956,7 +970,7 @@ class DoublyLinkedList extends base_1.IterableElementBase {
|
|
|
956
970
|
* @returns The `get` method returns the value of the first node in the doubly linked list that
|
|
957
971
|
* satisfies the provided predicate function. If no such node is found, it returns `undefined`.
|
|
958
972
|
*/
|
|
959
|
-
|
|
973
|
+
search(elementNodeOrPredicate) {
|
|
960
974
|
const predicate = this._ensurePredicate(elementNodeOrPredicate);
|
|
961
975
|
let current = this.head;
|
|
962
976
|
while (current) {
|
|
@@ -123,7 +123,7 @@ export declare class SinglyLinkedList<E = any, R = any> extends IterableElementB
|
|
|
123
123
|
* @returns The `get` method returns the value of the first node in the singly linked list that
|
|
124
124
|
* satisfies the provided predicate function. If no such node is found, it returns `undefined`.
|
|
125
125
|
*/
|
|
126
|
-
|
|
126
|
+
search(elementNodeOrPredicate: E | SinglyLinkedListNode<E> | ((node: SinglyLinkedListNode<E>) => boolean)): E | undefined;
|
|
127
127
|
/**
|
|
128
128
|
* Time Complexity: O(n)
|
|
129
129
|
* Space Complexity: O(1)
|
|
@@ -200,7 +200,7 @@ class SinglyLinkedList extends base_1.IterableElementBase {
|
|
|
200
200
|
* @returns The `get` method returns the value of the first node in the singly linked list that
|
|
201
201
|
* satisfies the provided predicate function. If no such node is found, it returns `undefined`.
|
|
202
202
|
*/
|
|
203
|
-
|
|
203
|
+
search(elementNodeOrPredicate) {
|
|
204
204
|
const predicate = this._ensurePredicate(elementNodeOrPredicate);
|
|
205
205
|
let current = this.head;
|
|
206
206
|
while (current) {
|
|
@@ -65,13 +65,100 @@ export declare class TrieNode {
|
|
|
65
65
|
* 9. Spell Check: Checking the spelling of words.
|
|
66
66
|
* 10. IP Routing: Used in certain types of IP routing algorithms.
|
|
67
67
|
* 11. Text Word Frequency Count: Counting and storing the frequency of words in a large amount of text data.
|
|
68
|
+
* @example
|
|
69
|
+
* // Autocomplete: Prefix validation and checking
|
|
70
|
+
* const autocomplete = new Trie<string>(['gmail.com', 'gmail.co.nz', 'gmail.co.jp', 'yahoo.com', 'outlook.com']);
|
|
71
|
+
*
|
|
72
|
+
* // Get all completions for a prefix
|
|
73
|
+
* const gmailCompletions = autocomplete.getWords('gmail');
|
|
74
|
+
* console.log(gmailCompletions); // ['gmail.com', 'gmail.co.nz', 'gmail.co.jp']
|
|
75
|
+
* @example
|
|
76
|
+
* // File System Path Operations
|
|
77
|
+
* const fileSystem = new Trie<string>([
|
|
78
|
+
* '/home/user/documents/file1.txt',
|
|
79
|
+
* '/home/user/documents/file2.txt',
|
|
80
|
+
* '/home/user/pictures/photo.jpg',
|
|
81
|
+
* '/home/user/pictures/vacation/',
|
|
82
|
+
* '/home/user/downloads'
|
|
83
|
+
* ]);
|
|
84
|
+
*
|
|
85
|
+
* // Find common directory prefix
|
|
86
|
+
* console.log(fileSystem.getLongestCommonPrefix()); // '/home/user/'
|
|
87
|
+
*
|
|
88
|
+
* // List all files in a directory
|
|
89
|
+
* const documentsFiles = fileSystem.getWords('/home/user/documents/');
|
|
90
|
+
* console.log(documentsFiles); // ['/home/user/documents/file1.txt', '/home/user/documents/file2.txt']
|
|
91
|
+
* @example
|
|
92
|
+
* // Autocomplete: Basic word suggestions
|
|
93
|
+
* // Create a trie for autocomplete
|
|
94
|
+
* const autocomplete = new Trie<string>([
|
|
95
|
+
* 'function',
|
|
96
|
+
* 'functional',
|
|
97
|
+
* 'functions',
|
|
98
|
+
* 'class',
|
|
99
|
+
* 'classes',
|
|
100
|
+
* 'classical',
|
|
101
|
+
* 'closure',
|
|
102
|
+
* 'const',
|
|
103
|
+
* 'constructor'
|
|
104
|
+
* ]);
|
|
105
|
+
*
|
|
106
|
+
* // Test autocomplete with different prefixes
|
|
107
|
+
* console.log(autocomplete.getWords('fun')); // ['functional', 'functions', 'function']
|
|
108
|
+
* console.log(autocomplete.getWords('cla')); // ['classes', 'classical', 'class']
|
|
109
|
+
* console.log(autocomplete.getWords('con')); // ['constructor', 'const']
|
|
110
|
+
*
|
|
111
|
+
* // Test with non-matching prefix
|
|
112
|
+
* console.log(autocomplete.getWords('xyz')); // []
|
|
113
|
+
* @example
|
|
114
|
+
* // Dictionary: Case-insensitive word lookup
|
|
115
|
+
* // Create a case-insensitive dictionary
|
|
116
|
+
* const dictionary = new Trie<string>([], { caseSensitive: false });
|
|
117
|
+
*
|
|
118
|
+
* // Add words with mixed casing
|
|
119
|
+
* dictionary.add('Hello');
|
|
120
|
+
* dictionary.add('WORLD');
|
|
121
|
+
* dictionary.add('JavaScript');
|
|
122
|
+
*
|
|
123
|
+
* // Test lookups with different casings
|
|
124
|
+
* console.log(dictionary.has('hello')); // true
|
|
125
|
+
* console.log(dictionary.has('HELLO')); // true
|
|
126
|
+
* console.log(dictionary.has('Hello')); // true
|
|
127
|
+
* console.log(dictionary.has('javascript')); // true
|
|
128
|
+
* console.log(dictionary.has('JAVASCRIPT')); // true
|
|
129
|
+
* @example
|
|
130
|
+
* // IP Address Routing Table
|
|
131
|
+
* // Add IP address prefixes and their corresponding routes
|
|
132
|
+
* const routes = {
|
|
133
|
+
* '192.168.1': 'LAN_SUBNET_1',
|
|
134
|
+
* '192.168.2': 'LAN_SUBNET_2',
|
|
135
|
+
* '10.0.0': 'PRIVATE_NETWORK_1',
|
|
136
|
+
* '10.0.1': 'PRIVATE_NETWORK_2'
|
|
137
|
+
* };
|
|
138
|
+
*
|
|
139
|
+
* const ipRoutingTable = new Trie<string>(Object.keys(routes));
|
|
140
|
+
*
|
|
141
|
+
* // Check IP address prefix matching
|
|
142
|
+
* console.log(ipRoutingTable.hasPrefix('192.168.1')); // true
|
|
143
|
+
* console.log(ipRoutingTable.hasPrefix('192.168.2')); // true
|
|
144
|
+
*
|
|
145
|
+
* // Validate IP address belongs to subnet
|
|
146
|
+
* const ip = '192.168.1.100';
|
|
147
|
+
* const subnet = ip.split('.').slice(0, 3).join('.');
|
|
148
|
+
* console.log(ipRoutingTable.hasPrefix(subnet)); // true
|
|
68
149
|
*/
|
|
69
150
|
export declare class Trie<R = any> extends IterableElementBase<string, R, Trie<R>> {
|
|
70
151
|
/**
|
|
71
|
-
* The constructor
|
|
72
|
-
*
|
|
73
|
-
* @param
|
|
74
|
-
*
|
|
152
|
+
* The constructor initializes a Trie data structure with optional options and words provided as
|
|
153
|
+
* input.
|
|
154
|
+
* @param {Iterable<string> | Iterable<R>} words - The `words` parameter in the constructor is an
|
|
155
|
+
* iterable containing either strings or elements of type `R`. It is used to initialize the Trie with
|
|
156
|
+
* a list of words or elements. If no `words` are provided, an empty iterable is used as the default
|
|
157
|
+
* value.
|
|
158
|
+
* @param [options] - The `options` parameter in the constructor is an optional object that can
|
|
159
|
+
* contain configuration options for the Trie data structure. One of the options it can have is
|
|
160
|
+
* `caseSensitive`, which is a boolean value indicating whether the Trie should be case-sensitive or
|
|
161
|
+
* not. If `caseSensitive` is set to `
|
|
75
162
|
*/
|
|
76
163
|
constructor(words?: Iterable<string> | Iterable<R>, options?: TrieOptions<R>);
|
|
77
164
|
protected _size: number;
|
|
@@ -101,6 +188,19 @@ export declare class Trie<R = any> extends IterableElementBase<string, R, Trie<R
|
|
|
101
188
|
* @returns {boolean} True if the word was successfully added.
|
|
102
189
|
*/
|
|
103
190
|
add(word: string): boolean;
|
|
191
|
+
/**
|
|
192
|
+
* Time Complexity: O(n * l)
|
|
193
|
+
* Space Complexity: O(1)
|
|
194
|
+
*
|
|
195
|
+
* The `addMany` function in TypeScript takes an iterable of strings or elements of type R, converts
|
|
196
|
+
* them using a provided function if available, and adds them to a data structure while returning an
|
|
197
|
+
* array of boolean values indicating success.
|
|
198
|
+
* @param {Iterable<string> | Iterable<R>} words - The `words` parameter in the `addMany` function is
|
|
199
|
+
* an iterable that contains either strings or elements of type `R`.
|
|
200
|
+
* @returns The `addMany` method returns an array of boolean values indicating whether each word in
|
|
201
|
+
* the input iterable was successfully added to the data structure.
|
|
202
|
+
*/
|
|
203
|
+
addMany(words?: Iterable<string> | Iterable<R>): boolean[];
|
|
104
204
|
/**
|
|
105
205
|
* Time Complexity: O(l), where l is the length of the input word.
|
|
106
206
|
* Space Complexity: O(1) - Constant space.
|
|
@@ -74,13 +74,100 @@ exports.TrieNode = TrieNode;
|
|
|
74
74
|
* 9. Spell Check: Checking the spelling of words.
|
|
75
75
|
* 10. IP Routing: Used in certain types of IP routing algorithms.
|
|
76
76
|
* 11. Text Word Frequency Count: Counting and storing the frequency of words in a large amount of text data.
|
|
77
|
+
* @example
|
|
78
|
+
* // Autocomplete: Prefix validation and checking
|
|
79
|
+
* const autocomplete = new Trie<string>(['gmail.com', 'gmail.co.nz', 'gmail.co.jp', 'yahoo.com', 'outlook.com']);
|
|
80
|
+
*
|
|
81
|
+
* // Get all completions for a prefix
|
|
82
|
+
* const gmailCompletions = autocomplete.getWords('gmail');
|
|
83
|
+
* console.log(gmailCompletions); // ['gmail.com', 'gmail.co.nz', 'gmail.co.jp']
|
|
84
|
+
* @example
|
|
85
|
+
* // File System Path Operations
|
|
86
|
+
* const fileSystem = new Trie<string>([
|
|
87
|
+
* '/home/user/documents/file1.txt',
|
|
88
|
+
* '/home/user/documents/file2.txt',
|
|
89
|
+
* '/home/user/pictures/photo.jpg',
|
|
90
|
+
* '/home/user/pictures/vacation/',
|
|
91
|
+
* '/home/user/downloads'
|
|
92
|
+
* ]);
|
|
93
|
+
*
|
|
94
|
+
* // Find common directory prefix
|
|
95
|
+
* console.log(fileSystem.getLongestCommonPrefix()); // '/home/user/'
|
|
96
|
+
*
|
|
97
|
+
* // List all files in a directory
|
|
98
|
+
* const documentsFiles = fileSystem.getWords('/home/user/documents/');
|
|
99
|
+
* console.log(documentsFiles); // ['/home/user/documents/file1.txt', '/home/user/documents/file2.txt']
|
|
100
|
+
* @example
|
|
101
|
+
* // Autocomplete: Basic word suggestions
|
|
102
|
+
* // Create a trie for autocomplete
|
|
103
|
+
* const autocomplete = new Trie<string>([
|
|
104
|
+
* 'function',
|
|
105
|
+
* 'functional',
|
|
106
|
+
* 'functions',
|
|
107
|
+
* 'class',
|
|
108
|
+
* 'classes',
|
|
109
|
+
* 'classical',
|
|
110
|
+
* 'closure',
|
|
111
|
+
* 'const',
|
|
112
|
+
* 'constructor'
|
|
113
|
+
* ]);
|
|
114
|
+
*
|
|
115
|
+
* // Test autocomplete with different prefixes
|
|
116
|
+
* console.log(autocomplete.getWords('fun')); // ['functional', 'functions', 'function']
|
|
117
|
+
* console.log(autocomplete.getWords('cla')); // ['classes', 'classical', 'class']
|
|
118
|
+
* console.log(autocomplete.getWords('con')); // ['constructor', 'const']
|
|
119
|
+
*
|
|
120
|
+
* // Test with non-matching prefix
|
|
121
|
+
* console.log(autocomplete.getWords('xyz')); // []
|
|
122
|
+
* @example
|
|
123
|
+
* // Dictionary: Case-insensitive word lookup
|
|
124
|
+
* // Create a case-insensitive dictionary
|
|
125
|
+
* const dictionary = new Trie<string>([], { caseSensitive: false });
|
|
126
|
+
*
|
|
127
|
+
* // Add words with mixed casing
|
|
128
|
+
* dictionary.add('Hello');
|
|
129
|
+
* dictionary.add('WORLD');
|
|
130
|
+
* dictionary.add('JavaScript');
|
|
131
|
+
*
|
|
132
|
+
* // Test lookups with different casings
|
|
133
|
+
* console.log(dictionary.has('hello')); // true
|
|
134
|
+
* console.log(dictionary.has('HELLO')); // true
|
|
135
|
+
* console.log(dictionary.has('Hello')); // true
|
|
136
|
+
* console.log(dictionary.has('javascript')); // true
|
|
137
|
+
* console.log(dictionary.has('JAVASCRIPT')); // true
|
|
138
|
+
* @example
|
|
139
|
+
* // IP Address Routing Table
|
|
140
|
+
* // Add IP address prefixes and their corresponding routes
|
|
141
|
+
* const routes = {
|
|
142
|
+
* '192.168.1': 'LAN_SUBNET_1',
|
|
143
|
+
* '192.168.2': 'LAN_SUBNET_2',
|
|
144
|
+
* '10.0.0': 'PRIVATE_NETWORK_1',
|
|
145
|
+
* '10.0.1': 'PRIVATE_NETWORK_2'
|
|
146
|
+
* };
|
|
147
|
+
*
|
|
148
|
+
* const ipRoutingTable = new Trie<string>(Object.keys(routes));
|
|
149
|
+
*
|
|
150
|
+
* // Check IP address prefix matching
|
|
151
|
+
* console.log(ipRoutingTable.hasPrefix('192.168.1')); // true
|
|
152
|
+
* console.log(ipRoutingTable.hasPrefix('192.168.2')); // true
|
|
153
|
+
*
|
|
154
|
+
* // Validate IP address belongs to subnet
|
|
155
|
+
* const ip = '192.168.1.100';
|
|
156
|
+
* const subnet = ip.split('.').slice(0, 3).join('.');
|
|
157
|
+
* console.log(ipRoutingTable.hasPrefix(subnet)); // true
|
|
77
158
|
*/
|
|
78
159
|
class Trie extends base_1.IterableElementBase {
|
|
79
160
|
/**
|
|
80
|
-
* The constructor
|
|
81
|
-
*
|
|
82
|
-
* @param
|
|
83
|
-
*
|
|
161
|
+
* The constructor initializes a Trie data structure with optional options and words provided as
|
|
162
|
+
* input.
|
|
163
|
+
* @param {Iterable<string> | Iterable<R>} words - The `words` parameter in the constructor is an
|
|
164
|
+
* iterable containing either strings or elements of type `R`. It is used to initialize the Trie with
|
|
165
|
+
* a list of words or elements. If no `words` are provided, an empty iterable is used as the default
|
|
166
|
+
* value.
|
|
167
|
+
* @param [options] - The `options` parameter in the constructor is an optional object that can
|
|
168
|
+
* contain configuration options for the Trie data structure. One of the options it can have is
|
|
169
|
+
* `caseSensitive`, which is a boolean value indicating whether the Trie should be case-sensitive or
|
|
170
|
+
* not. If `caseSensitive` is set to `
|
|
84
171
|
*/
|
|
85
172
|
constructor(words = [], options) {
|
|
86
173
|
super(options);
|
|
@@ -93,14 +180,7 @@ class Trie extends base_1.IterableElementBase {
|
|
|
93
180
|
this._caseSensitive = caseSensitive;
|
|
94
181
|
}
|
|
95
182
|
if (words) {
|
|
96
|
-
|
|
97
|
-
if (this.toElementFn) {
|
|
98
|
-
this.add(this.toElementFn(word));
|
|
99
|
-
}
|
|
100
|
-
else {
|
|
101
|
-
this.add(word);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
183
|
+
this.addMany(words);
|
|
104
184
|
}
|
|
105
185
|
}
|
|
106
186
|
/**
|
|
@@ -151,6 +231,30 @@ class Trie extends base_1.IterableElementBase {
|
|
|
151
231
|
}
|
|
152
232
|
return isNewWord;
|
|
153
233
|
}
|
|
234
|
+
/**
|
|
235
|
+
* Time Complexity: O(n * l)
|
|
236
|
+
* Space Complexity: O(1)
|
|
237
|
+
*
|
|
238
|
+
* The `addMany` function in TypeScript takes an iterable of strings or elements of type R, converts
|
|
239
|
+
* them using a provided function if available, and adds them to a data structure while returning an
|
|
240
|
+
* array of boolean values indicating success.
|
|
241
|
+
* @param {Iterable<string> | Iterable<R>} words - The `words` parameter in the `addMany` function is
|
|
242
|
+
* an iterable that contains either strings or elements of type `R`.
|
|
243
|
+
* @returns The `addMany` method returns an array of boolean values indicating whether each word in
|
|
244
|
+
* the input iterable was successfully added to the data structure.
|
|
245
|
+
*/
|
|
246
|
+
addMany(words = []) {
|
|
247
|
+
const ans = [];
|
|
248
|
+
for (const word of words) {
|
|
249
|
+
if (this.toElementFn) {
|
|
250
|
+
ans.push(this.add(this.toElementFn(word)));
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
ans.push(this.add(word));
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
return ans;
|
|
257
|
+
}
|
|
154
258
|
/**
|
|
155
259
|
* Time Complexity: O(l), where l is the length of the input word.
|
|
156
260
|
* Space Complexity: O(1) - Constant space.
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -24,4 +24,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
24
24
|
__exportStar(require("./data-structures/trie"), exports);
|
|
25
25
|
__exportStar(require("./types/data-structures/trie"), exports);
|
|
26
26
|
__exportStar(require("./types/common"), exports);
|
|
27
|
-
__exportStar(require("./
|
|
27
|
+
__exportStar(require("./types/utils"), exports);
|
|
28
|
+
__exportStar(require("./common"), exports);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BinaryTree, BinaryTreeNode } from '../../../data-structures';
|
|
2
2
|
import { IterationType, OptValue } from '../../common';
|
|
3
|
-
import { DFSOperation } from '../../../
|
|
3
|
+
import { DFSOperation } from '../../../common';
|
|
4
4
|
export type BinaryTreeNodeNested<K, V> = BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>;
|
|
5
5
|
export type BinaryTreeNested<K, V, R, NODE extends BinaryTreeNode<K, V, NODE>> = BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>;
|
|
6
6
|
export type ToEntryFn<K, V, R> = (rawElement: R) => BTNEntry<K, V>;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { BST, BSTNode } from '../../../data-structures';
|
|
2
2
|
import type { BinaryTreeOptions } from './binary-tree';
|
|
3
|
-
import {
|
|
3
|
+
import { Comparable } from '../../utils';
|
|
4
4
|
export type BSTNodeNested<K, V> = BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>;
|
|
5
5
|
export type BSTNested<K, V, R, NODE extends BSTNode<K, V, NODE>> = BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, BST<K, V, R, NODE, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>;
|
|
6
6
|
export type BSTOptions<K, V, R> = BinaryTreeOptions<K, V, R> & {
|
|
7
|
-
|
|
7
|
+
extractComparable?: (key: K) => Comparable;
|
|
8
|
+
isReverse?: boolean;
|
|
8
9
|
};
|
|
9
10
|
export type BSTNOptKey<K> = K | undefined;
|
|
10
11
|
export type OptNode<NODE> = NODE | undefined;
|
|
@@ -3,4 +3,4 @@ import type { BSTOptions } from "./bst";
|
|
|
3
3
|
export type RBTNColor = 'RED' | 'BLACK';
|
|
4
4
|
export type RedBlackTreeNodeNested<K, V> = RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>;
|
|
5
5
|
export type RedBlackTreeNested<K, V, R, NODE extends RedBlackTreeNode<K, V, NODE>> = RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, RedBlackTree<K, V, R, NODE, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>;
|
|
6
|
-
export type RBTreeOptions<K, V, R> = BSTOptions<K, V, R> & {};
|
|
6
|
+
export type RBTreeOptions<K, V, R> = Omit<BSTOptions<K, V, R>, 'isReverse'> & {};
|
|
@@ -6,13 +6,17 @@ export type TrlFn<A extends any[] = any[], R = any> = (...args: A) => R;
|
|
|
6
6
|
export type TrlAsyncFn = (...args: any[]) => any;
|
|
7
7
|
export type SpecifyOptional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
|
|
8
8
|
export type Any = string | number | bigint | boolean | symbol | undefined | object;
|
|
9
|
+
export type Arithmetic = number | bigint;
|
|
9
10
|
export type ComparablePrimitive = number | bigint | string | boolean;
|
|
10
|
-
export
|
|
11
|
-
[key
|
|
12
|
-
}
|
|
13
|
-
|
|
11
|
+
export interface BaseComparableObject {
|
|
12
|
+
[key: string]: unknown;
|
|
13
|
+
}
|
|
14
|
+
export interface ValueComparableObject extends BaseComparableObject {
|
|
15
|
+
valueOf: () => ComparablePrimitive | ValueComparableObject;
|
|
14
16
|
toString?: () => string;
|
|
15
|
-
}
|
|
17
|
+
}
|
|
18
|
+
export interface StringComparableObject extends BaseComparableObject {
|
|
16
19
|
toString: () => string;
|
|
17
|
-
}
|
|
20
|
+
}
|
|
21
|
+
export type ComparableObject = ValueComparableObject | StringComparableObject;
|
|
18
22
|
export type Comparable = ComparablePrimitive | Date | ComparableObject;
|
package/dist/utils/utils.js
CHANGED
|
@@ -213,7 +213,8 @@ exports.roundFixed = roundFixed;
|
|
|
213
213
|
function isPrimitiveComparable(value) {
|
|
214
214
|
const valueType = typeof value;
|
|
215
215
|
if (valueType === 'number')
|
|
216
|
-
return
|
|
216
|
+
return true;
|
|
217
|
+
// if (valueType === 'number') return !Number.isNaN(value);
|
|
217
218
|
return valueType === 'bigint' || valueType === 'string' || valueType === 'boolean';
|
|
218
219
|
}
|
|
219
220
|
/**
|
|
@@ -265,7 +266,8 @@ function isComparable(value, isForceObjectComparable = false) {
|
|
|
265
266
|
if (typeof value !== 'object')
|
|
266
267
|
return false;
|
|
267
268
|
if (value instanceof Date)
|
|
268
|
-
return
|
|
269
|
+
return true;
|
|
270
|
+
// if (value instanceof Date) return !Number.isNaN(value.getTime());
|
|
269
271
|
if (isForceObjectComparable)
|
|
270
272
|
return true;
|
|
271
273
|
const comparableValue = tryObjectToPrimitive(value);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "trie-typed",
|
|
3
|
-
"version": "1.53.
|
|
3
|
+
"version": "1.53.7",
|
|
4
4
|
"description": "Trie, Prefix tree. Javascript & Typescript Data Structure.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -128,6 +128,6 @@
|
|
|
128
128
|
"typescript": "^4.9.5"
|
|
129
129
|
},
|
|
130
130
|
"dependencies": {
|
|
131
|
-
"data-structure-typed": "^1.53.
|
|
131
|
+
"data-structure-typed": "^1.53.7"
|
|
132
132
|
}
|
|
133
133
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export enum DFSOperation {
|
|
2
|
+
VISIT = 0,
|
|
3
|
+
PROCESS = 1
|
|
4
|
+
}
|
|
5
|
+
export class Range<K> {
|
|
6
|
+
constructor(
|
|
7
|
+
public low: K,
|
|
8
|
+
public high: K,
|
|
9
|
+
public includeLow: boolean = true,
|
|
10
|
+
public includeHigh: boolean = true
|
|
11
|
+
) {}
|
|
12
|
+
|
|
13
|
+
// Determine whether a key is within the range
|
|
14
|
+
isInRange(key: K, comparator: (a: K, b: K) => number): boolean {
|
|
15
|
+
const lowCheck = this.includeLow ? comparator(key, this.low) >= 0 : comparator(key, this.low) > 0;
|
|
16
|
+
const highCheck = this.includeHigh ? comparator(key, this.high) <= 0 : comparator(key, this.high) < 0;
|
|
17
|
+
return lowCheck && highCheck;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -143,8 +143,9 @@ export class AVLTreeMultiMap<
|
|
|
143
143
|
return new AVLTreeMultiMap<K, V, R, NODE, TREE>([], {
|
|
144
144
|
iterationType: this.iterationType,
|
|
145
145
|
isMapMode: this._isMapMode,
|
|
146
|
-
|
|
146
|
+
extractComparable: this._extractComparable,
|
|
147
147
|
toEntryFn: this._toEntryFn,
|
|
148
|
+
isReverse: this._isReverse,
|
|
148
149
|
...options
|
|
149
150
|
}) as TREE;
|
|
150
151
|
}
|
|
@@ -187,17 +188,14 @@ export class AVLTreeMultiMap<
|
|
|
187
188
|
return [this.createNode(key, finalValue, count), finalValue];
|
|
188
189
|
}
|
|
189
190
|
|
|
190
|
-
if (this.isKey(keyNodeEntryOrRaw)) return [this.createNode(keyNodeEntryOrRaw, value, count), value];
|
|
191
|
-
|
|
192
191
|
if (this.isRaw(keyNodeEntryOrRaw)) {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
if (this.isKey(key)) return [this.createNode(key, finalValue, count), finalValue];
|
|
197
|
-
}
|
|
198
|
-
return [undefined, undefined];
|
|
192
|
+
const [key, entryValue] = this._toEntryFn!(keyNodeEntryOrRaw);
|
|
193
|
+
const finalValue = value ?? entryValue;
|
|
194
|
+
if (this.isKey(key)) return [this.createNode(key, finalValue, count), finalValue];
|
|
199
195
|
}
|
|
200
196
|
|
|
197
|
+
if (this.isKey(keyNodeEntryOrRaw)) return [this.createNode(keyNodeEntryOrRaw, value, count), value];
|
|
198
|
+
|
|
201
199
|
return [undefined, undefined];
|
|
202
200
|
}
|
|
203
201
|
|
|
@@ -113,8 +113,9 @@ export class AVLTree<
|
|
|
113
113
|
return new AVLTree<K, V, R, NODE, TREE>([], {
|
|
114
114
|
iterationType: this.iterationType,
|
|
115
115
|
isMapMode: this._isMapMode,
|
|
116
|
-
|
|
116
|
+
extractComparable: this._extractComparable,
|
|
117
117
|
toEntryFn: this._toEntryFn,
|
|
118
|
+
isReverse: this._isReverse,
|
|
118
119
|
...options
|
|
119
120
|
}) as TREE;
|
|
120
121
|
}
|
|
@@ -434,7 +435,7 @@ export class AVLTree<
|
|
|
434
435
|
*/
|
|
435
436
|
protected _balancePath(node: BTNRep<K, V, NODE> | R): void {
|
|
436
437
|
node = this.ensureNode(node);
|
|
437
|
-
const path = this.getPathToRoot(node => node,
|
|
438
|
+
const path = this.getPathToRoot(node, node => node, false); // first O(log n) + O(log n)
|
|
438
439
|
for (let i = 0; i < path.length; i++) {
|
|
439
440
|
// second O(log n)
|
|
440
441
|
const A = path[i];
|