读数据结构与算法分析

哈希表

一种用于以常数平均时间执行插入、删除和查找操作的数据结构。

但是是无序的

一般想法

  • 通常为一个包含关键字的具有固定大小的数组
  • 每个关键字通过散列函数映射到数组中
  • 冲突:两个关键字映射到同一个值

散列函数

简单的散列函数

不均匀,不够好

typedef unsigned int Index ;

Index Hash(const char *key, int Tablesize)
{
unsigned int HashVal = 0; while(*key != '\0')
HashVal += *key++ ; return HashVal % Tablesize ;
}

一个好的散列函数

Index Hash(const char *key, int TableSize)
{
unsigned int HashVal = 0 ;
while(*key != '\0')
HashVal += (HashVal << 5) + *key++ ; return HashVal %TableSize ;
}

解决冲突

分离链接法


将散列到同一个值的所有元素保存在一个表中


类型声明

struct ListNode ;
typedef struct ListNode *Position ;
struct Hashbl ;
typedef struct HashTbl *HashTable ; HashTable IntializeTable(int TableSize) ;
void DestroyTable(HashTable H) ;
Position Find(ElemenetType Key, HashTable H) ;
Void Insert(ElementType Key, HashTable H) ;
ElementType Retireve(Position P) ; struct ListNode
{
ElementType Element ;
Position Next ;
} ; typedef Position List ; strcut HashTbl
{
int TableSize ;
List *TheLists ; //实则为指针数组
}

哈希表的初始化

HashTable IntializeTable(int TableSize)
{
HashTable H ; TableSize = NextPrime(TableSize) ;//将表的大小设为它下一个素数
H->TheList = malloc(sizeof (List) * H->TableSize) ;
if(H->TheList == NULL)
FatalError("内存不足") ;
for(int i = 0,i < H->TableSize; i++)
{
H->TheLists[i] = malloc(struct ListNode) ;
if(H->TheLists[i] == NULL)
FatalError("内存不足") ;
else
H->TheLists[i]->Next = NULL ;
} return H ;
}

Find函数

Position Find(ElementType Key, HashTable)
{
Position P ;
List L ;
L = H->TheLists[Hash(Key,H->TableSize)];
P = L->Next ;
while(P != NULL && P->Element != Key) //如果关键字为字符串,可能用到strcmp函数
P = P->Next ; return P ; }

Insert函数

void Insert(ElementType Key, HashTable H)
{
Position P ,TmpCell;
List L ;
TmpCell = malloc(ListNode) ;
if(TmpCell == NULL)
FatalError("内存不足") ;
else
{
L = H->TheLists[Hash(Key,H->TableSize)] ;
P = L->Next ;
TmpCell->Element = Key ;
TmpCell->Next = P ;
L->Next = TmpCell ;
free(TmpCell) ;
}
}

开放定址法

当发生冲突时,重新选择地址

Hi(X) = (Hash(X) + F(i)) mod TableSize ;
  • 线性探测法:会发生一次聚集
  • 平方探测法:效果较好
 F(i) = i^2

类型声明

typedef unsigned int Index ;
typedef Index Position ; struct Hashbl ;
typedef struct HashTbl *HashTable ; HashTable IntializeTable(int TableSize) ;
void DestroyTable(HashTable H) ;
Position Find(ElemenetType Key, HashTable H) ;
Void Insert(ElementType Key, HashTable H) ;
ElementType Retireve(Position P) ; enum KindOfEntry{Legitimate,Empty,Deleted} ; struct HashEntry
{
ElementType Element ;
enum KingOfEntry Info ;
} ; typedef struct HashEntry Cell ; strcut HashTbl
{
int TableSize ;
Cell *TheCells ; //直接用结构数组
}

Find函数

Position Find(ElementType Key,HashTable H)
{
Position P ;
int Num = 0;
P = H->TheCells[Hash(Key,H->TableSize)] ;
while(H->TheCells[P].Info != Empty && H->TheCells[P].Element != Key) //如果关键字为字符串需要使用strcmp函数
{
P += 2 * ++Num - 1 ;
if(P >= H->TableSize)
P -= H->TableSize ;
} return P ;
}

Insert函数

void Insert(ElementType Key, HashTable H)
{
Position P ;
P = Find(Key,H) ;
if(H->TheCells[P] != Legitimate)
{
H->TheCells[P].Info = Legitimate ;
H->TheCells[P].Element = Key ;//如果为字符串,则可能使用strcpy函数
}
}

总结

  • 哈希表以常数平均时间执行Insert和Find操作是重要特点,但它是无序的
  • 在解决冲突时使用不同的方法应该注意它的装填因子导致的效率问题
  • 应用:
    1. 编译器使用哈希表追踪代码中声明的变量
    2. 在图论当中每个节点应当由实际的名字
    3. 游戏编程中的变化表
    4. 在线拼写检验

