开地址哈希函数的接口定义

基本的操作包括:初始化开地址哈希表、销毁开地址哈希表、插入元素、删除元素、查找元素、获取元素个数。

各种操作的定义如下:

ohtbl_init

int ohtbl_init (OHTbl *htbl, int positions, int (*h1) (const void *key), int (*h2)(const void *key),

int (*match)(const void *key1, const void *key2), void (*destroy)(void *data));

返回值  如果哈希表初始化成功,返回0;否则返回-1 。

描述  初始化开地址哈希表htbl。在对哈希表进行其他操作之前,必须首先进行初始化。

参数positions 指定表中的槽位个数。函数指针h1,h2用来指定用户定义的辅助哈希函数以完成双散列过程。函数指针match指向一个用户定义的函数,此函数用于判断两个键是否匹配,它的使用方法与chtbl_init中的match类似。函数指针destroy通过调用ohtbl_destroy来释放动态分配的内存空间,同样它与ohtbl_init中参数的使用方法类似。如果哈希函数表中的数据不需要释放,那么destroy应该指向NULL。

复杂度  O(m),m是哈希表中槽的个数。

ohtbl_destroy

void ohtbl_destroy (OHTbl *htbl ) ;

返回值  无 。

描述  销毁htbl指定的开地址哈希表。在调用ohtbl_destroy之后不再允许进行其他操作,除非再次初始化。

ohtbl_destroy会删除哈希表中的所有元素,并同时释放ohtbl_init中参数destroy不为NULL的成员所占用的内存空间。

复杂度  O(m),m是哈希表中槽的个数。

ohtbl_insert

int ohtbl_insert (OHTbl *htbl,const void *data ) ;

返回值  如果插入元素成功,返回0;如果哈希表中已经包含此元素,返回1;否则,返回-1 。

描述  向htbl指定的开地址哈希表中插入一个元素。

新元素包含一个指向data的指针,因此只要元素仍然存在于哈希表中,此指针就一直有效。与data相关的空间将由函数的调用者来管理。

复杂度  O(1)。

ohtbl_remove

int ohtbl_remove (OHTbl *htbl,const void **data ) ;

返回值  如果删除元素成功,返回0;否则,返回-1 。

描述  从htbl指定的开地址哈希表中删除与data匹配的元素。

返回时,data指向已经删除元素中存储的数据。与data相关的内存空间将由函数调用者来管理。

复杂度  O(1)。

ohtbl_lookup

int ohtbl_lookup (const OHTbl *htbl,const void **data ) ;

返回值  如果在表中找到元素,返回0;否则,返回-1 。

描述  查找htbl指定的开地址哈希表中是否有与data匹配的元素。

如果找到,在函数返回时,data指向哈希表中相匹配元素的数据。

复杂度  O(1)。

ohtbl_size

int ohtbl_size (const OHTbl *htbl ) ;

返回值  哈希表中元素的个数。

描述  获取哈希表中元素个数的宏。

复杂度  O(1)。

开地址哈希表的实现与分析

实现分为两个文件,一是开地址哈希表的头文件,一是抽象数据类型的实现文件。

示例1:开地址哈希表的头文件

/*ohtbl.h*/

#ifndef OHTBL_H#define OHTBL_H #include

/*定义开地址哈希表的数据结构*/typedefstructOHTbl_

{int positions; /*1指明哈希表中分配的槽位数目*/

void *vacated; /*2指向一个特殊的地址空间,这个特殊的地址上曾经删除过一个元素*/

int (*h1)(const void *key); /*3辅助哈希函数*/

int (*h2)(const void *key); /*4辅助哈希函数*/

int (*match)(const void *key1,const void *key2); /*5判断两个元素是否匹配*/

void (*destroy)(void *data); /*6销毁函数*/

int size; /*7现有的元素数目*/

void **table; /*8存储元素的数组*/} OHTbl;

/*函数原型声明*/

int ohtbl_init(OHTbl *htbl, int positions, int (*h1)(const void *key), int (*h2)(const void *key),

int (*match)(const void *key1,const void *key2),void (*destroy)(void *data));

void ohtbl_destroy(OHTbl *htbl);

int ohtbl_insert(OHTbl *htbl, const void *data);

int ohtbl_remove(OHTbl *htbl, void **data);

int ohtbl_lookup(const OHTbl *htbl, void **data);

#define ohtbl_size(htbl)((htbl)->size)#endif //OHTBL_H

示例2:开地址哈希表抽象数据类型的实现

