From d221391f6d83160846fa96833e79d0250dc19d23 Mon Sep 17 00:00:00 2001 From: Ashok Dey Date: Fri, 29 Nov 2019 19:51:21 +0530 Subject: [PATCH 01/13] update: initial skeleton for Hash Table --- src/_DataStructures_/HashTable/HashEntry.js | 9 ++ src/_DataStructures_/HashTable/index.js | 109 ++++++++++++++++++++ src/_DataStructures_/LinkedList/index.js | 4 +- 3 files changed, 120 insertions(+), 2 deletions(-) create mode 100644 src/_DataStructures_/HashTable/HashEntry.js create mode 100644 src/_DataStructures_/HashTable/index.js diff --git a/src/_DataStructures_/HashTable/HashEntry.js b/src/_DataStructures_/HashTable/HashEntry.js new file mode 100644 index 00000000..a6a8f8c3 --- /dev/null +++ b/src/_DataStructures_/HashTable/HashEntry.js @@ -0,0 +1,9 @@ +class HashEntry { + constructor(key, value) { + this.key = key; + this.value = value; + this.next = null; + } +} + +module.exports = HashEntry; diff --git a/src/_DataStructures_/HashTable/index.js b/src/_DataStructures_/HashTable/index.js new file mode 100644 index 00000000..665987a3 --- /dev/null +++ b/src/_DataStructures_/HashTable/index.js @@ -0,0 +1,109 @@ +const { Node } = require('../LinkedList'); + +class HashTable { + constructor(slots) { + // init with a default set of slots + this.slot = slots || 17; + // size to hold the current size + // and help to resize when the table is half filled + this.size = 0; + // the main bucket + this.bucket = new Array(this.slot); + + // fill the bucket with null + for (let i = 0; i < this.slot; i += 1) this.bucket[i] = null; + } + + _hash(key) { + // convert the key to String; + const stringKey = String(key); + + let index = 0; + const PRIME = 1801; + + // loop till the length of the key or mamx 100 + const loopTill = Math.min(stringKey.length, 100); + + for (let i = 0; i < loopTill; i += 1) { + const char = stringKey[i]; + const value = char.charCodeAt(0) - 96; + index = (index + PRIME + value) % this.bucket.length; + } + return index; + } + + _push(index, value) { + /** + * Util to add a SSL to the index in case of more than once + * value for the same key exixts + */ + const node = new Node(value); + if (!this.bucket[index]) { + this.bucket[index] = node; + this.size += 1; + return index; + } + + let head = this.bucket[index]; + + // traverse to the end + while (head.next !== null) { + head = head.next; + } + head.next = node; + this.size += 1; + return index; + } + + _values(index, key) { + /** + * Util to return the values as an array + */ + const res = []; + let head = this.bucket[index]; + while (head !== null) { + if (head.data.key === key) { + res.push(head.data.value); + } + head = head.next; + } + return res; + } + + set(key, value) { + // eslint-disable-next-line no-underscore-dangle + const index = this._hash(key); + // storing value as an key-value pair + // eslint-disable-next-line no-underscore-dangle + this._push(index, { key, value }); + } + + get(key) { + // get the index + // eslint-disable-next-line no-underscore-dangle + const index = this._hash(key); + if (!this.bucket[index]) return null; + // eslint-disable-next-line no-underscore-dangle + return this._values(index, key); + } + + getSize() { + return this.size; + } + + isEmpty() { + return this.getSize() === 0; + } +} + +// const ht = new HashTable(); +// ht.set('hello', 'I am a new value'); +// ht.set('hello', 'I am a yet another value'); +// ht.set('maroon', 'I maroon'); +// ht.set('yellow', 'I am yellow'); + +// console.log(ht.get('hello')); +// console.log(ht.get('maroon')); +// console.log(ht.bucket); + +module.exports = HashTable; diff --git a/src/_DataStructures_/LinkedList/index.js b/src/_DataStructures_/LinkedList/index.js index 4324dca7..74115b3f 100644 --- a/src/_DataStructures_/LinkedList/index.js +++ b/src/_DataStructures_/LinkedList/index.js @@ -1,8 +1,8 @@ -// do not change the node class, you never know how many things it caan break! :) +// do not change the node class, you never know how many things it caan break! :) class Node { constructor(data, next) { this.data = data; - this.next = next; + this.next = next || null; } } From bd73d1fa785ed0aba25b1dd434a2a73b7c0d4f52 Mon Sep 17 00:00:00 2001 From: Ashok Dey Date: Sat, 30 Nov 2019 00:55:28 +0530 Subject: [PATCH 02/13] update: change in the Node structure --- src/_DataStructures_/HashTable/HashEntry.js | 2 +- src/_DataStructures_/HashTable/index.js | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/_DataStructures_/HashTable/HashEntry.js b/src/_DataStructures_/HashTable/HashEntry.js index a6a8f8c3..82808392 100644 --- a/src/_DataStructures_/HashTable/HashEntry.js +++ b/src/_DataStructures_/HashTable/HashEntry.js @@ -1,5 +1,5 @@ class HashEntry { - constructor(key, value) { + constructor({ key, value }) { this.key = key; this.value = value; this.next = null; diff --git a/src/_DataStructures_/HashTable/index.js b/src/_DataStructures_/HashTable/index.js index 665987a3..64937a43 100644 --- a/src/_DataStructures_/HashTable/index.js +++ b/src/_DataStructures_/HashTable/index.js @@ -1,4 +1,4 @@ -const { Node } = require('../LinkedList'); +const HashEntry = require('./HashEntry'); class HashTable { constructor(slots) { @@ -37,7 +37,7 @@ class HashTable { * Util to add a SSL to the index in case of more than once * value for the same key exixts */ - const node = new Node(value); + const node = new HashEntry(value); if (!this.bucket[index]) { this.bucket[index] = node; this.size += 1; @@ -62,8 +62,8 @@ class HashTable { const res = []; let head = this.bucket[index]; while (head !== null) { - if (head.data.key === key) { - res.push(head.data.value); + if (head.key === key) { + res.push(head.value); } head = head.next; } @@ -96,7 +96,7 @@ class HashTable { } } -// const ht = new HashTable(); +// const ht = new HashTable(5); // ht.set('hello', 'I am a new value'); // ht.set('hello', 'I am a yet another value'); // ht.set('maroon', 'I maroon'); From ae5ea995e5a98dca0987974357364ca72b147d83 Mon Sep 17 00:00:00 2001 From: Ashok Dey Date: Sat, 30 Nov 2019 11:46:07 +0530 Subject: [PATCH 03/13] update: added rehashing to avoid collision --- src/_DataStructures_/HashTable/index.js | 43 ++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/src/_DataStructures_/HashTable/index.js b/src/_DataStructures_/HashTable/index.js index 64937a43..7d977c88 100644 --- a/src/_DataStructures_/HashTable/index.js +++ b/src/_DataStructures_/HashTable/index.js @@ -3,10 +3,12 @@ const HashEntry = require('./HashEntry'); class HashTable { constructor(slots) { // init with a default set of slots - this.slot = slots || 17; + this.slot = slots || 19; // size to hold the current size // and help to resize when the table is half filled this.size = 0; + // threshold (let it be 70%) + this.threshold = 0.7; // the main bucket this.bucket = new Array(this.slot); @@ -32,6 +34,34 @@ class HashTable { return index; } + _resize() { + const oldSlot = this.slot; + const oldBucket = this.bucket; + + this.slot = oldSlot * 2; + const newBucket = new Array(this.slot); + // fill the new bucket with nulls + for (let i = 0; i < this.slot; i += 1) newBucket[i] = null; + + this.bucket = newBucket; + + for (let i = 0; i < oldSlot; i += 1) { + if (oldBucket[i]) { + // get all the nodes associated here + let head = oldBucket[i]; + + while (head !== null) { + const { key, value } = head; + // eslint-disable-next-line no-underscore-dangle + const newIndex = this._hash(key); + // eslint-disable-next-line no-underscore-dangle + this._push(newIndex, { key, value }); + head = head.next; + } + } + } + } + _push(index, value) { /** * Util to add a SSL to the index in case of more than once @@ -76,6 +106,17 @@ class HashTable { // storing value as an key-value pair // eslint-disable-next-line no-underscore-dangle this._push(index, { key, value }); + + /** + * calculate the load factor, if it's greater than threshold + * resize the hash table + */ + const loadFactor = (this.size / this.slot).toFixed(1); + if (loadFactor > this.threshold) { + // console.log('Resizing hash table'); + // eslint-disable-next-line no-underscore-dangle + this._resize(); + } } get(key) { From 44c158a6e429e879b03e7ebacae2139f22c10dcd Mon Sep 17 00:00:00 2001 From: Ashok Dey Date: Sat, 30 Nov 2019 13:06:12 +0530 Subject: [PATCH 04/13] fixes: better hash function, improved comments --- src/_DataStructures_/HashTable/index.js | 37 ++++++++++++++----------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/src/_DataStructures_/HashTable/index.js b/src/_DataStructures_/HashTable/index.js index 7d977c88..710251f4 100644 --- a/src/_DataStructures_/HashTable/index.js +++ b/src/_DataStructures_/HashTable/index.js @@ -8,7 +8,7 @@ class HashTable { // and help to resize when the table is half filled this.size = 0; // threshold (let it be 70%) - this.threshold = 0.7; + this.threshold = 0.8; // the main bucket this.bucket = new Array(this.slot); @@ -21,15 +21,17 @@ class HashTable { const stringKey = String(key); let index = 0; - const PRIME = 1801; + const PRIME_MULTIPLIER = 1801; // Random prime number + const PRIME_ADDER = 2029; // Random prime number - // loop till the length of the key or mamx 100 + // loop till the length of the key or max 100 const loopTill = Math.min(stringKey.length, 100); for (let i = 0; i < loopTill; i += 1) { const char = stringKey[i]; const value = char.charCodeAt(0) - 96; - index = (index + PRIME + value) % this.bucket.length; + index = (index * PRIME_MULTIPLIER + value) % this.bucket.length; + index = (index + PRIME_ADDER) % this.bucket.length; } return index; } @@ -47,7 +49,6 @@ class HashTable { for (let i = 0; i < oldSlot; i += 1) { if (oldBucket[i]) { - // get all the nodes associated here let head = oldBucket[i]; while (head !== null) { @@ -64,8 +65,8 @@ class HashTable { _push(index, value) { /** - * Util to add a SSL to the index in case of more than once - * value for the same key exixts + * Utility to add a SLL to the index in case of more than one + * key hashes to the same index */ const node = new HashEntry(value); if (!this.bucket[index]) { @@ -87,7 +88,7 @@ class HashTable { _values(index, key) { /** - * Util to return the values as an array + * Utility to return the values as an array for a given key */ const res = []; let head = this.bucket[index]; @@ -111,7 +112,7 @@ class HashTable { * calculate the load factor, if it's greater than threshold * resize the hash table */ - const loadFactor = (this.size / this.slot).toFixed(1); + const loadFactor = Number((this.size / this.slot).toFixed(1)); if (loadFactor > this.threshold) { // console.log('Resizing hash table'); // eslint-disable-next-line no-underscore-dangle @@ -120,7 +121,7 @@ class HashTable { } get(key) { - // get the index + // get the index for the given key // eslint-disable-next-line no-underscore-dangle const index = this._hash(key); if (!this.bucket[index]) return null; @@ -137,14 +138,18 @@ class HashTable { } } -// const ht = new HashTable(5); -// ht.set('hello', 'I am a new value'); -// ht.set('hello', 'I am a yet another value'); -// ht.set('maroon', 'I maroon'); -// ht.set('yellow', 'I am yellow'); +const ht = new HashTable(5); +console.log('HT slots = ', ht.slot); +ht.set('maroon', 'I maroon'); +ht.set('hello', 'I am a new value'); +console.log(ht.bucket); +ht.set('hell', 'Bad value'); +ht.set('hello', 'I am a yet another value'); +console.log('HT slots = ', ht.slot); +ht.set('yellow', 'I am yellow'); // console.log(ht.get('hello')); // console.log(ht.get('maroon')); -// console.log(ht.bucket); +console.log(ht.bucket); module.exports = HashTable; From 62c6b714ca4b4885ae0272b0d4b92675ef9f2be5 Mon Sep 17 00:00:00 2001 From: Ashok Dey Date: Sat, 30 Nov 2019 13:06:46 +0530 Subject: [PATCH 05/13] update: change in threshold value --- src/_DataStructures_/HashTable/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_DataStructures_/HashTable/index.js b/src/_DataStructures_/HashTable/index.js index 710251f4..5fd8cb71 100644 --- a/src/_DataStructures_/HashTable/index.js +++ b/src/_DataStructures_/HashTable/index.js @@ -8,7 +8,7 @@ class HashTable { // and help to resize when the table is half filled this.size = 0; // threshold (let it be 70%) - this.threshold = 0.8; + this.threshold = 0.7; // the main bucket this.bucket = new Array(this.slot); From 7ff82768ef853010567c18e1e7837bac8441d1fe Mon Sep 17 00:00:00 2001 From: Ashok Dey Date: Sat, 30 Nov 2019 15:12:16 +0530 Subject: [PATCH 06/13] update: entry in README --- README.md | 7 +++++++ TOC.md | 1 + 2 files changed, 8 insertions(+) diff --git a/README.md b/README.md index 76b915fc..e248ef87 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,13 @@ This repo contains the following sections implemented in **JavaScript** Find the detailed contents and problem list here: [Table Of Contents](TOC.md) +## Contributors + +| Name | Twitter | LinkedIn | Website | +| ------------ | ------------------------------------------- | --------------------------------------------- | ------------------------------------------ | +| Ashok Dey | [ashokdey\_](https://twitter.com/ashokdey_) | [Ashok Dey](https://linkedin.com/in/ashokdey) | [https://ashokdey.in](https://ashokdey.in) | +| Ashu Deshwal | [\_TheSTL](https://twitter.com/_TheSTL_) | - | - | + ## Contribution Guide It's great to know that you want to contribute to this repo. Thanks for taking interest. please fing the [guide here](https://github.com/knaxus/problem-solving-javascript/blob/master/CONTRIBUTING.md) diff --git a/TOC.md b/TOC.md index 56a847f6..09a67ec7 100644 --- a/TOC.md +++ b/TOC.md @@ -49,6 +49,7 @@ - Problems - [K Largest Elements](src/_DataStructures_/Heaps/k-largest-in-array) - [K Smallest Elements](src/_DataStructures_/Heaps/k-smallest-in-array) +- [Hash Table](src/_DataStructures_/HashTable) ### Logical Problems From 22c64650110367e1a290d3f6d40d8bda423b5f93 Mon Sep 17 00:00:00 2001 From: Ashok Dey Date: Sat, 30 Nov 2019 15:23:04 +0530 Subject: [PATCH 07/13] update: added list of contributors --- README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e248ef87..98090fa5 100644 --- a/README.md +++ b/README.md @@ -28,10 +28,12 @@ Find the detailed contents and problem list here: [Table Of Contents](TOC.md) ## Contributors -| Name | Twitter | LinkedIn | Website | -| ------------ | ------------------------------------------- | --------------------------------------------- | ------------------------------------------ | -| Ashok Dey | [ashokdey\_](https://twitter.com/ashokdey_) | [Ashok Dey](https://linkedin.com/in/ashokdey) | [https://ashokdey.in](https://ashokdey.in) | -| Ashu Deshwal | [\_TheSTL](https://twitter.com/_TheSTL_) | - | - | +| Name | Twitter | LinkedIn | Website | +| ----------------------------------------- | ------------------------------------------- | --------------------------------------------- | ------------------------------------------ | +| [Ashok Dey](https://github.com/ashokdey) | [ashokdey\_](https://twitter.com/ashokdey_) | [Ashok Dey](https://linkedin.com/in/ashokdey) | [https://ashokdey.in](https://ashokdey.in) | +| [Ashu Deshwal](https://github.com/TheSTL) | [\_TheSTL\_](https://twitter.com/_TheSTL_) | - | - | + +[Detailed list of contributors](https://github.com/knaxus/problem-solving-javascript/graphs/contributors) ## Contribution Guide From 2060a13f3f48df1f1f3197be02f905c0c2ca84a3 Mon Sep 17 00:00:00 2001 From: Ashok Dey Date: Sat, 30 Nov 2019 16:41:06 +0530 Subject: [PATCH 08/13] update: delete key of hash table --- src/_DataStructures_/HashTable/index.js | 58 +++++++++++++++++++------ 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/src/_DataStructures_/HashTable/index.js b/src/_DataStructures_/HashTable/index.js index 5fd8cb71..13c4cfb0 100644 --- a/src/_DataStructures_/HashTable/index.js +++ b/src/_DataStructures_/HashTable/index.js @@ -129,6 +129,34 @@ class HashTable { return this._values(index, key); } + delete(key) { + // get the index + // eslint-disable-next-line no-underscore-dangle + const index = this._hash(key); + + // get the SLL using the index + let head = this.bucket[index]; + + // return null if the head is null + if (!head) { + return null; + } + + // get all the values for the key to return + // eslint-disable-next-line no-underscore-dangle + const vals = this._values(index, key); + + while (head !== null) { + if (head.key === key) { + // we have to delete current node + head = head.next; + } + } + // update the index with the lastest head value + this.bucket[index] = head; + return vals; + } + getSize() { return this.size; } @@ -138,18 +166,22 @@ class HashTable { } } -const ht = new HashTable(5); -console.log('HT slots = ', ht.slot); -ht.set('maroon', 'I maroon'); -ht.set('hello', 'I am a new value'); -console.log(ht.bucket); -ht.set('hell', 'Bad value'); -ht.set('hello', 'I am a yet another value'); -console.log('HT slots = ', ht.slot); -ht.set('yellow', 'I am yellow'); - -// console.log(ht.get('hello')); -// console.log(ht.get('maroon')); -console.log(ht.bucket); +// const ht = new HashTable(5); +// console.log('HT slots = ', ht.slot); +// ht.set('maroon', 'I maroon'); +// ht.set('hello', 'I am a new value'); +// console.log(ht.bucket); +// ht.set('hell', 'Bad value'); +// ht.set('hello', 'I am a yet another value'); +// console.log('HT slots = ', ht.slot); +// ht.set('yellow', 'I am yellow'); + +// // console.log(ht.get('hello')); +// // console.log(ht.get('maroon')); +// console.log(ht.bucket); + +// console.log('deleting hello........'); +// ht.delete('hello'); +// console.log(ht.bucket); module.exports = HashTable; From 3a09feff9d0fc243e506f55436e65d7ceefd70cb Mon Sep 17 00:00:00 2001 From: Ashok Dey Date: Sat, 30 Nov 2019 16:42:21 +0530 Subject: [PATCH 09/13] fix: renamed to remove() --- src/_DataStructures_/HashTable/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_DataStructures_/HashTable/index.js b/src/_DataStructures_/HashTable/index.js index 13c4cfb0..4899bf17 100644 --- a/src/_DataStructures_/HashTable/index.js +++ b/src/_DataStructures_/HashTable/index.js @@ -129,7 +129,7 @@ class HashTable { return this._values(index, key); } - delete(key) { + remove(key) { // get the index // eslint-disable-next-line no-underscore-dangle const index = this._hash(key); From 02fec4fbf2525fad3b387b0d21f84316c61fd4dc Mon Sep 17 00:00:00 2001 From: Ashok Dey Date: Sat, 30 Nov 2019 16:55:58 +0530 Subject: [PATCH 10/13] update: options added to refect corner case testing --- src/_DataStructures_/HashTable/index.js | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/_DataStructures_/HashTable/index.js b/src/_DataStructures_/HashTable/index.js index 4899bf17..78586a01 100644 --- a/src/_DataStructures_/HashTable/index.js +++ b/src/_DataStructures_/HashTable/index.js @@ -1,7 +1,7 @@ const HashEntry = require('./HashEntry'); class HashTable { - constructor(slots) { + constructor(slots, { allowResize = true, strongHash = true, custonHash = null }) { // init with a default set of slots this.slot = slots || 19; // size to hold the current size @@ -11,6 +11,11 @@ class HashTable { this.threshold = 0.7; // the main bucket this.bucket = new Array(this.slot); + this.allowResize = allowResize; + this.strongHash = strongHash; + if (custonHash) { + this._hash = custonHash; + } // fill the bucket with null for (let i = 0; i < this.slot; i += 1) this.bucket[i] = null; @@ -31,7 +36,9 @@ class HashTable { const char = stringKey[i]; const value = char.charCodeAt(0) - 96; index = (index * PRIME_MULTIPLIER + value) % this.bucket.length; - index = (index + PRIME_ADDER) % this.bucket.length; + if (this.strongHash) { + index = (index + PRIME_ADDER) % this.bucket.length; + } } return index; } @@ -113,7 +120,7 @@ class HashTable { * resize the hash table */ const loadFactor = Number((this.size / this.slot).toFixed(1)); - if (loadFactor > this.threshold) { + if (loadFactor > this.threshold && this.allowResize) { // console.log('Resizing hash table'); // eslint-disable-next-line no-underscore-dangle this._resize(); @@ -146,15 +153,17 @@ class HashTable { // eslint-disable-next-line no-underscore-dangle const vals = this._values(index, key); + let newHead = null; // to hold the start of the new SLL while (head !== null) { if (head.key === key) { // we have to delete current node - head = head.next; + newHead = head.next; } + head = head.next; } // update the index with the lastest head value - this.bucket[index] = head; - return vals; + this.bucket[index] = newHead; + return { key: vals }; } getSize() { @@ -181,7 +190,7 @@ class HashTable { // console.log(ht.bucket); // console.log('deleting hello........'); -// ht.delete('hello'); +// console.log(ht.remove('hello')); // console.log(ht.bucket); module.exports = HashTable; From 3c45b0b983cc53865405f6c9c0400050e667dc70 Mon Sep 17 00:00:00 2001 From: Ashok Dey Date: Sat, 30 Nov 2019 19:10:08 +0530 Subject: [PATCH 11/13] update: implementation of remove() --- src/_DataStructures_/HashTable/index.js | 39 +++++++++++++++++-------- 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/src/_DataStructures_/HashTable/index.js b/src/_DataStructures_/HashTable/index.js index 78586a01..6894e07d 100644 --- a/src/_DataStructures_/HashTable/index.js +++ b/src/_DataStructures_/HashTable/index.js @@ -14,6 +14,7 @@ class HashTable { this.allowResize = allowResize; this.strongHash = strongHash; if (custonHash) { + // eslint-disable-next-line no-underscore-dangle this._hash = custonHash; } @@ -108,6 +109,21 @@ class HashTable { return res; } + // eslint-disable-next-line class-methods-use-this + _convertNodesToSLL(nodeCollection) { + // convert collection of nodes into a SLL + let head = nodeCollection[0]; + const start = head; + let i = 1; + while (i < nodeCollection.length) { + head.next = nodeCollection[i]; + i += 1; + head = head.next; + } + + return start; + } + set(key, value) { // eslint-disable-next-line no-underscore-dangle const index = this._hash(key); @@ -143,7 +159,6 @@ class HashTable { // get the SLL using the index let head = this.bucket[index]; - // return null if the head is null if (!head) { return null; @@ -152,17 +167,19 @@ class HashTable { // get all the values for the key to return // eslint-disable-next-line no-underscore-dangle const vals = this._values(index, key); - - let newHead = null; // to hold the start of the new SLL + const nodes = []; while (head !== null) { - if (head.key === key) { - // we have to delete current node - newHead = head.next; + if (head.key !== key) { + nodes.push(new HashEntry({ key: head.key, value: head.value })); } head = head.next; } + + // eslint-disable-next-line no-underscore-dangle + const sll = this._convertNodesToSLL(nodes); + + this.bucket[index] = sll; // update the index with the lastest head value - this.bucket[index] = newHead; return { key: vals }; } @@ -171,18 +188,16 @@ class HashTable { } isEmpty() { - return this.getSize() === 0; + return this.size === 0; } } -// const ht = new HashTable(5); -// console.log('HT slots = ', ht.slot); +// const ht = new HashTable(5, { allowResize: false, strongHash: false }); // ht.set('maroon', 'I maroon'); // ht.set('hello', 'I am a new value'); -// console.log(ht.bucket); +// // console.log(ht.bucket); // ht.set('hell', 'Bad value'); // ht.set('hello', 'I am a yet another value'); -// console.log('HT slots = ', ht.slot); // ht.set('yellow', 'I am yellow'); // // console.log(ht.get('hello')); From cffd6e2483b3e43040fc3f978966fb79145fa26b Mon Sep 17 00:00:00 2001 From: Ashok Dey Date: Sat, 30 Nov 2019 21:28:30 +0530 Subject: [PATCH 12/13] update: remove() logic change --- src/_DataStructures_/HashTable/index.js | 37 +++++++++++++++---------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/src/_DataStructures_/HashTable/index.js b/src/_DataStructures_/HashTable/index.js index 6894e07d..3a454ec4 100644 --- a/src/_DataStructures_/HashTable/index.js +++ b/src/_DataStructures_/HashTable/index.js @@ -164,23 +164,29 @@ class HashTable { return null; } - // get all the values for the key to return - // eslint-disable-next-line no-underscore-dangle - const vals = this._values(index, key); - const nodes = []; + if (head.key === key) { + let node = head; + this.bucket[index] = head.next; + const val = { key, value: node.value }; + node = null; + this.size -= 1; + return val; + } + + let previous = null; + while (head !== null) { - if (head.key !== key) { - nodes.push(new HashEntry({ key: head.key, value: head.value })); + if (head.key === key) { + let node = head; + previous.next = head.next; + this.size -= 1; + const res = { key, value: node.value }; + node = null; + return res; } + previous = head; head = head.next; } - - // eslint-disable-next-line no-underscore-dangle - const sll = this._convertNodesToSLL(nodes); - - this.bucket[index] = sll; - // update the index with the lastest head value - return { key: vals }; } getSize() { @@ -197,7 +203,7 @@ class HashTable { // ht.set('hello', 'I am a new value'); // // console.log(ht.bucket); // ht.set('hell', 'Bad value'); -// ht.set('hello', 'I am a yet another value'); +// // ht.set('hello', 'I am a yet another value'); // ht.set('yellow', 'I am yellow'); // // console.log(ht.get('hello')); @@ -208,4 +214,7 @@ class HashTable { // console.log(ht.remove('hello')); // console.log(ht.bucket); +// console.log(ht.remove('yellow')); +// console.log(ht.bucket); + module.exports = HashTable; From ea7853e04787c80c20252eb0e78787570291c7b4 Mon Sep 17 00:00:00 2001 From: Ashok Dey Date: Mon, 2 Dec 2019 01:07:21 +0530 Subject: [PATCH 13/13] update: override the value for same key --- src/_DataStructures_/HashTable/index.js | 29 +++++++++++++++---------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/_DataStructures_/HashTable/index.js b/src/_DataStructures_/HashTable/index.js index 3a454ec4..0b1f543d 100644 --- a/src/_DataStructures_/HashTable/index.js +++ b/src/_DataStructures_/HashTable/index.js @@ -84,29 +84,33 @@ class HashTable { } let head = this.bucket[index]; + // extract the key and see if it already exists + const { key, value: newValue } = value; // traverse to the end while (head.next !== null) { + if (head.key === key) { + // overridet the value with the new value + head.value = newValue; + return index; + } head = head.next; } + // if the key was not found head.next = node; this.size += 1; return index; } - _values(index, key) { - /** - * Utility to return the values as an array for a given key - */ - const res = []; + _value(index, key) { let head = this.bucket[index]; while (head !== null) { if (head.key === key) { - res.push(head.value); + return head.value; } head = head.next; } - return res; + return null; } // eslint-disable-next-line class-methods-use-this @@ -149,7 +153,7 @@ class HashTable { const index = this._hash(key); if (!this.bucket[index]) return null; // eslint-disable-next-line no-underscore-dangle - return this._values(index, key); + return this._value(index, key); } remove(key) { @@ -187,6 +191,7 @@ class HashTable { previous = head; head = head.next; } + return null; } getSize() { @@ -201,13 +206,13 @@ class HashTable { // const ht = new HashTable(5, { allowResize: false, strongHash: false }); // ht.set('maroon', 'I maroon'); // ht.set('hello', 'I am a new value'); -// // console.log(ht.bucket); +// console.log(ht.bucket); // ht.set('hell', 'Bad value'); -// // ht.set('hello', 'I am a yet another value'); +// ht.set('hello', 'I am a yet another value'); // ht.set('yellow', 'I am yellow'); -// // console.log(ht.get('hello')); -// // console.log(ht.get('maroon')); +// console.log(ht.get('hello')); +// console.log(ht.get('maroon')); // console.log(ht.bucket); // console.log('deleting hello........');