哈希表 -数据结构(C语言实现)的更多相关文章

  1. [数据结构 - 第8章] 查找之哈希表(C语言实现)

    首先是需要定义一个哈希表的结构以及一些相关的常数.其中 HashTable 就是哈希表结构.结构当中的 elem 为一个动态数组. #define HASHSIZE 12 // 定义哈希表长为数组的长 ...

  2. 数据结构---哈希表的C语言实现(闭散列)

    原文地址:https://blog.csdn.net/weixin_40331034/article/details/79461705 构造一种存储结构,通过某种函数(hashFunc)使元素的存储位 ...

  3. 简单的哈希表实现 C语言

    简单的哈希表实现 简单的哈希表实现 原理 哈希表和节点数据结构的定义 初始化和释放哈希表 哈希散列算法 辅助函数strDup 哈希表的插入和修改 哈希表中查找 哈希表元素的移除 哈希表打印 测试一下 ...

  4. 哈希表的C语言实现

    首先介绍一下什么是哈希表.同线性表.树一样,哈希表也是一种数据结构,理想情况下可以不需要任何比较,一次存取便能得到所查记录.所以它的优点就是查找特定记录的速度快.因为哈希表是基于数组的,所以创建后就难 ...

  5. nginx 哈希表数据结构

    1.哈希表ngx_hash_t的优势和特点 哈希表是一种典型的以空间换取时间的数据结构,在没有冲突的情况下,对任意元素的插入.索引.删除的时间复杂度都是O(1).这样优秀的时间复杂度是通过将元素的ke ...

  6. C语言实现简单的哈希表

    这是一个简单的哈希表的实现,用c语言做的. 哈希表原理 这里不讲高深理论,只说直观感受.哈希表的目的就是为了根据数据的部分内容(关键字),直接计算出存放完整数据的内存地址. 试想一下,如果从链表中根据 ...

  7. 数据结构和算法(Golang实现)(26)查找算法-哈希表

    哈希表:散列查找 一.线性查找 我们要通过一个键key来查找相应的值value.有一种最简单的方式,就是将键值对存放在链表里,然后遍历链表来查找是否存在key,存在则更新键对应的值,不存在则将键值对链 ...

  8. 浅谈MatrixOne如何用Go语言设计与实现高性能哈希表

    目录 MatrixOne数据库是什么? 哈希表数据结构基础 哈希表基本设计与对性能的影响 碰撞处理 链地址法 开放寻址法 Max load factor Growth factor 空闲桶探测方法 一 ...

  9. C语言-简单哈希表(hash table)

    腾讯三面的时候,叫我写了个哈希表,当时紧张没写好···结果跪了··· 回来后粪发涂墙,赶紧写了一个! 什么都不说了···先让我到厕所里面哭一会··· %>_<% 果然现场发挥,以及基础扎实 ...

随机推荐

  1. nodejs实战的github地址,喜欢的你还等啥

    第一章.第二章:使用Express + MongoDB搭建多人博客:https://github.com/nswbmw/N-blog 第三章:使用Redis搭建漂流瓶服务器:https://githu ...

  2. 【题解】洛谷P4281 [AHOI2008] 紧急集合(求三个点LCA)

    洛谷P4281:https://www.luogu.org/problemnew/show/P4281 思路 答案所在的点必定是三个人所在点之间路径上的一点 本蒟蒻一开始的想法是:先求出2个点之间的L ...

  3. 浮动产生的高度坍塌解决方法以及使用siblings()方法获取同级元素

    高度坍塌:如果一个没有设置高度div里的元素都是浮动元素,这个时候就可能产生高度坍塌,因为div的高度都是普通元素撑起来的,div里的元素浮动之后,元素就会脱离文档流,所以父级的div高度就可能为零, ...

  4. 时间、时间戳相关小结 - iOS

    项目中难免会与时间打交道,故此次围绕时间展开做了一些日常使用的小结;如下 code 中也是围绕一些日常开发中较为常用的点展开小的方法封装. 具体方法的使用如下: // 2019-02-21 17:30 ...

  5. iOS之iOS中的(null)、<null>、 nil 的问题

      摘要: 你有没有过这样的经历,就是界面上显示出类似<null>.(null)这样一些东西,有时候还会莫名其妙的闪退.反反复复真是曰了犬,今天来总结一下这个问题的解决方法 前段时间开发过 ...

  6. [videos系列]日本的videos视频让男人产生了哪些误解?

    转载自:[videos系列]日本的videos视频让男人产生了哪些误解? 日本的videos视频是每个男人成长过程中都会看的启蒙教育片,也是男人在成年后调剂生活的必需品,但是由于影视作品是艺术的,是属 ...

  7. js中定时器使用方法经验总结

    前言,最近在做一个音频播放项目的时候,碰到播放时间精度的问题,捣鼓了几天,最终巧妙的运用定时器去降低了错误发生频率 正题,下面是对定时器的使用总结,如有错误之处,请读者加以纠正. 延迟执行(1次) s ...

  8. WSO2 API Manager中host Ip 不正确的问题解决方法

    问题: 根据官方的Quick start的教程,部署完AM后,添加的API的host Ip不正确,为localhost或者服务器上的其他虚拟ip. 安装版本:       WSO2AM 2.6.0 环 ...

  9. TinyMCE插件:RESPONSIVE filemanager 9 图片自动添加水印

    跟踪function() 搜索(filemanager/upload.php) 在代码中发现,上传成功后,会传回JSON信息数据,于是最后找到方法是 $upload_handler = new Upl ...

  10. TinyMCE插件:Filemanager [4.x-6.x] 文件名统一格式化

    上传图片程序(filemanager/upload.php) 在if (!empty($_FILES) && $upload_files)中上传图片时,在文件正式上传至服务器前,有一次 ...