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 CHANGED
@@ -1,8 +1,7 @@
1
1
  # TypeScript Data Structure Library
2
2
  [![NPM](https://img.shields.io/npm/v/typescript-ds-lib?label=npm%20package&color=limegreen)](https://www.npmjs.com/package/typescript-ds-lib)
3
3
 
4
- Native TypeScript data structure implementations without external dependencies.
5
- Provides Comparator for custom types. Just pass your own comparator function to the constructor.
4
+ TypeScript data structure implementations without external dependencies. Why to use this library?
6
5
 
7
6
  - Fully Tested
8
7
  - Fast
@@ -11,11 +10,13 @@ Provides Comparator for custom types. Just pass your own comparator function to
11
10
  - Comes with Comparator (for custom types)
12
11
  - `hashCode()` and `equals()` are supported
13
12
 
13
+
14
14
  ## Install
15
15
  ```
16
16
  npm install typescript-ds-lib
17
17
  ```
18
18
 
19
+
19
20
  ## Usage
20
21
  ```typescript
21
22
  import { Stack } from 'typescript-ds-lib';
@@ -32,6 +33,11 @@ console.log(stack.top()); // 2
32
33
  console.log(stack.size()); // 2
33
34
  ```
34
35
 
36
+
37
+ ## Documentation and Examples
38
+ See the [documentation](https://github.com/baloian/typescript-ds-lib/blob/master/doc/DOCUMENTATION.md) for more details and examples.
39
+
40
+
35
41
  ## Data Structures
36
42
  - Stack
37
43
  - Queue
@@ -44,11 +50,9 @@ console.log(stack.size()); // 2
44
50
  - Map
45
51
  - Hash Table
46
52
  - Matrix
53
+ - Graph (coming soon)
47
54
 
48
55
 
49
- ## Documentation and Examples
50
- See the [documentation](https://github.com/baloian/typescript-ds-lib/blob/master/doc/DOCUMENTATION.md) for more details and examples.
51
-
52
56
  ## Contributions
53
57
  Contributions are welcome and can be made by submitting GitHub pull requests
54
58
  to this repository. In general, the source code follows
package/dist/index.d.ts CHANGED
@@ -1,11 +1,12 @@
1
1
  export * from './types';
2
- export { Stack } from './lib/stack';
3
- export { Queue } from './lib/queue';
4
- export { PriorityQueue } from './lib/priority-queue';
5
2
  export { BinarySearchTree } from './lib/binary-search-tree';
6
3
  export { Deque } from './lib/deque';
4
+ export { HashTable } from './lib/hash-table';
7
5
  export { LinkedList } from './lib/linked-list';
8
- export { Set } from './lib/set';
9
6
  export { Map } from './lib/map';
7
+ export { Matrix } from './lib/matrix';
8
+ export { PriorityQueue } from './lib/priority-queue';
9
+ export { Queue } from './lib/queue';
10
10
  export { RedBlackTree } from './lib/red-black-tree';
11
- export { HashTable } from './lib/hash-table';
11
+ export { Set } from './lib/set';
12
+ export { Stack } from './lib/stack';
package/dist/index.js CHANGED
@@ -14,26 +14,28 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.HashTable = exports.RedBlackTree = exports.Map = exports.Set = exports.LinkedList = exports.Deque = exports.BinarySearchTree = exports.PriorityQueue = exports.Queue = exports.Stack = void 0;
17
+ exports.Stack = exports.Set = exports.RedBlackTree = exports.Queue = exports.PriorityQueue = exports.Matrix = exports.Map = exports.LinkedList = exports.HashTable = exports.Deque = exports.BinarySearchTree = void 0;
18
18
  __exportStar(require("./types"), exports);
19
- var stack_1 = require("./lib/stack");
20
- Object.defineProperty(exports, "Stack", { enumerable: true, get: function () { return stack_1.Stack; } });
21
- var queue_1 = require("./lib/queue");
22
- Object.defineProperty(exports, "Queue", { enumerable: true, get: function () { return queue_1.Queue; } });
23
- var priority_queue_1 = require("./lib/priority-queue");
24
- Object.defineProperty(exports, "PriorityQueue", { enumerable: true, get: function () { return priority_queue_1.PriorityQueue; } });
25
19
  var binary_search_tree_1 = require("./lib/binary-search-tree");
26
20
  Object.defineProperty(exports, "BinarySearchTree", { enumerable: true, get: function () { return binary_search_tree_1.BinarySearchTree; } });
27
21
  var deque_1 = require("./lib/deque");
28
22
  Object.defineProperty(exports, "Deque", { enumerable: true, get: function () { return deque_1.Deque; } });
23
+ var hash_table_1 = require("./lib/hash-table");
24
+ Object.defineProperty(exports, "HashTable", { enumerable: true, get: function () { return hash_table_1.HashTable; } });
29
25
  var linked_list_1 = require("./lib/linked-list");
30
26
  Object.defineProperty(exports, "LinkedList", { enumerable: true, get: function () { return linked_list_1.LinkedList; } });
31
- var set_1 = require("./lib/set");
32
- Object.defineProperty(exports, "Set", { enumerable: true, get: function () { return set_1.Set; } });
33
27
  var map_1 = require("./lib/map");
34
28
  Object.defineProperty(exports, "Map", { enumerable: true, get: function () { return map_1.Map; } });
29
+ var matrix_1 = require("./lib/matrix");
30
+ Object.defineProperty(exports, "Matrix", { enumerable: true, get: function () { return matrix_1.Matrix; } });
31
+ var priority_queue_1 = require("./lib/priority-queue");
32
+ Object.defineProperty(exports, "PriorityQueue", { enumerable: true, get: function () { return priority_queue_1.PriorityQueue; } });
33
+ var queue_1 = require("./lib/queue");
34
+ Object.defineProperty(exports, "Queue", { enumerable: true, get: function () { return queue_1.Queue; } });
35
35
  var red_black_tree_1 = require("./lib/red-black-tree");
36
36
  Object.defineProperty(exports, "RedBlackTree", { enumerable: true, get: function () { return red_black_tree_1.RedBlackTree; } });
37
- var hash_table_1 = require("./lib/hash-table");
38
- Object.defineProperty(exports, "HashTable", { enumerable: true, get: function () { return hash_table_1.HashTable; } });
37
+ var set_1 = require("./lib/set");
38
+ Object.defineProperty(exports, "Set", { enumerable: true, get: function () { return set_1.Set; } });
39
+ var stack_1 = require("./lib/stack");
40
+ Object.defineProperty(exports, "Stack", { enumerable: true, get: function () { return stack_1.Stack; } });
39
41
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,0CAAwB;AACxB,qCAAoC;AAA3B,8FAAA,KAAK,OAAA;AACd,qCAAoC;AAA3B,8FAAA,KAAK,OAAA;AACd,uDAAqD;AAA5C,+GAAA,aAAa,OAAA;AACtB,+DAA4D;AAAnD,sHAAA,gBAAgB,OAAA;AACzB,qCAAoC;AAA3B,8FAAA,KAAK,OAAA;AACd,iDAA+C;AAAtC,yGAAA,UAAU,OAAA;AACnB,iCAAgC;AAAvB,0FAAA,GAAG,OAAA;AACZ,iCAAgC;AAAvB,0FAAA,GAAG,OAAA;AACZ,uDAAoD;AAA3C,8GAAA,YAAY,OAAA;AACrB,+CAA6C;AAApC,uGAAA,SAAS,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,0CAAwB;AACxB,+DAA4D;AAAnD,sHAAA,gBAAgB,OAAA;AACzB,qCAAoC;AAA3B,8FAAA,KAAK,OAAA;AACd,+CAA6C;AAApC,uGAAA,SAAS,OAAA;AAClB,iDAA+C;AAAtC,yGAAA,UAAU,OAAA;AACnB,iCAAgC;AAAvB,0FAAA,GAAG,OAAA;AACZ,uCAAsC;AAA7B,gGAAA,MAAM,OAAA;AACf,uDAAqD;AAA5C,+GAAA,aAAa,OAAA;AACtB,qCAAoC;AAA3B,8FAAA,KAAK,OAAA;AACd,uDAAoD;AAA3C,8GAAA,YAAY,OAAA;AACrB,iCAAgC;AAAvB,0FAAA,GAAG,OAAA;AACZ,qCAAoC;AAA3B,8FAAA,KAAK,OAAA"}
@@ -0,0 +1,14 @@
1
+ export interface Graph<V, W> {
2
+ addVertex(vertex: V): void;
3
+ removeVertex(vertex: V): void;
4
+ addEdge(from: V, to: V, weight?: W): void;
5
+ removeEdge(from: V, to: V): void;
6
+ getNeighbors(vertex: V): V[];
7
+ getEdgeWeight(from: V, to: V): W;
8
+ getVertices(): V[];
9
+ hasVertex(vertex: V): boolean;
10
+ hasEdge(from: V, to: V): boolean;
11
+ vertexCount(): number;
12
+ edgeCount(): number;
13
+ clear(): void;
14
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=graph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph.js","sourceRoot":"","sources":["../../lib/graph.ts"],"names":[],"mappings":""}
@@ -0,0 +1,5 @@
1
+ export declare class HashTableUtils {
2
+ private static valueToString;
3
+ static hash<K>(key: K, capacity: number): number;
4
+ static keysEqual<K>(key1: K, key2: K): boolean;
5
+ }
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HashTableUtils = void 0;
4
+ class HashTableUtils {
5
+ static valueToString(value) {
6
+ if (value === null || value === undefined)
7
+ return 'null';
8
+ let stringKey;
9
+ switch (typeof value) {
10
+ case 'number':
11
+ stringKey = value.toString();
12
+ break;
13
+ case 'object':
14
+ if (typeof value.toString === 'function') {
15
+ stringKey = value.toString();
16
+ }
17
+ else {
18
+ stringKey = JSON.stringify(value);
19
+ }
20
+ break;
21
+ case 'string':
22
+ stringKey = value;
23
+ break;
24
+ case 'function':
25
+ stringKey = value.toString();
26
+ break;
27
+ case 'symbol':
28
+ stringKey = value.toString();
29
+ break;
30
+ default:
31
+ stringKey = String(value);
32
+ }
33
+ return stringKey;
34
+ }
35
+ static hash(key, capacity) {
36
+ if (key && typeof key.hashCode === 'function') {
37
+ return key.hashCode();
38
+ }
39
+ if (typeof key === 'number' && Number.isSafeInteger(key)) {
40
+ const knuthConstant = 2654435761;
41
+ return (Math.abs(key * knuthConstant) >>> 0) % capacity;
42
+ }
43
+ const stringKey = this.valueToString(key);
44
+ let hash = 0;
45
+ // DJB2 hash algorithm
46
+ for (let i = 0; i < stringKey.length; i++) {
47
+ hash = ((hash << 5) + hash) + stringKey.charCodeAt(i);
48
+ hash = hash >>> 0; // Convert to 32-bit unsigned integer
49
+ }
50
+ return hash % capacity;
51
+ }
52
+ static keysEqual(key1, key2) {
53
+ if (key1 && key2 && typeof key1.equals === 'function') {
54
+ return key1.equals(key2);
55
+ }
56
+ if (key1 === key2)
57
+ return true;
58
+ if (typeof key1 === 'number' && typeof key2 === 'number' && isNaN(key1) && isNaN(key2))
59
+ return true;
60
+ if (typeof key1 !== 'object' && typeof key2 !== 'object')
61
+ return key1 === key2;
62
+ if (key1 instanceof Date && key2 instanceof Date) {
63
+ // Handle invalid dates
64
+ if (isNaN(key1.getTime()) && isNaN(key2.getTime()))
65
+ return true;
66
+ return key1.getTime() === key2.getTime();
67
+ }
68
+ if (key1 instanceof RegExp && key2 instanceof RegExp) {
69
+ return key1.toString() === key2.toString();
70
+ }
71
+ if (Array.isArray(key1) && Array.isArray(key2)) {
72
+ return key1.length === key2.length &&
73
+ key1.every((val, idx) => HashTableUtils.keysEqual(val, key2[idx]));
74
+ }
75
+ if (key1 === null && key2 === null)
76
+ return true;
77
+ if (key1 === undefined && key2 === undefined)
78
+ return true;
79
+ if (key1 === null || key1 === undefined || key2 === null || key2 === undefined)
80
+ return false;
81
+ if (typeof key1 === 'object' && typeof key2 === 'object') {
82
+ const keys1 = Object.keys(key1);
83
+ const keys2 = Object.keys(key2);
84
+ return keys1.length === keys2.length &&
85
+ keys1.every(k => k in key2 && HashTableUtils.keysEqual(key1[k], key2[k]));
86
+ }
87
+ return false;
88
+ }
89
+ }
90
+ exports.HashTableUtils = HashTableUtils;
91
+ //# sourceMappingURL=hash-table-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash-table-utils.js","sourceRoot":"","sources":["../../lib/hash-table-utils.ts"],"names":[],"mappings":";;;AAAA,MAAa,cAAc;IACjB,MAAM,CAAC,aAAa,CAAI,KAAQ;QACtC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO,MAAM,CAAC;QACzD,IAAI,SAAiB,CAAC;QACtB,QAAQ,OAAO,KAAK,EAAE,CAAC;YACrB,KAAK,QAAQ;gBACX,SAAS,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;gBAC7B,MAAM;YACR,KAAK,QAAQ;gBACX,IAAI,OAAQ,KAAa,CAAC,QAAQ,KAAK,UAAU,EAAE,CAAC;oBAClD,SAAS,GAAI,KAAa,CAAC,QAAQ,EAAE,CAAC;gBACxC,CAAC;qBAAM,CAAC;oBACN,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;gBACpC,CAAC;gBACD,MAAM;YACR,KAAK,QAAQ;gBACX,SAAS,GAAG,KAAK,CAAC;gBAClB,MAAM;YACR,KAAK,UAAU;gBACb,SAAS,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;gBAC7B,MAAM;YACR,KAAK,QAAQ;gBACX,SAAS,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;gBAC7B,MAAM;YACR;gBACE,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,CAAC,IAAI,CAAI,GAAM,EAAE,QAAgB;QACrC,IAAI,GAAG,IAAI,OAAQ,GAAW,CAAC,QAAQ,KAAK,UAAU,EAAE,CAAC;YACvD,OAAQ,GAAW,CAAC,QAAQ,EAAE,CAAC;QACjC,CAAC;QACD,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC;YACzD,MAAM,aAAa,GAAG,UAAU,CAAC;YACjC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC,GAAG,QAAQ,CAAC;QAC1D,CAAC;QACD,MAAM,SAAS,GAAW,IAAI,CAAC,aAAa,CAAI,GAAG,CAAC,CAAC;QACrD,IAAI,IAAI,GAAG,CAAC,CAAC;QACb,sBAAsB;QACtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC1C,IAAI,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YACtD,IAAI,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC,qCAAqC;QAC1D,CAAC;QACD,OAAO,IAAI,GAAG,QAAQ,CAAC;IACzB,CAAC;IAED,MAAM,CAAC,SAAS,CAAI,IAAO,EAAE,IAAO;QAClC,IAAI,IAAI,IAAI,IAAI,IAAI,OAAQ,IAAY,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;YAC/D,OAAQ,IAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACpC,CAAC;QACD,IAAI,IAAI,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;QAC/B,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QACpG,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,OAAO,IAAI,KAAK,QAAQ;YAAE,OAAO,IAAI,KAAK,IAAI,CAAC;QAC/E,IAAI,IAAI,YAAY,IAAI,IAAI,IAAI,YAAY,IAAI,EAAE,CAAC;YACjD,uBAAuB;YACvB,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;gBAAE,OAAO,IAAI,CAAC;YAChE,OAAO,IAAI,CAAC,OAAO,EAAE,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC;QAC3C,CAAC;QACD,IAAI,IAAI,YAAY,MAAM,IAAI,IAAI,YAAY,MAAM,EAAE,CAAC;YACrD,OAAO,IAAI,CAAC,QAAQ,EAAE,KAAK,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC7C,CAAC;QACD,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/C,OAAO,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM;gBAChC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,cAAc,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACvE,CAAC;QACD,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;QAChD,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC;QAC1D,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO,KAAK,CAAC;QAE7F,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;YACzD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAChC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAChC,OAAO,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM;gBAClC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,IAAI,IAAI,cAAc,CAAC,SAAS,CAAE,IAAY,CAAC,CAAC,CAAC,EAAG,IAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAChG,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;CACF;AA/ED,wCA+EC"}
@@ -11,6 +11,4 @@ export declare class HashTable<K, V> implements HashTable<K, V> {
11
11
  private count;
12
12
  private readonly capacity;
13
13
  constructor(capacity?: number);
14
- private hash;
15
- private keysEqual;
16
14
  }
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.HashTable = void 0;
4
+ const hash_table_utils_1 = require("./hash-table-utils");
4
5
  class HashNode {
5
6
  key;
6
7
  value;
@@ -16,60 +17,13 @@ class HashTable {
16
17
  count;
17
18
  capacity;
18
19
  constructor(capacity = 32) {
19
- this.table = new Array(capacity).fill(null);
20
+ // Handle negative or zero capacity by using default capacity
21
+ this.capacity = capacity <= 0 ? 32 : capacity;
22
+ this.table = new Array(this.capacity).fill(null);
20
23
  this.count = 0;
21
- this.capacity = capacity;
22
- }
23
- hash(key) {
24
- if (typeof key.hashCode === 'function') {
25
- return key.hashCode();
26
- }
27
- let stringKey;
28
- switch (typeof key) {
29
- case 'number':
30
- // If the number is a safe integer, use Knuth's multiplicative method.
31
- if (Number.isSafeInteger(key)) {
32
- const knuthConstant = 2654435761;
33
- return (Math.abs(key * knuthConstant) >>> 0) % this.capacity;
34
- }
35
- stringKey = key.toString();
36
- break;
37
- case 'object':
38
- if (key === null) {
39
- stringKey = 'null';
40
- }
41
- else if (typeof key.toString === 'function') {
42
- stringKey = key.toString();
43
- }
44
- else {
45
- stringKey = JSON.stringify(key);
46
- }
47
- break;
48
- case 'string':
49
- stringKey = key;
50
- break;
51
- case 'function':
52
- stringKey = key.toString();
53
- break;
54
- case 'symbol':
55
- stringKey = key.toString();
56
- break;
57
- case 'undefined':
58
- stringKey = 'null';
59
- break;
60
- default:
61
- stringKey = String(key);
62
- }
63
- let hash = 0;
64
- // DJB2 hash algorithm
65
- for (let i = 0; i < stringKey.length; i++) {
66
- hash = ((hash << 5) + hash) + stringKey.charCodeAt(i);
67
- hash = hash >>> 0; // Convert to 32-bit unsigned integer
68
- }
69
- return hash % this.capacity;
70
24
  }
71
25
  insert(key, value) {
72
- const index = this.hash(key);
26
+ const index = hash_table_utils_1.HashTableUtils.hash(key, this.capacity);
73
27
  const newNode = new HashNode(key, value);
74
28
  if (!this.table[index]) {
75
29
  this.table[index] = newNode;
@@ -78,7 +32,7 @@ class HashTable {
78
32
  }
79
33
  let current = this.table[index];
80
34
  while (current) {
81
- if (this.keysEqual(current.key, key)) {
35
+ if (hash_table_utils_1.HashTableUtils.keysEqual(current.key, key)) {
82
36
  current.value = value;
83
37
  return;
84
38
  }
@@ -91,10 +45,10 @@ class HashTable {
91
45
  }
92
46
  }
93
47
  get(key) {
94
- const index = this.hash(key);
48
+ const index = hash_table_utils_1.HashTableUtils.hash(key, this.capacity);
95
49
  let current = this.table[index];
96
50
  while (current) {
97
- if (this.keysEqual(current.key, key)) {
51
+ if (hash_table_utils_1.HashTableUtils.keysEqual(current.key, key)) {
98
52
  return current.value;
99
53
  }
100
54
  current = current.next;
@@ -102,11 +56,11 @@ class HashTable {
102
56
  return undefined;
103
57
  }
104
58
  remove(key) {
105
- const index = this.hash(key);
59
+ const index = hash_table_utils_1.HashTableUtils.hash(key, this.capacity);
106
60
  let current = this.table[index];
107
61
  let prev = null;
108
62
  while (current) {
109
- if (this.keysEqual(current.key, key)) {
63
+ if (hash_table_utils_1.HashTableUtils.keysEqual(current.key, key)) {
110
64
  if (prev) {
111
65
  prev.next = current.next;
112
66
  }
@@ -121,36 +75,6 @@ class HashTable {
121
75
  }
122
76
  return false;
123
77
  }
124
- keysEqual(key1, key2) {
125
- // Check if keys have equals method and use it for comparison
126
- if (typeof key1.equals === 'function') {
127
- return key1.equals(key2);
128
- }
129
- if (key1 === key2)
130
- return true;
131
- if (key1 == null || key2 == null)
132
- return false;
133
- if (typeof key1 !== 'object' && typeof key2 !== 'object') {
134
- return key1 === key2;
135
- }
136
- if (key1 instanceof Date && key2 instanceof Date) {
137
- return key1.getTime() === key2.getTime();
138
- }
139
- if (key1 instanceof RegExp && key2 instanceof RegExp) {
140
- return key1.toString() === key2.toString();
141
- }
142
- if (Array.isArray(key1) && Array.isArray(key2)) {
143
- return key1.length === key2.length &&
144
- key1.every((val, idx) => this.keysEqual(val, key2[idx]));
145
- }
146
- if (typeof key1 === 'object' && typeof key2 === 'object') {
147
- const keys1 = Object.keys(key1);
148
- const keys2 = Object.keys(key2);
149
- return keys1.length === keys2.length &&
150
- keys1.every(k => k in key2 && this.keysEqual(key1[k], key2[k]));
151
- }
152
- return false;
153
- }
154
78
  size() {
155
79
  return this.count;
156
80
  }
@@ -1 +1 @@
1
- {"version":3,"file":"hash-table.js","sourceRoot":"","sources":["../../lib/hash-table.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hash-table.js","sourceRoot":"","sources":["../../lib/hash-table.ts"],"names":[],"mappings":";;;AAAA,yDAAoD;AAapD,MAAM,QAAQ;IACZ,GAAG,CAAI;IACP,KAAK,CAAI;IACT,IAAI,CAAwB;IAE5B,YAAY,GAAM,EAAE,KAAQ;QAC1B,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAGD,MAAa,SAAS;IACZ,KAAK,CAA+B;IACpC,KAAK,CAAS;IACL,QAAQ,CAAS;IAElC,YAAY,WAAmB,EAAE;QAC/B,6DAA6D;QAC7D,IAAI,CAAC,QAAQ,GAAG,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;QAC9C,IAAI,CAAC,KAAK,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjD,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;IACjB,CAAC;IAED,MAAM,CAAC,GAAM,EAAE,KAAQ;QACrB,MAAM,KAAK,GAAG,iCAAc,CAAC,IAAI,CAAI,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QACzD,MAAM,OAAO,GAAG,IAAI,QAAQ,CAAO,GAAG,EAAE,KAAK,CAAC,CAAC;QAC/C,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YACvB,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC;YAC5B,IAAI,CAAC,KAAK,EAAE,CAAC;YACb,OAAO;QACT,CAAC;QACD,IAAI,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAChC,OAAO,OAAO,EAAE,CAAC;YACf,IAAI,iCAAc,CAAC,SAAS,CAAI,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC;gBAClD,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC;gBACtB,OAAO;YACT,CAAC;YACD,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;gBAClB,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC;gBACvB,IAAI,CAAC,KAAK,EAAE,CAAC;gBACb,OAAO;YACT,CAAC;YACD,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;QACzB,CAAC;IACH,CAAC;IAED,GAAG,CAAC,GAAM;QACR,MAAM,KAAK,GAAG,iCAAc,CAAC,IAAI,CAAI,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QACzD,IAAI,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAChC,OAAO,OAAO,EAAE,CAAC;YACf,IAAI,iCAAc,CAAC,SAAS,CAAI,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC;gBAClD,OAAO,OAAO,CAAC,KAAK,CAAC;YACvB,CAAC;YACD,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;QACzB,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,CAAC,GAAM;QACX,MAAM,KAAK,GAAG,iCAAc,CAAC,IAAI,CAAI,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QACzD,IAAI,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAChC,IAAI,IAAI,GAA0B,IAAI,CAAC;QACvC,OAAO,OAAO,EAAE,CAAC;YACf,IAAI,iCAAc,CAAC,SAAS,CAAI,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC;gBAClD,IAAI,IAAI,EAAE,CAAC;oBACT,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;gBAC3B,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;gBACnC,CAAC;gBACD,IAAI,CAAC,KAAK,EAAE,CAAC;gBACb,OAAO,IAAI,CAAC;YACd,CAAC;YACD,IAAI,GAAG,OAAO,CAAC;YACf,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;QACzB,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAC,KAAK,KAAK,CAAC,CAAC;IAC1B,CAAC;IAED,KAAK;QACH,IAAI,CAAC,KAAK,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjD,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;IACjB,CAAC;CACF;AA/ED,8BA+EC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "typescript-ds-lib",
3
- "version": "0.2.7",
3
+ "version": "0.2.9",
4
4
  "description": "A collection of TypeScript data structure implementations",
5
5
  "author": "Artiom Baloian <artiom.baloian@gmail.com>",
6
6
  "license": "MIT",
@@ -8,14 +8,12 @@
8
8
  "types": "dist/index.d.ts",
9
9
  "files": [
10
10
  "dist",
11
- "lib",
12
- "types",
13
11
  "README.md",
14
12
  "LICENSE"
15
13
  ],
16
14
  "scripts": {
17
15
  "build": "rm -rf dist && tsc",
18
- "prepare": "npm run build",
16
+ "prepare": "npm run build",
19
17
  "test": "rm -rf dist && tsc && jest"
20
18
  },
21
19
  "repository": {
@@ -1,218 +0,0 @@
1
- import { Comparator } from '../types';
2
-
3
-
4
- export interface BinarySearchTree<T> {
5
- insert(element: T): void;
6
- remove(element: T): void;
7
- find(element: T): boolean;
8
- min(): T | undefined;
9
- max(): T | undefined;
10
- forEach(callback: (element: T) => void, traversal?: 'inorder' | 'preorder' | 'postorder'): void;
11
- isEmpty(): boolean;
12
- clear(): void;
13
- count(): number;
14
- }
15
-
16
-
17
- class TreeNode<T> {
18
- value: T;
19
- left: TreeNode<T> | null;
20
- right: TreeNode<T> | null;
21
-
22
- constructor(value: T) {
23
- this.value = value;
24
- this.left = null;
25
- this.right = null;
26
- }
27
- }
28
-
29
-
30
- export class BinarySearchTree<T> implements BinarySearchTree<T> {
31
- private root: TreeNode<T> | null;
32
- private comparator: Comparator<T>;
33
-
34
- constructor(comparator: Comparator<T> = (a: T, b: T) => a < b) {
35
- this.root = null;
36
- this.comparator = comparator;
37
- }
38
-
39
- /**
40
- * Inserts a value into the BST
41
- */
42
- insert(value: T): void {
43
- const newNode = new TreeNode(value);
44
- if (!this.root) {
45
- this.root = newNode;
46
- return;
47
- }
48
- let current = this.root;
49
- while (true) {
50
- if (this.comparator(value, current.value)) {
51
- if (current.left === null) {
52
- current.left = newNode;
53
- break;
54
- }
55
- current = current.left;
56
- } else {
57
- if (current.right === null) {
58
- current.right = newNode;
59
- break;
60
- }
61
- current = current.right;
62
- }
63
- }
64
- }
65
-
66
- /**
67
- * Searches for a value in the BST. Returns true if found, false otherwise
68
- */
69
- find(value: T): boolean {
70
- let current = this.root;
71
- while (current !== null) {
72
- if (this.isEqual(value, current.value)) {
73
- return true;
74
- }
75
- if (this.comparator(value, current.value)) {
76
- current = current.left;
77
- } else {
78
- current = current.right;
79
- }
80
- }
81
- return false;
82
- }
83
-
84
- /**
85
- * Returns the minimum value in the BST, or undefined if tree is empty
86
- */
87
- min(): T | undefined {
88
- if (!this.root) return undefined;
89
- let current = this.root;
90
- while (current.left !== null) {
91
- current = current.left;
92
- }
93
- return current.value;
94
- }
95
-
96
- /**
97
- * Returns the maximum value in the BST, or undefined if tree is empty
98
- */
99
- max(): T | undefined {
100
- if (!this.root) return undefined;
101
- let current = this.root;
102
- while (current.right !== null) {
103
- current = current.right;
104
- }
105
- return current.value;
106
- }
107
-
108
- /**
109
- * Removes a value from the BST if it exists
110
- */
111
- remove(value: T): void {
112
- this.root = this.removeNode(this.root, value);
113
- }
114
-
115
- private removeNode(node: TreeNode<T> | null, value: T): TreeNode<T> | null {
116
- if (node === null) return null;
117
- if (this.comparator(value, node.value)) {
118
- node.left = this.removeNode(node.left, value);
119
- return node;
120
- } else if (this.comparator(node.value, value)) {
121
- node.right = this.removeNode(node.right, value);
122
- return node;
123
- } else {
124
- // Node to delete found
125
- // Case 1: Leaf node
126
- if (node.left === null && node.right === null) {
127
- return null;
128
- }
129
- // Case 2: Node with one child
130
- if (node.left === null) return node.right;
131
- if (node.right === null) return node.left;
132
- // Case 3: Node with two children
133
- const minNode = this.findMin(node.right);
134
- node.value = minNode.value;
135
- node.right = this.removeNode(node.right, minNode.value);
136
- return node;
137
- }
138
- }
139
-
140
- private findMin(node: TreeNode<T>): TreeNode<T> {
141
- let current = node;
142
- while (current.left !== null) {
143
- current = current.left;
144
- }
145
- return current;
146
- }
147
-
148
- private isEqual(a: T, b: T): boolean {
149
- // Two values are equal if neither is less than the other
150
- return !this.comparator(a, b) && !this.comparator(b, a);
151
- }
152
-
153
- /**
154
- * Executes a callback function for each element in the BST in-order traversal
155
- */
156
- forEach(callback: (element: T) => void, traversal: 'inorder' | 'preorder' | 'postorder' = 'inorder'): void {
157
- switch (traversal) {
158
- case 'inorder':
159
- this.inorderTraversal(this.root, callback);
160
- break;
161
- case 'preorder':
162
- this.preorderTraversal(this.root, callback);
163
- break;
164
- case 'postorder':
165
- this.postorderTraversal(this.root, callback);
166
- break;
167
- default:
168
- this.inorderTraversal(this.root, callback);
169
- }
170
- }
171
-
172
- private inorderTraversal(node: TreeNode<T> | null, callback: (element: T) => void): void {
173
- if (node === null) return;
174
- this.inorderTraversal(node.left, callback);
175
- callback(node.value);
176
- this.inorderTraversal(node.right, callback);
177
- }
178
-
179
- private preorderTraversal(node: TreeNode<T> | null, callback: (element: T) => void): void {
180
- if (node === null) return;
181
- callback(node.value);
182
- this.preorderTraversal(node.left, callback);
183
- this.preorderTraversal(node.right, callback);
184
- }
185
-
186
- private postorderTraversal(node: TreeNode<T> | null, callback: (element: T) => void): void {
187
- if (node === null) return;
188
- this.postorderTraversal(node.left, callback);
189
- this.postorderTraversal(node.right, callback);
190
- callback(node.value);
191
- }
192
-
193
- /**
194
- * Returns true if the BST is empty, false otherwise
195
- */
196
- isEmpty(): boolean {
197
- return this.root === null;
198
- }
199
-
200
- /**
201
- * Removes all nodes from the BST
202
- */
203
- clear(): void {
204
- this.root = null;
205
- }
206
-
207
- /**
208
- * Returns the number of nodes in the BST
209
- */
210
- count(): number {
211
- return this.countNodes(this.root);
212
- }
213
-
214
- private countNodes(node: TreeNode<T> | null): number {
215
- if (node === null) return 0;
216
- return 1 + this.countNodes(node.left) + this.countNodes(node.right);
217
- }
218
- }