#include<iostream>
#include<cstring>
using namespace std;
template<typename T>
class node{
public:
string key;
T value;
node<T>*next;
node(string key, T val){
this->key = key;
value = val;
next = NULL;
}
~node(){
if(next!=NULL){
delete next;
}
}
};
template<typename T>
class HashTable{
node<T>** table; //pointer to an array of pointers
int current_size;
int table_size;
int hashfn(string key){
int idx = 0;
int p=1;
for(int j=0;j<key.length();j++){
idx = idx + (key[j]*p)%table_size;
idx = idx%table_size;
p = (p*27)%table_size;
}
return idx;
}
void rehash(){
node<T>** oldTable = table;
int oldTableSize = table_size;
table_size = 2*table_size;
table = new node<T>*[table_size];
//initialize new table buckets with null
//now oldtable has data and new table is null
for(int i=0;i<table_size;i++){
table[i] = NULL;
}
current_size = 0;
//shift data from old table to new table
for(int i=0;i<oldTableSize;i++){
node<T>*temp = oldTable[i];
while(temp!=NULL){
insert(temp->key,temp->value);
temp = temp->next;
}
//delete this entire row from oldtable
if(oldTable[i]!=NULL){
delete oldTable[i];
}
}
delete [] oldTable;
}
public:
HashTable(int ts = 7){
table_size = ts;
table = new node<T>*[table_size];
current_size = 0;
for(int i=0;i<table_size;i++){
table[i] = NULL;
}
}
void insert(string key , T value){
int idx = hashfn(key);
node<T>*n = new node<T>(key,value);
//insert at head of linkedlist with id=idx
n->next = table[idx];
table[idx]=n;
current_size++;
//rehash
float load_factor = current_size/(1.0*table_size);
if(load_factor>0.7){
rehash();
}
}
void print (){
for(int i=0;i<table_size;i++){
cout<<"bucket"<<i<<"->";
node<T>*temp = table[i];
while(temp!=NULL){
cout<<temp->key<<"->";
temp=temp->next;
}
cout<<endl;
}
}
T* Search(string key){
int idx = hashfn(key);
node<T>*temp = table[idx];
while(temp!=NULL){
if(temp->key == key){
return &temp->value;
}
temp = temp->next;
}
return NULL;
}
void Erase(string key){
int idx = hashfn(key);
node<T>*temp = table[idx];
node<T>*prev = NULL;
while(temp->next!=NULL){
if(temp->next->key == key){
prev = temp;
prev->next = temp->next->next;
delete temp->next;
}
temp = temp->next;
}
return;
}
};
int main(){
HashTable<int>price_menu;
price_menu.insert("burger",120);
price_menu.insert("pepsi",80);
price_menu.insert("burgerpizza",90);
price_menu.insert("noodles",150);
price_menu.insert("coke",50);
price_menu.print();
int *price = price_menu.Search("noodles");
if(price!=NULL){
cout<<"found "<<*price;
}
else{
cout<<"not found";
}
price_menu.Erase("noodles");
price_menu.print();
return 0;}