散列函数c语言实现,哈希表的C语言实现

news/2024/12/13 1:53:18/

#include #include#include

#define BUCKETCOUNT 16

structhashEntry

{const char*key;char*value;struct hashEntry*next;

};

typedefstructhashEntry entry;structhashTable

{

entry bucket[BUCKETCOUNT];//先默认定义16个桶

};

typedefstructhashTable table;//初始化哈希表

void initHashTable(table*t)

{inti;if (t == NULL)return;for (i = 0; i < BUCKETCOUNT; ++i) {

t->bucket[i].key =NULL;

t->bucket[i].value =NULL;

t->bucket[i].next =NULL;

}

}//释放哈希表

void freeHashTable(table*t)

{inti;

entry* e,*ep;if (t == NULL)return;for (i = 0; i

e= &(t->bucket[i]);while (e->next !=NULL) {

ep= e->next;

e->next = ep->next;

free(ep->key);

free(ep->value);

free(ep);

}

}

}//哈希散列方法函数

int keyToIndex(const char*key)

{intindex , len , i;if (key == NULL)return -1;

len=strlen(key);

index= (int)key[0];for (i = 1; i

index*= 1103515245 + (int)key[i];

}

index>>= 27;

index&= (BUCKETCOUNT - 1);returnindex;

}//在堆上分配足以保存str的内存//并拷贝str内容到新分配位置

char* strDup(const char*str)

{intlen;char*ret;if (str == NULL)returnNULL;

len=strlen(str);

ret= (char*)malloc(len + 1);if (ret !=NULL) {

memcpy(ret , str , len);

ret[len]= ‘\0‘;

}returnret;

}//向哈希表中插入数据//insertEntry(&t , "电脑型号" , "华硕 X550JK 笔记本电脑");

int insertEntry(table* t , const char* key , const char*value)

{intindex , vlen1 , vlen2;

entry* e , *ep;if (t == NULL || key == NULL || value ==NULL) {return -1;

}

index=keyToIndex(key);

printf("index = %d\n",index);if (t->bucket[index].key ==NULL) {

t->bucket[index].key =strDup(key);

t->bucket[index].value =strDup(value);

}else{

e= ep = &(t->bucket[index]);while (e != NULL) { //先从已有的找

if (strcmp(e->key , key) == 0) {//找到key所在,替换值

vlen1 =strlen(value);

vlen2= strlen(e->value);if (vlen1 >vlen2) {

free(e->value);

e->value = (char*)malloc(vlen1 + 1);

}

memcpy(e->value , value , vlen1 + 1);return index; //插入完成了

}

ep=e;

e= e->next;

}//end while(e...//没有在当前桶中找到//创建条目加入

e = (entry*)malloc(sizeof(entry));

e->key =strDup(key);

e->value =strDup(value);

e->next =NULL;

ep->next =e;

}returnindex;

}//在哈希表中查找key对应的value//找到了返回value的地址,没找到返回NULL

const char* findValueByKey(const table* t , const char*key)

{intindex;const entry*e;if (t == NULL || key ==NULL) {returnNULL;

}

index=keyToIndex(key);

e= &(t->bucket[index]);if (e->key == NULL) return NULL;//这个桶还没有元素

while (e !=NULL) {if (0 == strcmp(key , e->key)) {return e->value; //找到了,返回值

}

e= e->next;

}returnNULL;

}//在哈希表中查找key对应的entry//找到了返回entry,并将其从哈希表中移除//没找到返回NULL

entry* removeEntry(table* t , char*key)

{intindex;

entry* e,*ep; //查找的时候,把ep作为返回值

if (t == NULL || key ==NULL) {returnNULL;

}

index=keyToIndex(key);

e= &(t->bucket[index]);while (e !=NULL) {if (0 == strcmp(key , e->key)) {//如果是桶的第一个

if (e == &(t->bucket[index])) {//如果这个桶有两个或以上元素//交换第一个和第二个,然后移除第二个

ep = e->next;if (ep !=NULL) {

entry tmp= *e; //做浅拷贝交换

*e = *ep;//相当于链表的头节点已经移除

*ep = tmp; //这就是移除下来的链表头节点

ep->next =NULL;

}else {//这个桶只有第一个元素

ep = (entry*)malloc(sizeof(entry));*ep = *e;

e->key = e->value =NULL;

e->next =NULL;

}

}else{//如果不是桶的第一个元素//找到它的前一个(这是前面设计不佳导致的多余操作)

ep = &(t->bucket[index]);while (ep->next != e)ep = ep->next;//将e从中拿出来

ep->next = e->next;

e->next =NULL;

ep=e;

}returnep;

}//end if(strcmp...

e = e->next;

}returnNULL;

}void printTable(table*t)

{inti;

entry*e;if (t == NULL)return;for (i = 0; i

printf("\nbucket[%d]:\n", i);

e= &(t->bucket[i]);while (e->key !=NULL) {

printf("\t%s\t=\t%s\n" , e->key , e->value);if (e->next == NULL)break;

e= e->next;

}

}

}intmain()

