设为首页 收藏本站
查看: 757|回复: 0

[经验分享] 实现极小一部分PHP的HASHMAP

[复制链接]
发表于 2017-4-6 11:02:38 | 显示全部楼层 |阅读模式
又修改了一下,实现了resize

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <math.h>
typedef struct bucket{
int h;  
char* key;
void* pData;
struct bucket* pNext;
struct bucket* pLast;
}Bucket;
typedef struct hashtable{
int size;
int elementsNum;
int mask;
Bucket** arBuckets; //这是一个存放buckets的array
}HashTable;
/**
**  这是一个计算HASH值的算法
**/
int time33(char* arKey,int arlength){
int h = 0;
int i;
for(i=0;i<arlength;i++){
h = h*33 + (int)*arKey++;
}
return h;
}
/**
**  初始化一个大小是1的HASHTABLE
**/
int _init_hash_table(HashTable** ht){
*ht = (HashTable*)malloc(sizeof(HashTable));
(*ht)->size = 1;
(*ht)->mask = (*ht)->size - 1;
(*ht)->elementsNum = 1;
(*ht)->arBuckets = (Bucket**)malloc(sizeof(Bucket*)*(*ht)->size);
memset((*ht)->arBuckets,0,sizeof(Bucket*)*(*ht)->size);
return 1;
}
int _hash_link_bucket_to_bucket_head(Bucket** newBucket,Bucket** bucketHead){
if(*bucketHead==NULL){
*bucketHead = *newBucket;
}else{
(*newBucket)->pNext = (*bucketHead)->pNext;
(*newBucket)->pLast = (*bucketHead);
if((*bucketHead)->pNext != NULL){
(*bucketHead)->pNext->pLast = *newBucket;
}
(*bucketHead)->pNext = *newBucket;
}
return 1;
}
int _hash_new_bucket(Bucket** newBucket,int hash,char* arkey,void* pData){
(*newBucket) = (Bucket*)malloc(sizeof(Bucket));
(*newBucket)->h = hash;
(*newBucket)->key = arkey;
(*newBucket)->pData = pData;
(*newBucket)->pNext = NULL;
(*newBucket)->pLast = NULL;
return 1;
}

int _hash_rehash(HashTable* ht){
int i = 0;
//由于我没定义pListNext指针,所以只能这样rehash了。
for( ; i<ht->size ; i++){
if(ht->arBuckets != NULL){
int index = ht->arBuckets->h & ht->mask ;
if(i != index){
_hash_link_bucket_to_bucket_head(&ht->arBuckets,&ht->arBuckets[index]);
ht->arBuckets = NULL;
}
}
}
return 1;
}
/**
**  将HASHTABLE的大小扩容1倍
**/
int _hash_resize(HashTable* ht){
if(ht != NULL){
ht->size = ht->size << 1;
ht->mask = ht->size - 1;
realloc(&ht->arBuckets,sizeof(Bucket*) * ht->size);
int i;
for(i=ht->size>>1;i<ht->size;i++){
ht->arBuckets = NULL;
}
//memset(ht->arBuckets[0],NULL,sizeof(Bucket*) * (ht->size >> 1));
printf("resize:%i\r\n", ht->size);
_hash_rehash(ht);
return 1;
}
return 0;
}

/**
**  往HASHTABLE中添加元素
**/
int _hash_add_or_update(HashTable* ht,char* arKey,int arLength,void* pData){
int h = time33(arKey,arLength);
int index = h & ht->mask;
Bucket* p = ht->arBuckets[index];
while(p!=NULL){
if(strcmp(arKey,p->key)==0){
//这里应该执行更新操作
free(p->pData);
p->pData = pData;
return 1;
}
p = p->pNext;
}
Bucket* newBucket;
_hash_new_bucket(&newBucket,h,arKey,pData);
_hash_link_bucket_to_bucket_head(&newBucket,&ht->arBuckets[index]);
ht->elementsNum++;
if(ht->elementsNum = ht->size){
_hash_resize(ht);
}
return 0;
}
void* _hash_find(HashTable* ht,char* arKey,int arLength){
int h = time33(arKey,arLength);
int index = h & ht->mask;
Bucket* p = ht->arBuckets[index];
while(p!=NULL){
if(strcmp(arKey,p->key)==0){
return p->pData;
}
p = p->pNext;
}
return 0;
}
int PUT(HashTable* ht,void* key,void* value){
char* arKey = (char*)key;
int len = strlen(arKey);
return _hash_add_or_update(ht,arKey,len,value);
}
void* GET(HashTable* ht,void* key){
char* arKey = (char*)key;
int len = strlen(arKey);
return _hash_find(ht,arKey,len);
}
int main(){
printf("%s\r\n","这是一个hashtable的例子");
HashTable* ht;
_init_hash_table(&ht);
PUT(ht,"1","mengjun");
PUT(ht,"2","aaaaa");
PUT(ht,"3","fff");
PUT(ht,"24","eee");
PUT(ht,"25","ddd");
printf("%s\r\n",(char*)GET(ht,"1"));
printf("%s\r\n",(char*)GET(ht,"2"));
printf("%s\r\n",(char*)GET(ht,"3"));
printf("%s\r\n",(char*)GET(ht,"24"));
printf("%s\r\n",(char*)GET(ht,"25"));
printf("HASHTABLE总共有元素%i个\r\n",ht->elementsNum);
return 0;
}

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-360984-1-1.html 上篇帖子: php 字符串分割几种方式 下篇帖子: discuz x2.5 php 自动发帖
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表