/*ohtbl.c*/#include

#include

#include "ohtbl.h"

/*为空出的元素预留一个特殊的内存地址*/

static char vacated;

/*ohtbl_init 初始化htbl指定的开地址哈希表*/

int ohtbl_init(OHTbl *htbl,int positions, int (*h1)(const void *key), int (*h2)(const void *key),

int (*match)(const void *key1, const void *key2),void (*destroy)(void *data))

{

int i;

/*为空分配空间*/

if((htbl->table = (void **)malloc(positions * sizeof(void *))) == NULL)

return -1;

/*初始化每个槽位,把每个槽位的指针设置为NULL*/

htbl->positions = positions;

for(i=0; ipositions; i++)

htbl->table[i] = NULL;

/*将空出的成员设置为为此保留的特殊内存地址*/

htbl->vacated = &vacated;

/*封装4个函数*/

htbl->h1 = h1;

htbl->h2 = h2;

htbl->match = match;

htbl->destroy=destroy;

/*初始化元素数量*/

htbl->size = 0;

return 0;

}

/*ohtbl_destroy 销毁htbl指定的开地址式哈希表*/

void ohtbl_destroy(OHTbl *htbl)

{

int i;

if(htbl->destroy != NULL)

{

for(i=0; i < htbl->positions; i++)

{

if(htbl->table[i] != NULL && htbl->table[i] != htbl->vacated)

htbl->destroy(htbl->table[i]);

}

}

/*释放表空间*/

free(htbl->table);

/*清除数据结构*/

memset(htbl,0,sizeof(OHTbl);

return;

}

/*ohtbl_insert 向表中插入元素*/

int ohtbl_insert(OHTbl *htbl,const void *data)

{

void *temp;

int position,i;

/*因为开地址哈希表有固定的大小,所以在插入之前必须保证有足够的空间放置元素*/

if(htbl->size == htbl->positions)

return -1;

/*相同的键不允许重复插入表中,插入之前调用htbl_lookup检查是否有相同的元素*/

temp = (void *)data;

if(ohtbl_lookup(htbl,temp) == 0)

return 1;

/*满足以上条件,使用双散列法在表中寻找未被占用的槽*/

for(i=0; i< htbl->positions; i++)

{

position = (htbl->h1(data) + (i*htbl->h2(data))) % htbl->positions;

if(htbl->table[position]==NULL || htbl->table[position]==htbl->vacated)

{

/*将元素插入表中*/

htbl->table[position] = (void *)data;

htbl->size++;

return 0;

}

}

/*选用了错误的哈希函数*/

return -1;

}

/*ohtbl_remove 删除htbl指定表中与data相匹配的元素*/

int ohtbl_remove(OHTbl *htbl,void **data)

{

int position,i;

/*通过双散列定位到要删除元素的位置*/

for(i=0; ipositions; i++)

{

position = (htbl->h1(*data) + (i * h2(*data))) % htbl->positions ;

if(htbl->table[position] == NULL)

{

/*没有找到匹配的数据*/

return -1;

}

else if (htbl->table[position] == htbl->vacated)

{

/*查找到了突出的位置,继续搜索*/

continue;

}

else if (htbl->match(htbl->table[position],*data))

{

/*将data指向正在删除的数据*/

*data = htbl->table[position];

/*将此槽位的地址放到vacated成员中*/

htbl->[position] = htbl->vacated;

htbl->size--;

return 0;

}

}

/*如果没有找到元素,则返回-1*/

return -1;

}

/*ohtbl_lookup 查找htbl指定的表中,与data相匹配的元素*/

int ohtbl_lookup(const OHTbl *htbl,void **data)

{

int position,i;

for(i=0; ipositions; i++)

{

position = (htbl->h1(*data) + (i * htbl->h2(*data)))% htbl->positions;

if(htbl->table[position] == NULL)

{

/*没有找到数据*/

retun -1;

}

else if(htbl->match(htbl->table[position],*data))

{

/*将data指向找到的数据*/

*data = htbl->table[position];

return 0;

}

}

return -1;

}

Linux哈希表数组,开地址哈希表(Hash Table)的接口定义与实现分析相关推荐

  1. 数据结构 链式哈希表(Hash Table)的接口定义与实现分析(完整代码)

    链式哈希表的接口定义 关于哈希表与链式哈希表的描述可以参阅:http://www.cnblogs.com/idreamo/p/7990860.html 链式哈希表的操作与属性有:初始化.销毁.插入元素 ...

  2. Linux两个网卡mac地址重复,ARP响应Linux服务器上的单个MAC地址,同一网络上有多个接口...

    Linux服务器有2个活动网络接口: IF:eth1 IP:192.168.1.1/24 MAC:11:11:11:11:11:11 (1GbE) IF:eth2 IP:192.168.1.2/24 ...

  3. SWUST OJ 1012: 哈希表(链地址法处理冲突)

    1012: 哈希表(链地址法处理冲突) 题目描述 采用除留余数法(H(key)=key %n)建立长度为n的哈希表,处理冲突用链地址法.建立链表的时候采用尾插法. 输入 第一行为哈西表的长度m: 第二 ...

  4. 数据结构学习,哈希表(链地址)

    各位小伙伴,新年快乐. 哈希表,本质上是数组,而链地址就是存放了链表的数组. 借用哈希函数对某个数进行适当运算求得该数的哈希值,在根据这个哈希值对哈希表进行查找插入删除操作. 假设这是一个哈希表H,容 ...

  5. PHP关联数组和哈希表(hash table) 未指定

    PHP有数据的一个非常重要的一类,就是关联数组.又称为哈希表(hash table),是一种很好用的数据结构. 在程序中.我们可能会遇到须要消重的问题,举一个最简单的模型: 有一份username列表 ...

  6. (7)哈希表的链地址法实现

    哈希表(Hash table,也叫散列表),是根据关键码值(Key value)而直接进行访问的数据结构.也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度.哈希表在像Java. ...

  7. codewars打怪日记 Greed is Good JavaScript中数组用法和 哈希表的使用

    codewars是一个在线编程网站,其奖励机制像打怪升级.你不能查看高于你级别的问题的答案.除非自己通过提交测试.通过提交之后可以看到各种解法排行榜 .通过对比自己解法和排行榜对比,可以找到差距,提高 ...

  8. c++ 哈希表_C语言精华知识:表驱动法编程实践

    问:怎么每天看到这种文章? 答:只需搜索公众号"51单片机学习网"免费关注 排版:嵌入式云IOT技术圈 数据压倒一切.如果选择了正确的数据结构并把一切组织的井井有条,正确的算法就不 ...

  9. linux C/C++服务器后台开发面试题总结

    一.编程语言 1.根据熟悉的语言,谈谈两种语言的区别? 主要浅谈下C/C++和PHP语言的区别: 1)PHP弱类型语言,一种脚本语言,对数据的类型不要求过多,较多的应用于Web应用开发,现在好多互联网 ...

