typescript-ds-lib 0.2.7 → 0.2.9

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/lib/deque.ts DELETED
@@ -1,86 +0,0 @@
1
- import { LinkedList } from './linked-list';
2
-
3
-
4
- export interface Deque<T> {
5
- pushFront(element: T): void;
6
- pushBack(element: T): void;
7
- popFront(): T | undefined;
8
- popBack(): T | undefined;
9
- front(): T | undefined;
10
- back(): T | undefined;
11
- isEmpty(): boolean;
12
- size(): number;
13
- clear(): void;
14
- }
15
-
16
-
17
- export class Deque<T> implements Deque<T> {
18
- private items: LinkedList<T>;
19
-
20
- constructor() {
21
- this.items = new LinkedList<T>();
22
- }
23
-
24
- /**
25
- * Adds an element to the front of the deque
26
- */
27
- pushFront(element: T): void {
28
- this.items.pushFront(element);
29
- }
30
-
31
- /**
32
- * Adds an element to the back of the deque
33
- */
34
- pushBack(element: T): void {
35
- this.items.pushBack(element);
36
- }
37
-
38
- /**
39
- * Removes and returns the front element from the deque, or undefined if deque is empty
40
- */
41
- popFront(): T | undefined {
42
- return this.items.popFront();
43
- }
44
-
45
- /**
46
- * Removes and returns the back element from the deque, or undefined if deque is empty
47
- */
48
- popBack(): T | undefined {
49
- return this.items.popBack();
50
- }
51
-
52
- /**
53
- * Returns the front element without removing it, or undefined if deque is empty
54
- */
55
- front(): T | undefined {
56
- return this.items.get(0);
57
- }
58
-
59
- /**
60
- * Returns the back element without removing it, or undefined if deque is empty
61
- */
62
- back(): T | undefined {
63
- return this.items.get(this.items.size() - 1);
64
- }
65
-
66
- /**
67
- * Returns true if the deque is empty, false otherwise
68
- */
69
- isEmpty(): boolean {
70
- return this.items.isEmpty();
71
- }
72
-
73
- /**
74
- * Returns the number of elements in the deque
75
- */
76
- size(): number {
77
- return this.items.size();
78
- }
79
-
80
- /**
81
- * Removes all elements from the deque
82
- */
83
- clear(): void {
84
- this.items.clear();
85
- }
86
- }
package/lib/hash-table.ts DELETED
@@ -1,179 +0,0 @@
1
- export interface HashTable<K, V> {
2
- insert(key: K, value: V): void;
3
- get(key: K): V | undefined;
4
- remove(key: K): boolean;
5
- size(): number;
6
- isEmpty(): boolean;
7
- clear(): void;
8
- }
9
-
10
-
11
- class HashNode<K, V> {
12
- key: K;
13
- value: V;
14
- next: HashNode<K, V> | null;
15
-
16
- constructor(key: K, value: V) {
17
- this.key = key;
18
- this.value = value;
19
- this.next = null;
20
- }
21
- }
22
-
23
- export class HashTable<K, V> implements HashTable<K, V> {
24
- private table: Array<HashNode<K, V> | null>;
25
- private count: number;
26
- private readonly capacity: number;
27
-
28
- constructor(capacity: number = 32) {
29
- this.table = new Array(capacity).fill(null);
30
- this.count = 0;
31
- this.capacity = capacity;
32
- }
33
-
34
- private hash(key: K): number {
35
- if (typeof (key as any).hashCode === 'function') {
36
- return (key as any).hashCode();
37
- }
38
-
39
- let stringKey: string;
40
- switch (typeof key) {
41
- case 'number':
42
- // If the number is a safe integer, use Knuth's multiplicative method.
43
- if (Number.isSafeInteger(key)) {
44
- const knuthConstant = 2654435761;
45
- return (Math.abs(key * knuthConstant) >>> 0) % this.capacity;
46
- }
47
- stringKey = key.toString();
48
- break;
49
- case 'object':
50
- if (key === null) {
51
- stringKey = 'null';
52
- } else if (typeof (key as any).toString === 'function') {
53
- stringKey = (key as any).toString();
54
- } else {
55
- stringKey = JSON.stringify(key);
56
- }
57
- break;
58
- case 'string':
59
- stringKey = key;
60
- break;
61
- case 'function':
62
- stringKey = key.toString();
63
- break;
64
- case 'symbol':
65
- stringKey = key.toString();
66
- break;
67
- case 'undefined':
68
- stringKey = 'null';
69
- break;
70
- default:
71
- stringKey = String(key);
72
- }
73
- let hash = 0;
74
- // DJB2 hash algorithm
75
- for (let i = 0; i < stringKey.length; i++) {
76
- hash = ((hash << 5) + hash) + stringKey.charCodeAt(i);
77
- hash = hash >>> 0; // Convert to 32-bit unsigned integer
78
- }
79
- return hash % this.capacity;
80
- }
81
-
82
- insert(key: K, value: V): void {
83
- const index = this.hash(key);
84
- const newNode = new HashNode(key, value);
85
- if (!this.table[index]) {
86
- this.table[index] = newNode;
87
- this.count++;
88
- return;
89
- }
90
- let current = this.table[index];
91
- while (current) {
92
- if (this.keysEqual(current.key, key)) {
93
- current.value = value;
94
- return;
95
- }
96
- if (!current.next) {
97
- current.next = newNode;
98
- this.count++;
99
- return;
100
- }
101
- current = current.next;
102
- }
103
- }
104
-
105
- get(key: K): V | undefined {
106
- const index = this.hash(key);
107
- let current = this.table[index];
108
- while (current) {
109
- if (this.keysEqual(current.key, key)) {
110
- return current.value;
111
- }
112
- current = current.next;
113
- }
114
- return undefined;
115
- }
116
-
117
- remove(key: K): boolean {
118
- const index = this.hash(key);
119
- let current = this.table[index];
120
- let prev: HashNode<K, V> | null = null;
121
- while (current) {
122
- if (this.keysEqual(current.key, key)) {
123
- if (prev) {
124
- prev.next = current.next;
125
- } else {
126
- this.table[index] = current.next;
127
- }
128
- this.count--;
129
- return true;
130
- }
131
- prev = current;
132
- current = current.next;
133
- }
134
- return false;
135
- }
136
-
137
- private keysEqual(key1: K, key2: K): boolean {
138
- // Check if keys have equals method and use it for comparison
139
- if (typeof (key1 as any).equals === 'function') {
140
- return (key1 as any).equals(key2);
141
- }
142
- if (key1 === key2) return true;
143
- if (key1 == null || key2 == null) return false;
144
-
145
- if (typeof key1 !== 'object' && typeof key2 !== 'object') {
146
- return key1 === key2;
147
- }
148
- if (key1 instanceof Date && key2 instanceof Date) {
149
- return key1.getTime() === key2.getTime();
150
- }
151
- if (key1 instanceof RegExp && key2 instanceof RegExp) {
152
- return key1.toString() === key2.toString();
153
- }
154
- if (Array.isArray(key1) && Array.isArray(key2)) {
155
- return key1.length === key2.length &&
156
- key1.every((val, idx) => this.keysEqual(val, key2[idx]));
157
- }
158
- if (typeof key1 === 'object' && typeof key2 === 'object') {
159
- const keys1 = Object.keys(key1);
160
- const keys2 = Object.keys(key2);
161
- return keys1.length === keys2.length &&
162
- keys1.every(k => k in key2 && this.keysEqual((key1 as any)[k], (key2 as any)[k]));
163
- }
164
- return false;
165
- }
166
-
167
- size(): number {
168
- return this.count;
169
- }
170
-
171
- isEmpty(): boolean {
172
- return this.count === 0;
173
- }
174
-
175
- clear(): void {
176
- this.table = new Array(this.capacity).fill(null);
177
- this.count = 0;
178
- }
179
- }
@@ -1,314 +0,0 @@
1
- export interface LinkedList<T> {
2
- pushBack(element: T): void;
3
- pushFront(element: T): void;
4
- popBack(): T | undefined;
5
- popFront(): T | undefined;
6
- front(): T | undefined;
7
- back(): T | undefined;
8
- insert(element: T, position: number): boolean;
9
- insertBefore(element: T, condition: (element: T) => boolean): boolean;
10
- insertAfter(element: T, condition: (element: T) => boolean): boolean;
11
- removeIf(condition: (element: T) => boolean): boolean;
12
- removeAt(position: number): T | undefined;
13
- forEach(callback: (element: T) => void): void;
14
- get(position: number): T | undefined;
15
- isEmpty(): boolean;
16
- size(): number;
17
- clear(): void;
18
- }
19
-
20
-
21
- class Node<T> {
22
- value: T;
23
- next: Node<T> | null;
24
-
25
- constructor(value: T) {
26
- this.value = value;
27
- this.next = null;
28
- }
29
- }
30
-
31
-
32
- export class LinkedList<T> implements LinkedList<T> {
33
- private head: Node<T> | null;
34
- private tail: Node<T> | null;
35
- private length: number;
36
-
37
- constructor() {
38
- this.head = null;
39
- this.tail = null;
40
- this.length = 0;
41
- }
42
-
43
- /**
44
- * Returns the first element in the list without removing it, or undefined if list is empty
45
- */
46
- front(): T | undefined {
47
- return this.head?.value;
48
- }
49
-
50
- /**
51
- * Returns the last element in the list without removing it, or undefined if list is empty
52
- */
53
- back(): T | undefined {
54
- return this.tail?.value;
55
- }
56
-
57
- /**
58
- * Adds an element to the end of the list
59
- */
60
- pushBack(element: T): void {
61
- const newNode = new Node(element);
62
- if (!this.head) {
63
- this.head = newNode;
64
- this.tail = newNode;
65
- } else {
66
- this.tail!.next = newNode;
67
- this.tail = newNode;
68
- }
69
- this.length++;
70
- }
71
-
72
- /**
73
- * Adds an element to the front of the list
74
- */
75
- pushFront(element: T): void {
76
- const newNode = new Node(element);
77
- if (!this.head) {
78
- this.head = newNode;
79
- this.tail = newNode;
80
- } else {
81
- newNode.next = this.head;
82
- this.head = newNode;
83
- }
84
- this.length++;
85
- }
86
-
87
- /**
88
- * Removes and returns the last element from the list, or undefined if list is empty
89
- */
90
- popBack(): T | undefined {
91
- if (!this.head) {
92
- return undefined;
93
- }
94
- if (this.length === 1) {
95
- const value = this.head.value;
96
- this.head = null;
97
- this.tail = null;
98
- this.length = 0;
99
- return value;
100
- }
101
- let current = this.head;
102
- while (current.next !== this.tail) {
103
- current = current.next!;
104
- }
105
- const value = this.tail!.value;
106
- current.next = null;
107
- this.tail = current;
108
- this.length--;
109
- return value;
110
- }
111
-
112
- /**
113
- * Removes and returns the first element from the list, or undefined if list is empty
114
- */
115
- popFront(): T | undefined {
116
- if (!this.head) {
117
- return undefined;
118
- }
119
- const value = this.head.value;
120
- this.head = this.head.next;
121
- this.length--;
122
- if (this.length === 0) {
123
- this.tail = null;
124
- }
125
- return value;
126
- }
127
-
128
- /**
129
- * Inserts an element at the specified position. Returns true if successful, false if position is invalid
130
- */
131
- insert(element: T, position: number): boolean {
132
- if (position < 0 || position > this.length) {
133
- return false;
134
- }
135
- if (position === 0) {
136
- this.pushFront(element);
137
- return true;
138
- }
139
- if (position === this.length) {
140
- this.pushBack(element);
141
- return true;
142
- }
143
- const newNode = new Node(element);
144
- let current = this.head;
145
- let prev: Node<T> | null = null;
146
- let index: number = 0;
147
- while (index < position) {
148
- prev = current;
149
- current = current!.next;
150
- index++;
151
- }
152
- prev!.next = newNode;
153
- newNode.next = current;
154
- this.length++;
155
- return true;
156
- }
157
-
158
- /**
159
- * Inserts an element before the first element that satisfies the condition. Returns true if successful, false if no matching element found
160
- */
161
- insertBefore(element: T, condition: (element: T) => boolean): boolean {
162
- if (!this.head) {
163
- return false;
164
- }
165
- if (condition(this.head.value)) {
166
- this.pushFront(element);
167
- return true;
168
- }
169
- let current = this.head;
170
- while (current.next !== null) {
171
- if (condition(current.next.value)) {
172
- const newNode = new Node(element);
173
- newNode.next = current.next;
174
- current.next = newNode;
175
- this.length++;
176
- return true;
177
- }
178
- current = current.next;
179
- }
180
- return false;
181
- }
182
-
183
- /**
184
- * Inserts an element after the first element that satisfies the condition. Returns true if successful, false if no matching element found
185
- */
186
- insertAfter(element: T, condition: (element: T) => boolean): boolean {
187
- let current = this.head;
188
- while (current !== null) {
189
- if (condition(current.value)) {
190
- const newNode = new Node(element);
191
- newNode.next = current.next;
192
- current.next = newNode;
193
- if (current === this.tail) {
194
- this.tail = newNode;
195
- }
196
- this.length++;
197
- return true;
198
- }
199
- current = current.next;
200
- }
201
- return false;
202
- }
203
-
204
- /**
205
- * Removes the first element that satisfies the predicate. Returns true if an element was removed, false otherwise.
206
- */
207
- removeIf(condition: (element: T) => boolean): boolean {
208
- let current: Node<T> | null = this.head;
209
- let prev: Node<T> | null = null;
210
- while (current !== null) {
211
- if (condition(current.value)) {
212
- if (prev === null) {
213
- this.head = current.next;
214
- } else {
215
- prev.next = current.next;
216
- }
217
- if (current === this.tail) {
218
- this.tail = prev;
219
- }
220
- this.length--;
221
- return true;
222
- }
223
- prev = current;
224
- current = current.next;
225
- }
226
- return false;
227
- }
228
-
229
- /**
230
- * Removes and returns the element at the specified position. Returns undefined if position is invalid
231
- */
232
- removeAt(position: number): T | undefined {
233
- if (position < 0 || position >= this.length) {
234
- return undefined;
235
- }
236
- let current: Node<T> | null = this.head;
237
- if (position === 0) {
238
- this.head = current!.next;
239
- if (this.length === 1) {
240
- this.tail = null;
241
- }
242
- this.length--;
243
- return current!.value;
244
- }
245
-
246
- let prev: Node<T> | null = null;
247
- let index: number = 0;
248
- while (index < position) {
249
- prev = current;
250
- current = current!.next;
251
- index++;
252
- }
253
- prev!.next = current!.next;
254
- if (position === this.length - 1) {
255
- this.tail = prev;
256
- }
257
- this.length--;
258
- return current!.value;
259
- }
260
-
261
- /**
262
- * Executes a provided function once for each element in the list
263
- */
264
- forEach(callback: (element: T) => void): void {
265
- let current = this.head;
266
- while (current !== null) {
267
- callback(current.value);
268
- current = current.next;
269
- }
270
- }
271
-
272
- /**
273
- * Returns the element at the specified position without removing it. Returns undefined if position is invalid
274
- */
275
- get(position: number): T | undefined {
276
- if (position < 0 || position >= this.length) {
277
- return undefined;
278
- }
279
- // Optimize for front element
280
- if (position === 0) return this.head!.value;
281
- // Optimize for back element
282
- if (position === this.length - 1) return this.tail!.value;
283
- let current: Node<T> | null = this.head;
284
- let index: number = 0;
285
- while (index < position) {
286
- current = current!.next;
287
- index++;
288
- }
289
- return current!.value;
290
- }
291
-
292
- /**
293
- * Returns true if the list is empty, false otherwise
294
- */
295
- isEmpty(): boolean {
296
- return this.length === 0;
297
- }
298
-
299
- /**
300
- * Returns the number of elements in the list
301
- */
302
- size(): number {
303
- return this.length;
304
- }
305
-
306
- /**
307
- * Removes all elements from the list
308
- */
309
- clear(): void {
310
- this.head = null;
311
- this.tail = null;
312
- this.length = 0;
313
- }
314
- }
package/lib/map.ts DELETED
@@ -1,55 +0,0 @@
1
- import { Comparator } from '../types';
2
- import { RedBlackTree } from './red-black-tree';
3
-
4
-
5
- export interface Map<K, V> {
6
- insert(key: K, value: V): void;
7
- find(key: K): V | undefined;
8
- delete(key: K): void;
9
- remove(key: K): void;
10
- forEach(callback: (key: K, value: V) => void): void;
11
- clear(): void;
12
- isEmpty(): boolean;
13
- size(): number;
14
- }
15
-
16
-
17
- export class Map<K, V> implements Map<K, V> {
18
- private rbTree: RedBlackTree<K, V>;
19
-
20
- constructor(comparator: Comparator<K> = (a: K, b: K) => a < b) {
21
- this.rbTree = new RedBlackTree<K, V>(comparator);
22
- }
23
-
24
- insert(key: K, value: V): void {
25
- this.rbTree.insert(key, value);
26
- }
27
-
28
- find(key: K): V | undefined {
29
- return this.rbTree.find(key);
30
- }
31
-
32
- delete(key: K): void {
33
- this.rbTree.remove(key);
34
- }
35
-
36
- remove(key: K): void {
37
- this.rbTree.remove(key);
38
- }
39
-
40
- clear(): void {
41
- this.rbTree.clear();
42
- }
43
-
44
- size(): number {
45
- return this.rbTree.size();
46
- }
47
-
48
- isEmpty(): boolean {
49
- return this.rbTree.isEmpty();
50
- }
51
-
52
- forEach(callback: (key: K, value: V) => void): void {
53
- this.rbTree.forEach(callback);
54
- }
55
- }