读数据结构与算法分析

哈希表

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

但是是无序的

一般想法

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

散列函数

简单的散列函数

不均匀,不够好

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. SQLMAP使用详解

    使用示例 python sqlmap.py -u "http://xx.com/member.php?id=XX"  -p id --dbms "Mysql"  ...

  2. C++分享笔记:5X5单词字谜游戏设计

    笔者在大学二年级刚学完C++程序设计后,做过一次课程设计,题目是:5X5单词字谜游戏设计.为了设计算法并编写程序,笔者在当时颇费了一番心力,最后还是成功地完成了.设计中不乏有精妙之处.该程序设计完全是 ...

  3. mysql复制表结构和数据

    1.复制表结构: create table newName like oldName;//可以复制所有结构. 或者: create table newName select * from oldNam ...

  4. js 校验身份证号

    根据地区编码.身份证格式.18位身份证需要验证最后一位校验位 //校验身份证 function IdentityCodeValid(code) { var city = { 11: "北京& ...

  5. 数据仓库和Hadoop大数据平台有什么差别?

    广义上来说,Hadoop大数据平台也可以看做是新一代的数据仓库系统, 它也具有很多现代数据仓库的特征,也被企业所广泛使用.因为MPP架构的可扩展性,基于MPP的数据仓库系统有时候也被划分到大数据平台类 ...

  6. Python语言发展的关键时间节点

    1989年:Python想法的产生 1991年:发布最早的Python可用版本 2000年:发布Python2.0 2010年:发布Python2.x系列的最后一个版本,主版本号为2.7 2008年: ...

  7. 解决应用程序无法正常启动0xc0150002等问题

    1.在程序运行出错的时候,右键“我的电脑”,然后点击“管理”→“事件查看器”→“Windows 日志”→“应用程序”,查看错误信息: 1> “E:\IPCam_share\ARP\數據處理\Hg ...

  8. Git使用列表(四)

    最近,由于自己的一个项目,导致自己的关于自己的要使用Git的很多的命令,突然发现自己的git的还有许多不知道的东西 不过,在这个工作的过程中,也发现自己的一些很大的缺陷,就是自己题目理解力有限,明明就 ...

  9. Git使用规范(三)

    今天我们来介绍一下Git的一些操作,这个里面主要是一些我们平时遇到的一些问题 1.当我进入了一个分支的是时候,我在查看git log的时候,为什么会有别人的信息,我一直以为 这个是查看分支提交情况, ...

  10. 结合《需求征集系统》谈MVC框架

    结合<需求征集系统>分析MVC框架. 六个质量属性: 可用性:在系统压力过大时,会提示系统繁忙. 可修改性:使用配置文件,修改配置文件即可.对于一些公共的方法,进行封装,修改时,只需修改封 ...