哈希表示例

2023-05-16

哈希表的意义在于高效查找。对于查找来说,如果数据量特别大,二分查找和哈希表算法十分有用了。二分查找前面已经讲过,现来讲讲哈希表算法。
就像输入数据数组下标返回数组元素一样,这样的查找方式是最高效的了,哈希表就是这样一种数据结构。
假设现在有10个元素的数组,通过每一个元素可以确定它存在在哈希表中的哪一个位置(哈希表可以理解为一个特殊数组,它的数据成员也有下标),当下次要查找该元素时候,就可以通过该位置拿到该数值元素,这便是哈希表的核心思想。
如何通过一个数据元素确定其在哈希表中的位置,一般我们可以通过该元素取模于元素个数,这样一来我们只要分配一个跟元素个数一样大的哈希表就可以来存放这些数组元素了。但是,这样会数据重叠的情况发生。例如下面例子,
数组a的数据成员为:

int a[3] = {2, 3, 6};

对于2来说,它放在hash[2 % 3],即hash[2]处,但是对于3和6来讲,它们放在哈希表的hash[3 % 3] 和hash[6 % 3],即hash[0]处,那么就会出现后存到hash[0]的’6’覆盖掉先存到hash[0]的3了。因此哈希表的数据成员不能这样单纯的存放,解决办法是采用链表。
哈希表的数据成员是链表头,即是链表变量(注意,不是链表指针),每次数据都是追加到对应的哈希表位置的链表头指向的链表中。这样,一来不会产生数据覆盖,二来对于查找操作效率也大大提高。
示例代码如下:
为了方便测试,先定义并实现两个函数,分别是用于产生随机数存放到数组、遍历数数所在数组:

void rand_array(void)
{
    for (i = 0; i < MAX; i++)
        a[i] = rand() % 100;
}

void show_array(const char *str)
{
    printf("%s", str);
    for (i = 0; i < MAX; i++)
        printf("%d ", a[i]);
    printf("\n");
}

定义链表节点,这里采用双向链表,方便操作

typedef struct _Node NODE;  //前向typedef
struct _Node{
    int data;
    NODE* pre;
    NODE* next;
};

创建哈希表,并将数组成员放到哈希表对应的位置

//返回哈希表的地址。哈希表的数据成员是链表,所以返回类型是链表类型的地址
NODE* hash_create(int max)
{
    NODE *list = NULL, *new = NULL;
    int index;
    list = (NODE* )malloc(max * sizeof(NODE));  //动态分配空间,该空间的数据成员是链表变量

    //对哈希表中的数据元素初始化
    for (i = 0; i < max; i++)
    {
        list[i].pre = &list[i];
        list[i].next = &list[i];
    }

    //将数组元素挂到对应哈希表位置中
    for (i = 0; i < max; i++)
    {
        //推算该数据应在哈希表的哪一个位置存放
        index = create_hash_index(a[i]);        

        new = (NODE* )malloc(sizeof(NODE));
        new->data = a[i];

        //将数据挂到双向链表中
        new->next = &list[index];
        new->pre = list[index].pre;
        list[index].pre->next = new;
        list[index].pre = new;
    }

    return list;
}

上面根据数据元素推算出应在哈希表哪一个位置函数create_hash_index的实现体为:

int create_hash_index(int dat)
{
    return dat % MAX;
}

遍历哈希表的数据成员

//遍历哈希表中的所有数据
void travel_hash(NODE* list)
{
    NODE* tmp = NULL;
    for (i = 0; i < MAX; i++)
    {
        tmp = list[i].next;
        printf("list[%d]: ", i);
        while (tmp != &list[i])
        {
            printf("%d ", tmp->data);
            tmp = tmp->next;
        }
        printf("\n");
    }
}

查找哈希表中的数据,查找成功返回该元素在该哈希表中的下标,找不到则返回-1

//查找哈希表中的数据
int find_hash(NODE* list, int key)
{
    NODE* tmp = NULL;

    for (i = 0; i < MAX; i++)
    {
        tmp = list[i].next;
        while (tmp != &list[i])
        {
            if (tmp->data == key)
                return i; //tmp->data;
            tmp = tmp->next;
        }       
    }
    return -1;
}

销毁哈希表及哈希表中链表数据成员

//销毁哈希表及哈希表中链表数据成员
void destory_hash(NODE* list)
{
    NODE* tmp = NULL, *save = NULL;

    for (i = 0; i < MAX; i++)
    {
        tmp = list[i].next;
        while (tmp != &list[i])
        {
            save = tmp->next;
            free(tmp);          
            tmp = save;

            //save = tmp;
            //free(tmp);
            //tmp = save->next;
        }
    }
    free(list);
}