最新文章

  1. leetcode算法题--调整数组顺序使奇数位于偶数前面
  2. java打印倒立直角三角形
  3. 【观点】微博的弊端和它的真正意义
  4. 大学计算机vfp最新考试题库,大学计算机vfp考试选择题题库.doc
  5. 软工实践第一次作业-自我审视和规划
  6. linux下proc文件的读写(部分转载)
  7. Web压力测试和手机App测试
  8. API函数之GetUserName
  9. 自媒体行业现在还能赚钱吗?
  10. LeetCode 781 森林中的兔子 题解
  11. 解决宿舍路由器校园网共享登陆问题
  12. Apereo CAS 5.0.3.1安装配置
  13. 探究Stereo中的DSI(Disparity Space Image)到底是指什么
  14. 白鹭h5加java_白鹭引擎EUI做H5活动 入门篇
  15. 测试大会能给我们带来什么?
  16. 极线几何(Epipolar Geometry)
  17. 总计超5万星!GitHub上10个超级好玩的项目
  18. SpringBoot利用Aop打印入参出参日志
  19. Hive中各种日期格式转换方法总结
  20. 通用分页 (基于jquery、bootstrap)

热门文章

  1. 瑞典正成为欧洲硅谷?
  2. 360 安全浏览器尝试收费;苹果macOS首次出现在云端;pip 20.3 发布|极客头条
  3. 轻薄于型 强悍于内 拯救者9000X 2021硬核发布
  4. 中国首枚芯片邮票问世;苹果开源 Swift System | 极客头条
  5. 微软直播马上开始,近百岗位等你来,快戳进直播间
  6. 用 C++ 跟你聊聊“桥接模式” | 原力计划
  7. 港中文用 Zoom 考试,中途遭黑客入侵传播不可描述内容
  8. 阿里乌镇大动作:平头哥开源 MCU 设计平台!
  9. 未来五年,物联网将迎来什么样的蜕变?
  10. 探寻京东云核心竞争力的源泉