读数据结构与算法分析

哈希表

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

但是是无序的

一般想法

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

散列函数

简单的散列函数

不均匀,不够好

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. OpenCV 中CV_IMAGE_ELEM 的使用

    CV_IMAGE_ELEM 是一个宏函数,基本形式: CV_IMAGE_ELEM(image,elemtype,row,col) 其中,image为指针数组,elemtype为数据的存取类型,row为 ...

  2. C#串口通讯

    本文提供一个用C#实现串口通讯实例,亲自编写,亲测可用! 开发环境:VS2008+.net FrameWork3.5(实际上2.0应该也可以) 第一步 创建一个WinForm窗体,拉入一些界面元素 重 ...

  3. Java 循环结构

    Java 循环结构 - for, while 及 do...while 顺序结构的程序语句只能被执行一次.如果您想要同样的操作执行多次,,就需要使用循环结构. Java中有三种主要的循环结构: whi ...

  4. Linux 学习第三天

    一.常用命令 1.diff A.diff -q 源文件 目标文件  (快速比较文件是否相同) 2.ifconfig.nmcli (查看配置信息) 命令输入注意: Windows 查看网卡配置信息输入命 ...

  5. UML类图介绍以及PlantUML使用方法

    类的UML表示方法 UML介绍 类图,是UML(统一建模语言)中用于描述"类"以及"类与类"之间的示意图.它形象的描述出了系统的结构,帮助人们理解系统. 类图是 ...

  6. 【Flume】数据采集引擎Flume

    一.概述 flume是一个高效的.可靠的.可用的分布式海量日志数据收集.聚合.传输的工具. Flume is a distributed, reliable, and available servic ...

  7. php源码建博客1--搭建站点-实现登录页面

    主要: 站点搭建 实现登录页面 分析及改进 站点搭建 1)  在apache安装目录下: [conf\extra\httpd-vhosts.conf]加入站点配置 <VirtualHost *: ...

  8. Django自定制分页功能

    URL: """django_paginner URL Configuration The `urlpatterns` list routes URLs to views ...

  9. 《PHP实用问题解决案例》系列分享专栏

    <PHP实用问题解决案例>已整理成PDF文档,点击可直接下载至本地查阅https://www.webfalse.com/read/201725.html 文章 PHP汉字拼音转换和公历农历 ...

  10. 《HTML与CSS知识》系列分享专栏

    收藏HTML和CSS方面的技术文章,作为一个WEB开发者,必须要知道HTML和CSS方面的知识,即使作为后台开发者也应该知道一些常用的HTML和CSS知识,甚至架构师也要了解,这样才会开发出实用的网站 ...