main函数的调用

int main(void)
{
    NODE* hash_list = NULL;
    int dat;

    //产生随机数并存放到数组中
    rand_array();

    //显示数组中的随机数
    show_array("rand: ");

    //创建哈希表并将数组元素放到哈希表中
    hash_list = hash_create(MAX);

    //遍历哈希表
    travel_hash(hash_list);

     while (1)
    {
        printf("please input dat:");
        scanf("%d", &dat);

        if (dat == -1)
            break;

        printf("find: %d\n", find_hash(hash_list, dat));
    }
    //销毁哈希表及哈希表中的链表数据成员
    destory_hash(hash_list);    
    return 0;
}

运行结果:
这里写图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

哈希表示例 的相关文章

  • 基于RK3399&ESP8285自动售货柜项目—ESP8266(8285)程序编写与烧录

    基于RK3399 amp ESP8285自动售货柜项目 ESP8266 8285 程序编写与烧录 本系列文章讲详细讲解该基于RK3399及ESP8285自动售货柜的完整实现方法 xff0c 从硬件连接到网络通信再到软件实现 xff0c 本产
  • Windows10安装OpenCV4.1.0+opencv_contrib

    Windows10安装OpenCV4 1 0 43 opencv contrib 文章目录 Windows10安装OpenCV4 1 0 43 opencv contrib一 Visual Studio 2015安装二 下载和安装OpenC
  • 用MATLAB来做智能小车的建模与仿真

    两种智能小车的构造简介 在市面上常见的两种智能小车都是基于轮式的 xff0c 在某宝上面卖的最多的 xff0c 各位在学生时代拿来应付课程设计和毕业设计用的各种小车分为两种 1 后轮驱动 xff0c 前轮阿克曼转向的 xff0c 通常后轴通
  • Qt编写网络调试助手(TCP客户端+TCP服务端+UDP服务端)

    Qt编写网络调试助手 xff08 TCP客户端 43 TCP服务端 43 UDP服务端 xff09 终极版开源 飞扬青云 博客园
  • RKNN-Toolkit模型转换并在Rockchip NPU推理并进行性能评估

    RKNN Toolkit转换Tensorflow模型至Rockchip NPU推理并进行性能评估 文章目录 RKNN Toolkit转换Tensorflow模型至Rockchip NPU推理并进行性能评估一 基本知识二 环境部署2 1环境准
  • Redis Stream终端间使用流消费者组通信

    redis stream终端间使用流消费者组通信 附redis消息队列和消费者相关命令表 消息队列的相关命令 xff1a XADD xff1a 添加消息到末尾 xff08 生产消息 xff09 XTRIM xff1a 对流进行修剪 xff0
  • 如何将顶点数据保存为STL文件?

    stl 文件是在计算机图形应用系统中 xff0c 用于表示三角形网格的一种文件格式 它的文件格式非常简单 xff0c 应用很广泛 STL是最多快速模型系统所应用的标准文件类型 STL是用三角网格来表现3D CAD模型 STL只能用来表示封闭
  • 常见图像噪声及产生原因(高斯、泊松和椒盐噪声)

    目录 什么是图像噪声噪声来源常见噪声高斯噪声泊松噪声乘性噪声椒盐噪声 信噪比 什么是图像噪声 噪声在图像上常表现为一引起较强视觉效果的孤立像素点或像素块 一般 xff0c 噪声信号与要研究的对象不相关 xff0c 它以无用的信息形式出现 x
  • 音视频OSD——修改叠加信息的位置

    目录 分析 叠加代码分析 总结 同一行中叠加 代码 效果 不同行中叠加 现象 代码 效果 纵向保护 代码 效果 总结 代码 c文件 h文件 效果 分析 之前的OSD叠加的位置是默认的 在初始位置 若想改动OSD叠加的位置 在叠加时进行位置的
  • 音视频OSD——修改叠加在yuv420p图像上信息的颜色

    目录 预备知识 准备图片 分析 映射关系 代码 效果 代码优化 c h 效果 预备知识 字符编码 一些基本概念 字符编码 详解常用字符集 ASCII ISO8859 1 GB2312 GBK Unicode 和字符编码 UTF 8 UTF
  • H.264——使用H.264视频编解码器JM进行YUV图像序列的编解码

    目录 常见H 264视频编码器JM基础配置准备一个YUV视频 JM实现编码修改配置文件Encoder Control编译运行 JM实现解码如何判断编码解码是否正确 常见H 264视频编码器 X264 xff08 只有编码没有解码 xff09
  • 有意思的题:(++a * a++)、(b++ * ++b)、(c++ * c++)、(++d * ++d)

    include lt stdio h gt int main int a 61 3 b 61 3 c 61 3 d 61 3 int a1 b1 c1 d1 a1 61 43 43 a a 43 43 b1 61 b 43 43 43 43
  • 详解LVDS通信协议

    目录 LVDS概述LVDS接口电路的组成LVDS输出接口电路类型单路6位LVDS输出接口双路6位LVDS输出接口单路8位1TL输出接口双路8位1TL输出位接口 典型LVDS发送芯片介绍四通道LVDS发送芯片五通道LVDS发送芯片十通道LVD
  • 自动跟随机器人:一种简易的自动跟随方案,自动跟随小车、自动跟随平衡小车、STM32、基于超声波的自动跟随小车

    目的 xff1a 一种廉价的跟随方案 xff0c 让大家都能够参与进来 xff0c 技术难度不大 xff0c 一些人也能够DIY一些属于自己的 跟随 机器人 xff01 并不是要做工业应用什么的 只是做出来玩玩 1 介绍 先看视频 xff0
  • 详解MIPI协议

    目录 前言MIPI简介MIPI联盟的MIPI DSI规范MIPI名词解释MIPI DSI分层结构command和video模式 D PHYLane模组Lane 全局架构Lane电压和状态DATA LANE操作模式时钟LANE低功耗状态高速数
  • 音频处理——详解PCM数据格式

    目录 知识储备什么是PCM采样采样率重采样 量化编码PCM常用指标 PCM数据流 知识储备 音频处理 音频编码原理简介 音频处理 音频处理的基本概念 什么是PCM PCM全称Pulse Code Modulation xff0c 翻译一下是
  • 音频处理——常用音频编码格式简介(PCM、G726、ADPCM、LPCM、G711、AAC)

    目录 PCMG726ADPCMLPCMG711AAC格式对比音频帧长音频播放过程 PCM 音频处理 详解PCM数据格式 音频处理 解析PCM格式实例 xff08 音量调控 xff09 G726 G 726是ITU T定义的音频编码算法 19
  • 音频处理——G711标准详解

    目录 G711简介G711A算法原理压缩方法举例代码 G711U算法原理压缩方法举例代码 G711A与G711U对比 参考链接 G711简介 G711是国际电信联盟ITU T定制出来的一套语音压缩标准 xff0c 它代表了对数PCM xff
  • PS流详解(载荷H264)

    目录 PS简介标准结构标准H264流结构定长音频帧和其他流式私有数据的结构 PS流封装标准PSH结构PES包结构PSM包结构体 元素流 PS 封装规则H264元素流封装规则音频元素流封装规则私有信息封装规则 PS简介 PS 封装方式需要支持
  • Postman中的authorization

    1 概述 Authorization是验证是否拥有从服务器访问所需数据的权限 当发送请求时 xff0c 通常必须包含参数 xff0c 以确保请求具有访问和返回所需数据的权限 Postman提供了授权类型 xff0c 可以轻松地在Postma

随机推荐

  • 操作pdf,提示startxref not found

    startxref not found多半是文件被损坏了 xff0c 检查一下 xff0c 是不是之前自己写的代码把pdf文件跑崩了 可以尝试重新生成一遍该pdf文件 xff0c 然后再进行操作 或者尝试一下 xff1a https www
  • FTP 530未登录

    提供一种思路 xff1a 如果说FTP服务器已开 xff0c 服务器也能ping通 就得考虑是不是我们在FTP服务器上设置的默认路径有问题 xff08 不符合我们的需求 xff09 Windows10下 xff0c FTP设置默认位置 xf
  • 开源个小demo

    https github com UnderADome epms 内部项目管理
  • LDAP的基本知识

    https zhuanlan zhihu com p 147768058 https www cnblogs com gaoyanbing p 13967860 html
  • 「权威发布」2019年电赛最全各类题目细节问题解答汇总

    点击上方 大鱼机器人 xff0c 选择 置顶 星标公众号 福利干货 xff0c 第一时间送达 xff01 各位朋友大家上午好 xff0c 今天是比赛的第二天 xff0c 许多朋友都给我发消息 xff0c 我不是不回 xff0c 我实在是回不
  • Unable to find explicit activity class

    做项目从一个activity逐渐转向到使用多个activity xff0c 这个时候新手就容易出现一个问题 xff0c 忘了给activity在AndroidManifest xml中注册 打开日志 xff0c 在遇到这个报错信息的时候 x
  • Errors running builder 'Maven Project Builder'

    由于第一次玩maven的时候 xff0c 很多东西都还是懵懵懂懂 xff0c 不是很清楚 xff0c 不知道怎么把Myeclipse中的maven配置弄坏了 xff0c 从外部导入maven项目的时候 xff0c 总会报一些错误 xff1a
  • Type handler was null on parameter mapping for property '__frch_id_0'

    1 Type handler was null on parameter mapping for property frch id 0 2 Type handler was null on parameter mapping or prop
  • 如何解决error: failed to push some refs to 'xxx(远程库)'

    在使用git 对源代码进行push到gitHub时可能会出错 xff0c 信息如下 此时很多人会尝试下面的命令把当前分支代码上传到master分支上 git push u origin master 但依然没能解决问题 出现错误的主要原因是
  • expected an indented block

    Python中没有分号 xff0c 用严格的缩进来表示上下级从属关系 导致excepted an indented block这个错误的原因一般有两个 xff1a 1 冒号后面是要写上一定的内容的 xff08 新手容易遗忘这一点 xff09
  • C 实现TCP服务端(select、poll、epoll)

    使用C简单的实现一个tcp server xff0c 包括常规server 多线程实现server select实现server poll实现server epoll实现server IO模型原理可以看上一篇文章 常规模式 define M
  • UART串口通信

    目录 一 通信特点二 通信应用三 接线示意图三 UART通信协议四 STM32F4 串口使用1 资源分布2 特性3 UART框图4 使用方法5 相关库函数6 函数实例 五 实战 上位机控制开发板小灯 一 通信特点 异步 串行 全双工 一般描
  • 项目:文件搜索助手(FileSeeker)

    目录 1 项目简介 2 项目源代码 3 相关技术 4 实现原理 5 项目架构图 6 项目功能 7 测试报告 7 1 测试用例 7 2 测试环境 7 3 测试结论 7 3 1 功能测试 7 3 2 性能测试 7 3 3 兼容性 7 3 4 容
  • cocos2d实现2D地图A*广度路径算法

    h ifndef HELLOWORLD SCENE H define HELLOWORLD SCENE H include 34 cocos2d h 34 USING NS CC enum PatchFront Uper 61 1 Down
  • Keil 中,仿真调试查看局部变量值总是显示<not in scope>

    原因 xff1a 编译器把代码优化掉了 xff0c 直接导致在仿真中变量根本没有分配内存 xff0c 也就无法查看变量值 以后调试中遇到这种情况的解决办法 xff1a 核心思想是 xff1a 让变量值在代码中被读取其内存值 1 把变量定义为
  • 联合体在串口通讯中的妙用

    背景 本文主要涉及到的是一种串口通讯的数据处理方法 xff0c 主要是为了解决浮点数在串口通讯中的传输问题 xff1b 通常而言 xff0c 整形的数据类型 xff0c 只需进行移位运算按位取出每个字节即可 xff0c 那么遇到浮点型的数据
  • Linux 平均负载

    本文首发自公众号 LinuxOK xff0c ID 为 xff1a Linux ok 关注公众号第一时间获取更新 xff0c 分享不仅技术文章 xff0c 还有关于职场生活的碎碎念 在 Linux 系统中 xff0c 所谓平均负载 xff0
  • Linux 进程状态

    Linux 进程状态是平时排查问题 程序稳定性测试的基础知识 xff0c 查看进程状态的常用工具有 top 和 ps 以 top 的输出为例 xff1a S 列 xff08 Status xff09 表示进程的状态 xff0c 图中可见 D
  • Docker 是什么

    本文首发自公众号 LinuxOK xff0c ID为 xff1a Linux ok xff0c 关注公众号第一时间获取更新 xff0c 分享记录职场开发过程中所见所感 Docker 是一个用 GO 语言实现的开源项目 xff0c 它可以将应
  • 哈希表示例

    哈希表的意义在于高效查找 对于查找来说 xff0c 如果数据量特别大 xff0c 二分查找和哈希表算法十分有用了 二分查找前面已经讲过 xff0c 现来讲讲哈希表算法 就像输入数据数组下标返回数组元素一样 xff0c 这样的查找方式是最高效