- What is a Hash Tables?
- Why Hash Tables?
- How Hash Tables Work?
- What is a Hash Function?
- Hash Tables with Big O Notation
- Implementing Hash Tables
What is a Hash Tables?
Hash Tables, Hashes, Maps, Unordered Maps or Objects, There are many names to call This Data Structure.
In JavaScript, Objects are a type of a Hash Table
Hash Tables don't maintain order, like Arrays.
Why Hash Tables?
Imagine that we want to store the number of active Users in a particular app.
Doing this in Arrays is not the cleanest way.
So we need Hash Tables or Objects to do so
const users = { activeUsers: 1000, };
How Hash Tables Work?
In Hash Tables we use keys and values.
keys instead of indexes to find the data in memory.
To make this happen we need a Hash Function.
First, We pass the key to the Hash Function
Then, the Hash Function will generate a hashed output to store the data in the memory.
What is a Hash Function?
A function that coverts inputs of any length into a fixed size string using a mathematical equation.
The output of a hash function has to be unique.
And the same input should always produce the same hashed output.
And there are many types of Hash Functions such as MD2, CRC23, SHA-1, ... and more.
You can try it here
Example of a simple Hash Function
function hashFunction(key) { let hash = 0; for (let i = 0; i < key.length; i++) { hash = hash + key.charCodeAt(i); } return hash; } // Giving it the string "Hello" console.log(hashFunction("Hello")); // 500 console.log(hashFunction("Hello")); // 500 console.log(hashFunction("Hello")); // 500 // Giving it the string "hello" console.log(hashFunction("hello")); // 532 console.log(hashFunction("hello")); // 532 console.log(hashFunction("hello")); // 532
Hash Tables with Big O Notation
- Access => O(1) || O(n). - Insert => O(1). - Delete => O(1).
Later in the article we will know why Accessing might be O(n).
Example
const user = { firstName: "Youssef", lastName: "Zidan", }; // Access // O(1) console.log(user.firstName); // "Youssef" // Insert // O(1) user.job = "Web Developer"; console.log(user.job); // "Web Developer" // Delete O(1) delete user.lastName; console.log(user.lastName); // undefined
Implementing Hash Tables
In order to really understand Big O with Hash Tables, we are going to Implement one.
class HashTable { constructor(size) { this.data = new Array(size); } // hash function _hash(key) { let hash = 0; for (let i = 0; i < key.length; i++) { hash = (hash + key.charCodeAt(i) * i) % this.data.length; } return hash; } // O(1) set(key, value) { let address = this._hash(key); if (!this.data[address]) { this.data[address] = []; // O(1) this.data[address].push([key, value]); // O(1) } else { this.data[address].push([key, value]); // O(1) } } // O(1) || O(n) get(key) { let address = this._hash(key); // O(1) let current = this.data[address]; // O(1) if (current) { for (let i = 0; i < current.length; i++) { // O(n) // O(1) if current.length === 1 // or the ele is found in the first index if (current[i][0] === key) { return current[i][1]; } } } else { // O(1) return undefined; } } keys() { if (!this.data.length) { return undefined; } const keys = []; for (let i = 0; i < this.data.length; i++) { if (this.data[i]) { if (this.data[i].length === 1) { keys.push(this.data[i][0][0]); } if (this.data[i].length > 1) { for (let j = 0; j < this.data[i].length; j++) { keys.push(this.data[i][j][0]); } } } } return keys; } }
Breaking Down
hash function
_hash(key) { let hash = 0; for (let i = 0; i < key.length; i++) { hash = (hash + key.charCodeAt(i) * i) % this.data.length; } return hash; }
Using this specific algorithm to determine that the created element will not exceed the length of the Hash Table.
set
set(key, value) { let address = this._hash(key); if (!this.data[address]) { this.data[address] = []; // O(1) this.data[address].push([key, value]); // O(1) } else { this.data[address].push([key, value]); // O(1) } }
- Getting the address using the hash function.
- If the generated address doesn't exist in
this.data
object, Create an empty array of this address. - Push the key and the value passed inside another array to the created empty array.
- If there is no data in this particular address just push an array contains the key and value.
get
get(key) { let address = this._hash(key); // O(1) let current = this.data[address]; // O(1) if (current) { for (let i = 0; i < current.length; i++) { // O(n) or // O(1) if current.length === 1 // or the ele is found in the first index if (current[i][0] === key) { return current[i][1]; } } } else { // O(1) return undefined; } }
- Getting the address using the hash function.
- Getting the current value of the generated address.
- Checking if there is a value in this current position.
- Looping through the current array.
- Check for they key
current[i][0]
if it's equal the passed key and return the valuecurrent[i][1]
. - Return undefined if there is no current address found.
keys
keys() { if (!this.data.length) { return undefined; } const keys = []; for (let i = 0; i < this.data.length; i++) { if (this.data[i]) { if (this.data[i].length === 1) { keys.push(this.data[i][0][0]); } if (this.data[i].length > 1) { for (let j = 0; j < this.data[i].length; j++) { keys.push(this.data[i][j][0]); } } } } return keys; }
- Checking for the length of the Hash Table and return
undefined
if there is no data. - Creating an empty keys array.
- Checking if the current element has a value.
- Checking if the length of this array element is 1 O(1) so we will push the key which will be
this.data[i][0][0]
- If the length is greater than 1 O(n), then this position has more than one array so we also loop through it and return the keys inside
this.data[i][j][0]
.
Example
const ht = new HashTable(10); ht.set("a", 1); ht.set("b", 2); ht.set("c", 3); ht.set("d", 4); ht.set("e", 5); ht.set("f", 6); ht.set("g", 7); ht.set("h", 8); ht.set("i", 9); ht.set("j", 10); console.log(ht); /* 0: Array[10] 0: Array[2] 0: "a" 1: 1 1: Array[2] 2: Array[2] 3: Array[2] 4: Array[2] 5: Array[2] 6: Array[2] 7: Array[2] 8: Array[2] 9: Array[2] 1: undefined 2: undefined 3: undefined 4: undefined 5: undefined 6: undefined 7: undefined 8: undefined 9: undefined */ console.log(ht.get("g")); // 7 console.log(ht.keys()); // ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]
Top comments (0)