A Quick Overview of Hash Tables
Let's combine the different operations discussed previously and test out the functionality of our complete hash table class.
We'll cover the following...
Complete Implementation
Below, you can find the complete hash table class.
Press + to interact
class HashEntry {constructor(key, data) {this.key = key;// data to be storedthis.value = data;// reference to new entrythis.next = null;}}class HashTable {//Constructorconstructor() {//Size of the HashTablethis.slots = 10;//Current entries in the table//Used while resizing the table when half of the table gets filledthis.size = 0;//Array of HashEntry objects (by deafult all null)this.bucket = [];for (var i = 0; i < this.slots; i++) {this.bucket[i] = null;}this.threshold = 0.6}//Helper Functionsget_size() {return this.size;}//Hash FunctiongetIndex(key) {let index = key % this.slots;return index;}isEmpty() {return this.get_size() == 0;}insert(key, value) {//Find the node with the given keylet b_Index = this.getIndex(key);if (this.bucket[b_Index] == null) {this.bucket[b_Index] = new HashEntry(key, value);console.log(String(key) + ", " + String(value) + " - inserted.")} else {let head = this.bucket[b_Index];while (head != null) {if (head.key == key) {head.value = value;break;} else if (head.next == null) {head.next = new HashEntry(key, value);console.log(String(key) + ", " + String(value) + " - inserted.");break;}head = head.next;}}this.size += 1;let load_factor = Number(this.size) / Number(this.slots);//Checks if 60% of the entries in table are filled, threshold = 0.6if (load_factor >= this.threshold) {this.resize();}}//Return a value for a given keysearch(key) {//Find the node with the given keylet b_Index = this.getIndex(key);let head = this.bucket[b_Index]//Search key in the slotsif (head != null) {while (head != null) {if (head.key == key) {return head.value;}head = head.next}}//If key not foundconsole.log("Key not found");return null;}//Remove a value based on a keydeleteVal(key) {//Find indexlet b_Index = this.getIndex(key);let head = this.bucket[b_Index];//If key exists at first slotif (head.key == key) {this.bucket[b_Index] = head.next;console.log("Key deleted");this.size -= 1;return this;}//Find the key in slotslet prev = null;while (head != null) {//If key existsif (head.key == key) {prev.next = head.next;console.log("Key deleted");this.size -= 1;return this;}//Else keep moving in chainprev = head;head = head.next;}//If key does not existconsole.log("Key not found");return null;}resize() {let new_slots = this.slots * 2;let new_bucket = [];for (var n = 0; n < new_slots; n++) {new_bucket[n] = null;}this.slots = new_slots;// rehash all items into new slotsfor (var i = 0; i < this.bucket.length; i++) {let head = this.bucket[i];while (head != null) {let new_index = this.getIndex(head.key);if (new_bucket[new_index] == null) {new_bucket[new_index] = new HashEntry(head.key, head.value);} else {let node = new_bucket[new_index];while (node != null) {if (node.key == head.key) {node.value = head.value;node = null;} else if (node.next == null) {node.next = new HashEntry(head.key, head.value);node = null;} else {node = node.next;}}}head = head.next}}this.bucket = new_bucket;}}let table = new HashTable(); //Create a HashTableconsole.log(table.isEmpty());table.insert("This", 1);table.insert("is", 2)table.insert("a", 3)table.insert("Test", 4)table.insert("Driver", 5)console.log("Table Size: " + String(table.get_size()));console.log("The value for 'is' key: " + String(table.search("is")));table.deleteVal("is");table.deleteVal("a");console.log("Table Size: " + String(table.get_size()));
Summing Up
To sum up the discussion here, hash tables are the ideal ...