Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 094e1ba

Browse files
authored
Merge pull request knaxus#160 from knaxus/hash-table
added Hash Table
2 parents a47787d + ea7853e commit 094e1ba

File tree

5 files changed

+246
-2
lines changed

5 files changed

+246
-2
lines changed

‎README.md‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,15 @@ This repo contains the following sections implemented in **JavaScript**
2626

2727
Find the detailed contents and problem list here: [Table Of Contents](TOC.md)
2828

29+
## Contributors
30+
31+
| Name | Twitter | LinkedIn | Website |
32+
| ----------------------------------------- | ------------------------------------------- | --------------------------------------------- | ------------------------------------------ |
33+
| [Ashok Dey](https://github.com/ashokdey) | [ashokdey\_](https://twitter.com/ashokdey_) | [Ashok Dey](https://linkedin.com/in/ashokdey) | [https://ashokdey.in](https://ashokdey.in) |
34+
| [Ashu Deshwal](https://github.com/TheSTL) | [\_TheSTL\_](https://twitter.com/_TheSTL_) | - | - |
35+
36+
[Detailed list of contributors](https://github.com/knaxus/problem-solving-javascript/graphs/contributors)
37+
2938
## Contribution Guide
3039

3140
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)

‎TOC.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
- Problems
5050
- [K Largest Elements](src/_DataStructures_/Heaps/k-largest-in-array)
5151
- [K Smallest Elements](src/_DataStructures_/Heaps/k-smallest-in-array)
52+
- [Hash Table](src/_DataStructures_/HashTable)
5253

5354
### Logical Problems
5455

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
class HashEntry {
2+
constructor({ key, value }) {
3+
this.key = key;
4+
this.value = value;
5+
this.next = null;
6+
}
7+
}
8+
9+
module.exports = HashEntry;
Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
const HashEntry = require('./HashEntry');
2+
3+
class HashTable {
4+
constructor(slots, { allowResize = true, strongHash = true, custonHash = null }) {
5+
// init with a default set of slots
6+
this.slot = slots || 19;
7+
// size to hold the current size
8+
// and help to resize when the table is half filled
9+
this.size = 0;
10+
// threshold (let it be 70%)
11+
this.threshold = 0.7;
12+
// the main bucket
13+
this.bucket = new Array(this.slot);
14+
this.allowResize = allowResize;
15+
this.strongHash = strongHash;
16+
if (custonHash) {
17+
// eslint-disable-next-line no-underscore-dangle
18+
this._hash = custonHash;
19+
}
20+
21+
// fill the bucket with null
22+
for (let i = 0; i < this.slot; i += 1) this.bucket[i] = null;
23+
}
24+
25+
_hash(key) {
26+
// convert the key to String;
27+
const stringKey = String(key);
28+
29+
let index = 0;
30+
const PRIME_MULTIPLIER = 1801; // Random prime number
31+
const PRIME_ADDER = 2029; // Random prime number
32+
33+
// loop till the length of the key or max 100
34+
const loopTill = Math.min(stringKey.length, 100);
35+
36+
for (let i = 0; i < loopTill; i += 1) {
37+
const char = stringKey[i];
38+
const value = char.charCodeAt(0) - 96;
39+
index = (index * PRIME_MULTIPLIER + value) % this.bucket.length;
40+
if (this.strongHash) {
41+
index = (index + PRIME_ADDER) % this.bucket.length;
42+
}
43+
}
44+
return index;
45+
}
46+
47+
_resize() {
48+
const oldSlot = this.slot;
49+
const oldBucket = this.bucket;
50+
51+
this.slot = oldSlot * 2;
52+
const newBucket = new Array(this.slot);
53+
// fill the new bucket with nulls
54+
for (let i = 0; i < this.slot; i += 1) newBucket[i] = null;
55+
56+
this.bucket = newBucket;
57+
58+
for (let i = 0; i < oldSlot; i += 1) {
59+
if (oldBucket[i]) {
60+
let head = oldBucket[i];
61+
62+
while (head !== null) {
63+
const { key, value } = head;
64+
// eslint-disable-next-line no-underscore-dangle
65+
const newIndex = this._hash(key);
66+
// eslint-disable-next-line no-underscore-dangle
67+
this._push(newIndex, { key, value });
68+
head = head.next;
69+
}
70+
}
71+
}
72+
}
73+
74+
_push(index, value) {
75+
/**
76+
* Utility to add a SLL to the index in case of more than one
77+
* key hashes to the same index
78+
*/
79+
const node = new HashEntry(value);
80+
if (!this.bucket[index]) {
81+
this.bucket[index] = node;
82+
this.size += 1;
83+
return index;
84+
}
85+
86+
let head = this.bucket[index];
87+
// extract the key and see if it already exists
88+
const { key, value: newValue } = value;
89+
90+
// traverse to the end
91+
while (head.next !== null) {
92+
if (head.key === key) {
93+
// overridet the value with the new value
94+
head.value = newValue;
95+
return index;
96+
}
97+
head = head.next;
98+
}
99+
// if the key was not found
100+
head.next = node;
101+
this.size += 1;
102+
return index;
103+
}
104+
105+
_value(index, key) {
106+
let head = this.bucket[index];
107+
while (head !== null) {
108+
if (head.key === key) {
109+
return head.value;
110+
}
111+
head = head.next;
112+
}
113+
return null;
114+
}
115+
116+
// eslint-disable-next-line class-methods-use-this
117+
_convertNodesToSLL(nodeCollection) {
118+
// convert collection of nodes into a SLL
119+
let head = nodeCollection[0];
120+
const start = head;
121+
let i = 1;
122+
while (i < nodeCollection.length) {
123+
head.next = nodeCollection[i];
124+
i += 1;
125+
head = head.next;
126+
}
127+
128+
return start;
129+
}
130+
131+
set(key, value) {
132+
// eslint-disable-next-line no-underscore-dangle
133+
const index = this._hash(key);
134+
// storing value as an key-value pair
135+
// eslint-disable-next-line no-underscore-dangle
136+
this._push(index, { key, value });
137+
138+
/**
139+
* calculate the load factor, if it's greater than threshold
140+
* resize the hash table
141+
*/
142+
const loadFactor = Number((this.size / this.slot).toFixed(1));
143+
if (loadFactor > this.threshold && this.allowResize) {
144+
// console.log('Resizing hash table');
145+
// eslint-disable-next-line no-underscore-dangle
146+
this._resize();
147+
}
148+
}
149+
150+
get(key) {
151+
// get the index for the given key
152+
// eslint-disable-next-line no-underscore-dangle
153+
const index = this._hash(key);
154+
if (!this.bucket[index]) return null;
155+
// eslint-disable-next-line no-underscore-dangle
156+
return this._value(index, key);
157+
}
158+
159+
remove(key) {
160+
// get the index
161+
// eslint-disable-next-line no-underscore-dangle
162+
const index = this._hash(key);
163+
164+
// get the SLL using the index
165+
let head = this.bucket[index];
166+
// return null if the head is null
167+
if (!head) {
168+
return null;
169+
}
170+
171+
if (head.key === key) {
172+
let node = head;
173+
this.bucket[index] = head.next;
174+
const val = { key, value: node.value };
175+
node = null;
176+
this.size -= 1;
177+
return val;
178+
}
179+
180+
let previous = null;
181+
182+
while (head !== null) {
183+
if (head.key === key) {
184+
let node = head;
185+
previous.next = head.next;
186+
this.size -= 1;
187+
const res = { key, value: node.value };
188+
node = null;
189+
return res;
190+
}
191+
previous = head;
192+
head = head.next;
193+
}
194+
return null;
195+
}
196+
197+
getSize() {
198+
return this.size;
199+
}
200+
201+
isEmpty() {
202+
return this.size === 0;
203+
}
204+
}
205+
206+
// const ht = new HashTable(5, { allowResize: false, strongHash: false });
207+
// ht.set('maroon', 'I maroon');
208+
// ht.set('hello', 'I am a new value');
209+
// console.log(ht.bucket);
210+
// ht.set('hell', 'Bad value');
211+
// ht.set('hello', 'I am a yet another value');
212+
// ht.set('yellow', 'I am yellow');
213+
214+
// console.log(ht.get('hello'));
215+
// console.log(ht.get('maroon'));
216+
// console.log(ht.bucket);
217+
218+
// console.log('deleting hello........');
219+
// console.log(ht.remove('hello'));
220+
// console.log(ht.bucket);
221+
222+
// console.log(ht.remove('yellow'));
223+
// console.log(ht.bucket);
224+
225+
module.exports = HashTable;

‎src/_DataStructures_/LinkedList/index.js‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
// do not change the node class, you never know how many things it caan break! :)
1+
// do not change the node class, you never know how many things it caan break! :)
22
class Node {
33
constructor(data, next) {
44
this.data = data;
5-
this.next = next;
5+
this.next = next||null;
66
}
77
}
88

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /