各位小伙伴,新年快乐。

哈希表,本质上是数组,而链地址就是存放了链表的数组。

借用哈希函数对某个数进行适当运算求得该数的哈希值,在根据这个哈希值对哈希表进行查找插入删除操作。

假设这是一个哈希表H,容量为5,长度为0;五个指针全部为NULL;

首先我们有一个数:3;假设其求得的哈希值为2,如图所示:

然后再令3成为这个存放这五个链表的数组中,第三个链表的,第一个结点。

如图所示:

这就是插入,删除也可借鉴单链表的操作。

下面来看怎么实现的

目录

预先要引用的头文件以及宏定义

所使用哈希表的结构

所使用的哈希函数

其基本操作接口

初始化哈希表

销毁哈希表

查找

插入

删除

遍历

一些接口的测试


预先要引用的头文件以及宏定义

#include<stdio.h>
#include<iostream>
//
//using namespace std;#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -1
#define UNSUCCESS 0
#define SUCCESS 1
typedef int ElemType;
typedef int Status;
typedef int KeyType;

所使用哈希表的结构

//(链地址)
typedef struct {KeyType Key;//这里可以存放其他数据
}RecordType, RcdType;
typedef struct Node {                       //其实这个指针就是链表RcdType r;struct Node* next;
}Node;
typedef struct {Node** rcd;                             //(指向指针的指针)存放指针的数组int size;                               //哈希表的容量int count;                              //当前表中含有的记录个数int(*hash)(KeyType key, int hashSize); //函数指针变量,选取哈希函数
}HashTable;

所使用的哈希函数

int hash(int key, int hashSize)
{//哈希函数,hashSize为地址空间长度(哈希表的容量)return (3 * key) % hashSize;
}

哈希函数可以有很多种

1,直接定址法,你这个数是98,那里就到H.rcd[98]里面去,直接。hash = 98

2,除留余数法,hash = 关键字%(某个你中意的数(一般是哈希表的容量))也是我选择的。

3,数字分析法,

4,折叠法,

5,平方取中法,

等。3,4,5大家有兴趣就搜一下,我不会讲。

其基本操作接口

Status InitHash(HashTable& H, int size, int(*hash)(KeyType, int));   //初始化哈希表
Status DestroyHash(HashTable& H);                                   //销毁哈希表
Node* SearchHash(HashTable H, KeyType key);                         //查找
Status InsertHash(HashTable& H, RcdType e);                         //插入
Status DeleteHash(HashTable& H, KeyType key, RcdType& e);           //删除
void HashTraverse(HashTable H);                                     //遍历

初始化哈希表

Status InitHash(HashTable& H, int size, int(*hash)(KeyType, int))
{H.rcd = (Node**)malloc(size*sizeof(Node*));if (H.rcd != NULL){for (int i = 0; i < size; i++){      H.rcd[i] = NULL;           }H.size = size;H.hash = hash;H.count = 0;return OK;}else {return OVERFLOW;}
}

销毁哈希表

Status DestroyHash(HashTable& H)
{if (H.rcd != NULL){Node* np, * nt;for (int i = 0; i < H.size; i++){np = H.rcd[i];while (np != NULL){nt = np;np = np->next;free(nt);}}H.size = 0;H.count = 0;H.hash = NULL;return OK;}else{return OVERFLOW;}
}

查找

Node* SearchHash(HashTable H, KeyType key)
{int p = H.hash(key, H.size);Node* np;for (np = H.rcd[p]; np != NULL; np = np->next){if (np->r.Key == key)return np;}return NULL;
}

插入

Status InsertHash(HashTable& H, RcdType e)
{int p;Node* np;np = SearchHash(H, e.Key);if (np == NULL){p = H.hash(e.Key, H.size);np = (Node*)malloc(sizeof(Node));if (np != NULL){np->r = e;np->next = H.rcd[p];H.rcd[p] = np;H.count++;return OK;}else{return OVERFLOW;        }}else{return ERROR;}
}

删除

