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/README.md +9 -5
- package/dist/index.d.ts +6 -5
- package/dist/index.js +13 -11
- package/dist/index.js.map +1 -1
- package/dist/lib/graph.d.ts +14 -0
- package/dist/lib/graph.js +3 -0
- package/dist/lib/graph.js.map +1 -0
- package/dist/lib/hash-table-utils.d.ts +5 -0
- package/dist/lib/hash-table-utils.js +91 -0
- package/dist/lib/hash-table-utils.js.map +1 -0
- package/dist/lib/hash-table.d.ts +0 -2
- package/dist/lib/hash-table.js +10 -86
- package/dist/lib/hash-table.js.map +1 -1
- package/package.json +2 -4
- package/lib/binary-search-tree.ts +0 -218
- package/lib/deque.ts +0 -86
- package/lib/hash-table.ts +0 -179
- package/lib/linked-list.ts +0 -314
- package/lib/map.ts +0 -55
- package/lib/matrix.ts +0 -427
- package/lib/priority-queue.ts +0 -71
- package/lib/queue.ts +0 -62
- package/lib/red-black-tree.ts +0 -350
- package/lib/set.ts +0 -83
- package/lib/stack.ts +0 -59
- package/types/index.ts +0 -1
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
|
-
}
|
package/lib/linked-list.ts
DELETED
|
@@ -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
|
-
}
|