字典

字典在不少高級語言裏都有,好比java

  1. js的對象結構能夠當字典來用
  2. python的字典
  3. go的map
  4. ......................

可是大家知道字典是怎麼實現的嗎?本文來實現一個簡單的字典。python

python的字典

先來看python的字典是怎樣的ios

d = {}
d["name"]="biningo"
d["age"] = "19"
name = d.get("name")
age = d.get("age")

c語言實現

參考了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
找不到元素
相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息