Status DeleteHash(HashTable& H, KeyType key, RcdType& e)
{Node* n;n = SearchHash(H, key);if (n != NULL){int p = H.hash(key, H.size);Node* np, * nq;np = H.rcd[p];nq = NULL;while (np != NULL){if (np->r.Key != key){nq = np;np = np->next;}else{e = np->r;if (nq == NULL)//表头{H.rcd[p] = np->next;}else//不是表头{nq->next = np->next;}break;}}H.count--;free(np);return OK;}else{return ERROR;}
}

遍历

void HashTraverse(HashTable H)
{if (H.rcd != NULL){Node* np, * nq;for (int i = 0; i < H.size; i++){np = H.rcd[i];if (np == NULL){printf("  #");}else{while (np){printf("%3d", np->r.Key);np = np->next;}}printf("\n");}}
}

一些接口的测试

int main()
{HashTable H;InitHash(H, 10, hash);for (int i = 0; i < 12; i++){RcdType e;e.Key = i;InsertHash(H, e);}HashTraverse(H);RcdType e1;DeleteHash(H, 9, e1);printf("被删数据%d\n", e1.Key);HashTraverse(H);DestroyHash(H);
}

其实想想看,如果他不是链表,是棵B树呢!!!,存放B树的数组,哈哈哈哈哈哈。

数据结构学习,哈希表(链地址)相关推荐

  1. 7-45 航空公司VIP客户查询 【哈希表 链地址法】

    不少航空公司都会提供优惠的会员服务,当某顾客飞行里程累积达到一定数量后,可以使用里程积分直接兑换奖励机票或奖励升舱等服务.现给定某航空公司全体会员的飞行记录,要求实现根据身份证号码快速查询会员里程积分 ...

  2. c语言链地址法构造哈希表,链地址处理法构造简单哈希表

    链地址法:将所有关键字为同义词的记录保存在一个线性链表中(拉链法) 设某哈希函数产生的哈希地址在区间[0,12]上,则创建指针数组add[12],其中每个元素都是一个单项链表的头结点(有值). 由于仅 ...

  3. 数据结构学习:哈希表

    哈希表 一.概念 二.散列函数 三.散列冲突 四.代码实现 一.概念 哈希(Hash)表又称为散列表,是利用数组支持按照下标随机访问的特性,是数组的一种扩展,可以说没有数组就没有哈希表 哈希表存储键值 ...

  4. C++八股文分享---数据结构其二---哈希表

    C++八股文分享-数据结构其二-哈希表 前言 什么是哈希表? 搜索二叉树对值的查找是通过从根节点开始,逐个节点与目标值做比较,向下查找,直至找到目标值或是到达根节点未查找到,时间复杂度为O(logn) ...

  5. 【数据结构】哈希表的概念及应用

    [数据结构]哈希表的概念及应用 前言 1.写出哈希表的基本概念 2.列出常用的哈希函数构造方法,并阐述各自的特点. 直接定址法 除留余数法 数字分析法 其他构造整数关键字的哈希函数的方法: 平方取中法 ...

  6. 数据结构:哈希表(散列表)基础

    哈希表(散列表)基础 引入哈希表 什么是哈西表: 一种具有相同特性的数据元素的集合,每个元素具有唯一标识自己的关键字. 基本原理: 说明: 顺序查找.二分查找或者二叉树的查找是基于待查关键字与表中元素 ...

  7. 【数据结构】哈希表、哈希值计算分析

    哈希表.哈希值计算分析 哈希表完整代码 引出哈希表 哈希表(Hash Table) 哈希冲突(Hash Collision) JDK1.8的哈希冲突解决方案 哈希函数 如何生成 key 的哈希值 In ...

  8. 图书馆管理系统(C、数据结构、哈希表、文件IO)

    目录 技术路线 实现效果展示 ​程序主体 1.头文件部分 2.自定义函数定义部分 3.main函数部分 注意 技术路线 数据结构.哈希表.文件IO 通过C语言进行程序设计,有用到数据结构中的哈希表,通 ...

  9. 「Redis数据结构」哈希表(Dict)

    「Redis数据结构」哈希表(Dict) 文章目录 「Redis数据结构」哈希表(Dict) @[toc] 一.概述 二.结构 三.哈希冲突 四.链式哈希 五.rehash 六. 渐进式 rehash ...

  10. 用c语言实现基本数据结构(哈希表)

    用c语言实现基本数据结构(哈希表) 写这个哈希表总是段错误,找了半天的bug...原来是各种小错误不断,写得很蛋疼. 我是是用数组实现的,数组的最大值定义成的宏.一共只有四个函数,分别为初始化哈希表, ...

最新文章

  1. Linux命令CURL用法
  2. linux 普通用户退出vim,Linux环境下VI/VIM编辑文件时无权限保存的解决方法(普通用户)...
  3. Python学习笔记——glob模块【文件、路径操作】
  4. 计算机学生工学交替报告书,工学交替学生守则
  5. WTMPlus 1.4 Uniapp来了
  6. [react] react中发起网络请求应该在哪个生命周期中进行?为什么?
  7. 【干货】小米用户画像实战.pdf(附下载链接)
  8. linux websocket服务安全组,在 linux 下安装并使用 websocket
  9. 2020广西电子设计竞赛题目
  10. 基于php的人力资源管理系统,基于thinkPHP框架的人力资源管理系统
  11. 基于Python编写的倒计时工具
  12. esxi安装报错解决方案
  13. 部署k8s集群(k8s集群搭建详细实践版)
  14. 【Beetl笔记整理二】定义变量
  15. android新emoji表情符号,安卓7.0全新emoji表情符号预览:更像人了
  16. Kinetics400/600/700数据集免费下载
  17. 时钟周期,机器周期,指令周期的区别
  18. php 文件图片上传
  19. 1.1 Java基础(一)概述
  20. “阿法狗”之父:关于围棋,人类3000年来犯了一个错!

热门文章

  1. 软件许可证管理应该怎么做?
  2. 阿里腾讯都到百度去挖AI大牛,百度对此却不care,为何?
  3. 计算机用户凭据删除,win8系统如何删除保存的共享凭据(用户名和密码)
  4. matlab牛顿法求区间根程序,MATLAB用二分法、不动点迭代法及Newton迭代(切线)法求非线性方程的根...
  5. java, Statement类的介绍
  6. 大小限制_微信传文件有大小限制怎么办?教你3秒把100MPPT压缩成10M
  7. centos搭建局域网DNS服务器及单服务器配置多域名
  8. 【HTML502】HTML基础02_标题_段落_文本格式化_链接
  9. ZooKeeper 命令操作
  10. None和nan、NaN、NAN