{

table t;

initHashTable(&t);

insertEntry(&t , "电脑型号" , "华硕 X550JK 笔记本电脑");

insertEntry(&t , "操作系统" , "Windows 8.1 64位 (DirectX 11)");

insertEntry(&t , "处理器" , "英特尔 Core i7 - 4710HQ @ 2.50GHz 四核");

insertEntry(&t , "主板" , "华硕 X550JK(英特尔 Haswell)");

insertEntry(&t , "内存" , "4 GB(Hynix / Hyundai)");

insertEntry(&t , "主硬盘" , "日立 HGST HTS541010A9E680(1 TB / 5400 转 / 分)");

insertEntry(&t , "显卡" , "NVIDIA GeForce GTX 850M (2 GB / 华硕)");

insertEntry(&t , "显示器" , "奇美 CMN15C4(15.3 英寸)");

insertEntry(&t , "光驱" , "松下 DVD - RAM UJ8E2 S DVD刻录机");

insertEntry(&t , "声卡" , "Conexant SmartAudio HD @ 英特尔 Lynx Point 高保真音频");

insertEntry(&t , "网卡" , "瑞昱 RTL8168 / 8111 / 8112 Gigabit Ethernet Controller / 华硕");

insertEntry(&t , "主板型号" , "华硕 X550JK");

insertEntry(&t , "芯片组" , "英特尔 Haswell");

insertEntry(&t , "BIOS" , "X550JK.301");

insertEntry(&t , "制造日期" , "06 / 26 / 2014");

insertEntry(&t , "主人" , "就是我");

insertEntry(&t , "价格" , "六十张红色毛主席");

insertEntry(&t , "主硬盘" , "换了个120G的固态");

entry* e = removeEntry(&t , "主板型号");if (e !=NULL) {

puts("找到后要释放");

free(e->key);

free(e->value);

free(e);

e=NULL;

}

printTable(&t);const char* keys[] = { "显示器" , "主人","没有" , "处理器"};for (int i = 0; i < 4; ++i) {const char* value = findValueByKey(&t , keys[i]);if (value !=NULL) {

printf("find %s\t=\t%s\n",keys[i], value);

}else{

printf("not found %s\n",keys[i]);

}

}

freeHashTable(&t);

getchar();return 0;

}


http://www.ppmy.cn/news/426748.html

相关文章

华硕X550VC(Qualcomm Atheros AR9485 无线网卡)解决在ubuntu14.04/15.04下无线网卡不能链接无线网问题...

华硕X550VC&#xff08;Qualcomm Atheros AR9485 无线网卡&#xff09;解决在ubuntu14.04/15.04下无线网卡不能链接无线网问题 根据这五个命令来解决无线网卡驱动问题&#xff0c;最后一部echo数据后自行重启系统即可完美解决驱动问题。有问题请留言。 lspci -nnk | grep -A2 …

铝制LED灯邦纳WLB92X550PWM

亮度可调LED灯WLB92X550PWM 外壳式线性带 主要外壳材料铝 产品类型照明 安装螺纹无螺纹 颜色输入控制个人&#xff08;一根线/颜色&#xff0c;与输入线相同的颜色数&#xff09; 颜色选项1 /工作灯白色 动画选项1 Solid On 流明颜色1 3510 颜色1 - 波长/色温/坐标5000K&…

华硕X550C 安装Ubuntu 14.10 无线网络显示硬件被禁用的解决方法

小学期涉及到LINUX 下 QT 用户界面与MySQL的应用&#xff0c;原来电脑是WIN8 WIN7双系统&#xff0c;为了大作业 只能在安装一个Ubuntu。用的是Ubuntu14.10版本的&#xff0c;通过EasyBCD引导安装&#xff0c;网上有的是自己可以查下&#xff0c;安装完毕之后发现无线网络不可…

Ubuntu解决华硕x550C的WiFi问题

执行下列命令后&#xff0c;重新启动 echo "options asus_nb_wmi wapf4" | sudo tee /etc/modprobe.d/asus_nb_wmi.conf

义乌购API,item_search_img - 按图搜索义乌购商品(拍立淘

点击获取key和secret 返回参数 --------------------------------------- Result Object: --------------------------------------- {"items": {"url": "http://img.yiwugo.com/search.html?urlhttp%3A%2F%2Fimg1.yiwugou.com%2Fi004%2F2018%2F0…

mysql数据库之视图

mysql数据库之视图 视图是虚拟的表&#xff0c;本身不包含数据&#xff0c;也就不能对其进行索引操作。 对视图的操作和对普通表的操作一样。 视图具有如下好处: 1.简化复杂的 SQL 操作&#xff0c;比如复杂的连接&#xff1b; 2.只使用实际表的一部分数据&#xff1b; 3.通过…

深圳行-八:惠州泡温泉

今天本来不想写这个日志的&#xff0c;肚子难受、咳嗽导致的喉咙痛一直没好、心情也很郁闷、加上从惠州回来一路也很累。但是&#xff0c;日志这个东西&#xff0c;时间一长就懒掉了&#xff0c;所以还是坚持一下&#xff1a;写&#xff01; 前面说了&#xff0c;深圳的天气如何…

非常有用的生活小智慧 非常非常实用

作者&#xff1a;HelloKitty变身咯 提交日期&#xff1a;2008-11-27 15:40:00 访问&#xff1a;496563 回复&#xff1a;5973 原贴http://www.tianya.cn/publicforum/content/funinfo/1/1307085.shtml 搜集到第19页 有重复、无错过~ 方便大家收藏&#xff01; 先贴两个我自己贡…