字典在不少高級語言裏都有,好比java
可是大家知道字典是怎麼實現的嗎?本文來實現一個簡單的字典。python
先來看python的字典是怎樣的ios
d = {} d["name"]="biningo" d["age"] = "19" name = d.get("name") age = d.get("age")
參考了Redis的字典結構。字典在redis底層應用很是廣泛。由於redis是一個K-V數據庫c++
這裏只是實現了string類型的字典,鍵值都是stringredis
用一個Hash Table來存放鍵值,線性探測法解決衝突【redis是用拉鍊法】數據庫
dictEntry:存放K-V的結構體數組
struct dictEntry{ string key; string val; };
dict:字典,裏面有一個Hash Tablespa
//字典 無序 struct dict{ dictEntry** table; //哈希表數組 int size; //哈希表大小 int len; //鍵值對計數器 };
根據string來計算Hash Codecode
//計算str的哈希值 參照java hashCode int hash(string s){ int h = 0; for(int i=0;i<s.length();i++){ h = 31 * h + (s[i] & 0xff); } return h; }
建立空字典對象
dict* dictCreate(int size){ dict* d = (dict*)malloc(sizeof(dict)); d->table = (dictEntry**)calloc(size,sizeof(dictEntry*)); //這裏要注意了 for(int i=0;i<size;i++) d->table[i] = NULL; d->size = size;//size看成負載因子 d->len=0; return d; }
Get、Set
void set(dict* d,string key,string val){ if(d->size==d->len){ cout<<"哈希表滿了"<<endl; return; } int index = hash(key)%d->size; while(d->table[index]!=NULL){ index = (index+1)%d->size; } d->table[index] = (dictEntry*)malloc(sizeof(dictEntry)); //先開闢空間 d->table[index]->val = val; d->table[index]->key = key; d->len++; return; } string get(dict* d,string key){ if(d->len==0){ cout<<"哈希表空的"<<endl; return ""; } int index = hash(key)%d->size; int c=1; while( c<d->size){ if(d->table[index] && d->table[index]->key==key) break; index = (index+1)%d->size; c++; } if(c<d->size){ d->len--; return d->table[index]->val; } else{ cout<<"找不到元素"<<endl; return ""; } }
刪除鍵值
//根據鍵查找哈希表的索引 int getIndex(dict* d,string key){ if(d->len==0){ cout<<"哈希表空的"<<endl; return -1; } int index = hash(key)%d->size; int c=1; while( c<d->size && d->table[index]->key!=key){ index = (index+1)%d->size; c++; } if(c<d->size) return index; else{ cout<<"找不到元素"<<endl; return -1; } } //根據鍵刪除鍵值對 void DeleteByKey(dict* d,string key){ int i = getIndex(d,key); if(i>=0){ d->table[i] = NULL; d->len--; } }
完整代碼以及示例
#include <iostream> #include<stdint.h> using namespace std; struct dictEntry{ string key; string val; }; //字典 無序 struct dict{ dictEntry** table; //哈希表數組 int size; //哈希表大小 int len; //鍵值對計數器 }; dict* dictCreate(int size){ dict* d = (dict*)malloc(sizeof(dict)); d->table = (dictEntry**)calloc(size,sizeof(dictEntry*)); //這裏要注意了 for(int i=0;i<size;i++) d->table[i] = NULL; d->size = size;//size看成負載因子 d->len=0; return d; } //計算str的哈希值 參照java hashCode int hash(string s){ int h = 0; for(int i=0;i<s.length();i++){ h = 31 * h + (s[i] & 0xff); } return h; } void set(dict* d,string key,string val){ if(d->size==d->len){ cout<<"哈希表滿了"<<endl; return; } int index = hash(key)%d->size; while(d->table[index]!=NULL){ index = (index+1)%d->size; } d->table[index] = (dictEntry*)malloc(sizeof(dictEntry)); //先開闢空間 d->table[index]->val = val; d->table[index]->key = key; d->len++; return; } string get(dict* d,string key){ if(d->len==0){ cout<<"哈希表空的"<<endl; return ""; } int index = hash(key)%d->size; int c=1; while( c<d->size){ if(d->table[index] && d->table[index]->key==key) break; index = (index+1)%d->size; c++; } if(c<d->size){ return d->table[index]->val; } else{ cout<<"找不到元素"<<endl; return ""; } } //根據鍵查找哈希表的索引 int getIndex(dict* d,string key){ if(d->len==0){ cout<<"哈希表空的"<<endl; return -1; } int index = hash(key)%d->size; int c=1; while( c<d->size && d->table[index]->key!=key){ index = (index+1)%d->size; c++; } if(c<d->size) return index; else{ cout<<"找不到元素"<<endl; return -1; } } //根據鍵刪除鍵值對 void DeleteByKey(dict* d,string key){ int i = getIndex(d,key); if(i>=0){ d->table[i] = NULL; d->len--; } } int main(int argc, char *argv[]) { dict* d = dictCreate(100); set(d,"age","1"); set(d,"name","biningo"); cout<<get(d,"one"); cout<<get(d,"age")<<" "<<get(d,"name")<<endl; DeleteByKey(d,"name"); cout<<get(d,"name")<<endl; return 0; } 找不到元素 1 biningo 找不到元素