-
-
Notifications
You must be signed in to change notification settings - Fork 5.8k
[DEV] Implementation of Hash Table Data Structure #1627
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
1fdf350
4452716
0089b70
40dbe92
d05deeb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| export default class HashTable { | ||
| constructor(limit = 100) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 100 seems very arbitrary. I'd force the user to choose for a fixed-size hash table. (I'd also make it clear that this is a fixed-size hash table (with dynamically grown buckets) as opposed to a dynamic hash table. In particular, a fixed-size hash table can't guarantee expected O(1) operations.)
|
||
| this.storage = new Array(limit) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be helpful to call this property |
||
| this.limit = limit | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This field is redundant with |
||
| } | ||
|
|
||
| _hash(key, max) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use the |
||
| let hash = 0 | ||
| for (let i = 0; i < key.length; i++) hash += key.charCodeAt(i) | ||
| return hash % max | ||
| } | ||
|
|
||
| set(key, value) { | ||
| const index = this._hash(key, this.limit) | ||
| if (this.storage[index] === undefined) this.storage[index] = [[key, value]] | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use an object |
||
| else { | ||
| let inserted = false | ||
| for (let i = 0; i < this.storage[index].length; i++) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use a |
||
| if (this.storage[index][i][0] === key) { | ||
| this.storage[index][i][1] = value | ||
| inserted = true | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just early |
||
| } | ||
| } | ||
| if (inserted === false) this.storage[index].push([key, value]) | ||
| } | ||
| } | ||
|
|
||
| // Get a value from the hash table | ||
| get(key) { | ||
| const index = this._hash(key, this.limit) | ||
| if (this.storage[index] === undefined) return undefined | ||
| else { | ||
| for (let i = 0; i < this.storage[index].length; i++) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use a |
||
| if (this.storage[index][i][0] === key) return this.storage[index][i][1] | ||
| } | ||
| } | ||
| } | ||
|
|
||
| remove(key) { | ||
| const index = this._hash(key, this.limit) | ||
| if (this.storage[index]) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd use an early return here: |
||
| if ( | ||
| this.storage[index].length === 1 && | ||
| this.storage[index][0][0] === key | ||
| ) { | ||
| delete this.storage[index] | ||
| } else { | ||
| for (let i = 0; i < this.storage[index].length; i++) { | ||
| if (this.storage[index][i][0] === key) delete this.storage[index][i] | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You're creating an array with holes here. I think this is rather dirty; it results in suboptimal time complexities (deleted items negatively affecting the time it takes to search a bucket). It would be cleaner to just take an entry from the end, swap the entry to be deleted with that, then pop the entry from the end. |
||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| has(key) { | ||
| const index = this._hash(key, this.limit) | ||
| if (this.storage[index]) { | ||
| for (let i = 0; i < this.storage[index].length; i++) { | ||
| if (this.storage[index][i][0] === key) return true | ||
| } | ||
| } | ||
| return false | ||
| } | ||
|
|
||
| printTable() { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think "print" helpers are good design. A debugger, or even just A better abstraction would be an "entries"-like method to iterate over all the key-value-pairs. |
||
| for (let i = 0; i < this.storage.length; i++) { | ||
| if (this.storage[i] !== undefined) | ||
| console.log(`Bucket ${i}: ${JSON.stringify(this.storage[i])}`) | ||
| else console.log(`Bucket ${i} Empty`) | ||
| } | ||
| } | ||
|
|
||
| clear() { | ||
| this.storage = new Array(this.limit) | ||
| } | ||
| } | ||