朝花夕拾 · 数据结构 | 哈希表篇

听故事学语言 · 数据结构篇 · 第五章 藏在文件里的顺序与链 数据结构篇第五章,工业章一,前四章家当的实战回门。拖动进度条为什么秒跳,MP4 登记簿记位置供直达;FAT 文件分配表,链式存储的逻辑、数组实现的身体,1977 年马克·麦克唐纳为软盘设计它;进程档案链表轮转,一头进一头出,内核偏爱链表的连接自由;浏览器后退键,教科书的双向链表对工业界的数组加游标,同一个队形,两种站位法,谁赢谁的战场。 阅读详情

一.散列函数的构造方法

在构造散列函数时,必须注意以下几点:
1)散列函数的定义域必须包含全部关键字,而值域的范围则依赖于散列表的大小。
2)散列函数计算出的地址应尽可能均匀地分布在整个地址空间,尽可能地减少冲突。
3)散列函数应尽量简单,能在较短的时间内计算出任意一个关键字对应的散列地址。

下面介绍常用的散列函数。

代码实现:

哈希表的定义

typedef struct per
{                        //结点里的数据体
    char name[32];
    char tel[16];
}Data_t;

typedef struct node     //结点
{
    Data_t data;
    struct node *pnext;
}Node_t;

Node_t *hash_table[HASH_SIZE] = {NULL};     //指针数组,存放各个链表的头结点指针

基本功能实现:

int hash_function(char key)
{
    if (key >= 'a' && key <= 'z')
    {
        return key-'a';
    }
    else if (key >= 'A' && key <= 'Z')
    {
        return key-'A';
    }
    else
    {
        return HASH_SIZE-1;
    }
}

int insert_hash_table(Node_t **hash_table, Data_t data)
{
    int addr = hash_function(data.name[0]);

    Node_t *pnode = malloc(sizeof(Node_t));
    if (NULL == pnode)
    {
        printf("malloc error\n");
        return -1;
    }
    pnode->data = data;
    pnode->pnext = NULL;

    pnode->pnext = hash_table[addr];  //phead
    hash_table[addr] = pnode;

    return 0;
}

void show_hash_table(Node_t **hash_table)
{
    for (int i = 0; i < HASH_SIZE; ++i)
    {
        Node_t *ptmp = hash_table[i];
        while (ptmp != NULL)
        {
            printf("%s: %s\n", ptmp->data.name, ptmp->data.tel);
            ptmp = ptmp->pnext;
        }
    }
}

Node_t *find_hash_table(Node_t **hash_table, char *name)
{
    int addr = hash_function(name[0]);
    Node_t *ptmp = hash_table[addr];
    while (ptmp != NULL)
    {
        if (0 == strcmp(ptmp->data.name, name))
        {
            return ptmp;
        }
        ptmp = ptmp->pnext;
    }

    return NULL;
}


void destroy_hash_table(Node_t **hash_table)
{
    for (int i = 0; i < HASH_SIZE; ++i)
    {
        Node_t *ptmp = NULL;
        while (hash_table[i] != NULL)
        { 
            ptmp = hash_table[i];
            hash_table[i] = ptmp->pnext;
            free(ptmp);
        }

    }
}

二.处理冲突的方法

应该注意到,任何设计出来的散列函数都不可能绝对地避免冲突。为此,必须考虑在发生冲突时应该如何处理,即为产生冲突的关键字寻找下一个“空”的Hash地址。用Hi表示处理冲突中第i次探测得到的散列地址,假设得到的另一个散列地址H1仍然发生冲突,只得继续求下一个地址H2,以此类推,直到Hk不发生冲突为止,则Hk为关键字在表中的地址。

1.开放定址法

注意:采用开放定址法时,不能随便物理删除表中已有元素,否则会截断其他同义词元素的查找路径,删除元素时可以做一个删除标记,进行逻辑删除。但这样做的副作用是:执行多次删除后,表面上看起来散列表很满,实际上有许多位置未利用。

2.拉链法

听故事学语言 · 数据结构篇 · 第六章 栈,后进先出的盒子 数据结构篇第六章,栈。二进制短除法余数为什么要倒着读,谜底是栈;括号匹配先让计数器上场,([)] 一串让它当场折戟,混括号必须栈;逆波兰记法,1924 年卢卡谢维奇发明波兰记法,1957 年汉布林把它倒过来;一件学生时代的四则运算器文物,带着一颗时发时不发的雷,当年调了很久怎么也跑不对,病没变,变的是它发不发作;双栈直接求值与随机表达式对数器一千组零不合;最小栈一步报最小,接雨水单调栈一层一层结算;汉诺塔的调用栈真身,V 字图退役;火车进出站十四种可能,卡塔兰数;链栈与共享栈收章。 阅读详情

相关推荐

快手极速版抓包实战:安卓/iOS双端获取client_salt全流程解析(避坑指南)

本文详细解析了在安卓和iOS平台上获取快手极速版关键参数`client_salt`的全流程,包括环境配置、抓包工具使用、参数识别与转换等实战技巧。特别针对双端差异和反抓包机制提供了避坑指南,帮助开发者高效安全地完成数据获取任务。

weixin_29021195的博客 714

数据结构 --- 【Map 和 Set】详解

本章目标 掌握 Map/Set 及实际实现类 HashMap/TreeMap/HashSet/TreeSet 的使用 掌握 TreeMap 和 TreeSet 背后的数据结构搜索树的原理和简单实现 掌握 HashMap 和 HashSet 背后的数据结构哈希表的原理和简单实现 Map 和 Set 的概念 Map 和 Set 是一种专门用来进行搜索的关联式容器或者数据结构; 关联式容是用来存储数据的,与序列式容器不同的是,其里面存储的是<key, value>结构的键值对,在数.

Lucky_mzc的博客 1961

OTN设备核心知识速记

本文章为工作笔记,若有错误,还需大家指正。不定期更新。

Hiddengold的博客 2648

温故而知新---1

浅浅地复习一下

少年何妨梦摘星,敢挽桑弓射玉衡。 他时若遂凌云志,敢笑黄巢不丈夫。 209

Microapp 接入vite子应用

MicroApp接入vite版本,干货满满,手把手步骤说明,加上报错说明,赶紧上车!

outsider76557的博客 4660

ESP32-S3开发板实战:5分钟搞定智能门铃的音视频通话功能(附源码)

本文详细介绍了如何利用乐鑫ESP32-S3开发板快速实现智能门铃的实时音视频通话功能。通过ESP-ADF框架和RTC服务,开发者可在五分钟内完成环境搭建与核心功能调试,并附有源码和关键配置详解,为嵌入式音视频应用开发提供了高效实践路径。

web99的专栏 527

【数据结构-5】单链表的实现

单链表,具体来说是单向的、不带头的、不循环的链表。链表由一个一个节点组成,每个节点分为数据域和指针域,数据域存放数据,指针域存放下一节点的地址。这样,就可以根据指针域中的地址找到下一个节点,节点就串起来了构成了单链表。

weixin_44218929的博客 194

oracle 11.2.0.3.0 client下载,oracle64位客户端 Instant Client

oracle64位 客户端安装程序,Instant Client v11.2.0.3.0(64-bit)可以用,bo客户端需要配这个的,所以装了一个,64位操作系统中、不安装Oracle-32bit客户端,方便使用PLSQL Developer(不支持64bit位Oracle客户端)安装教程安装配置instantclient下载后,解压到D:\Oracle\instantclient_11_2(特...

weixin_42573757的博客 4516

pandas 深度入门:从数据结构到一份真实销售报表

本文系统讲解Pandas核心应用,从三分钟安装到完整月度报表生成,涵盖数据读取、清洗、筛选、分组聚合、表连接、透视表与时间序列等13个关键环节。强调“先看数据再动手”,掌握Series/DataFrame/Index结构本质,熟练运用loc/iloc、merge校验、agg/transform区别,通过真实案例实现高效报表自动化,告别手动Excel操作。最后提供性能优化与高频报错解决方案,助力读者快速上手,真正实现“写二十行代码,跑三秒出结果”。

信息安全领域优质创作者|操作系统领域专家 290

Dynamics CRM证书更换

  Dynamics CRM产品一般有两种认证方式。第一种是基于声明的内部访问也就是无证书单纯用账号密码验证。第二种就是联合身份认证,需要安装网站证书。   对于联合身份认证的情况因为需要安装证书,而且证书是有一个一年的有效期,所以运维人员每年都需要进行证书更换的操作。以下就是更换证书的方法及过程。 证书根据申请方式一般也分两种,第一种是自建证书,这种证书是没有机构认证的所以安装上之后网站因为没...

bzpfly的博客 877

基于FPGA的64点fft变换verilog开发

这精度的损失在10bits看来对最后的误差的影响是存在是不可忽略的。此后,在这思想基础上又开发了高基和分裂基等快速算法,随着数字技术的高速发展,1976年出现建立在数论和多项式理论基础上的维诺格勒傅里叶变换算法(WFTA)和素因子傅里叶变换算法。采用这种算法能使计算机计算离散傅里叶变换所需要的乘法次数大为减少,特别是被变换的抽样点数N越多,FFT算法计算量的节省就越显著。采用这种算法能使计算机计算离散傅里叶变换所需要的乘法次数大为减少,特别是被变换的抽样点数N越多,FFT算法计算量的节省就越显著。

FPGA/MATLAB学习教程/源码/项目合作开发 1977

数据结构的基本概念和算法的初步认识

本文系统阐述数据结构与算法的基础概念,涵盖数据、数据元素、数据对象的层次关系,数据结构的三要素(逻辑结构、存储结构、数据运算),以及抽象数据类型。重点解析算法的特性与设计要求,并深入讲解时间复杂度分析的核心——大O表示法,通过“只保留最高阶项、忽略常数系数、取最坏情况”三大原则,结合实例剖析O(1)、O(n)等常见时间复杂度,揭示算法效率的本质评估方法。

ACH_YYX的博客 188

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

数据结构:9.Map和Set

有的讲解会说这里key是标识作用,这种说法其实没有太大意义,就算知道了他是标识value的作用又如何,在实际的使用过程中,我们只会根据具体的效果选择使用的方法等,不会执着于“标识”这种说法。2.由于哈希函数的设计原则太过理论,它仅仅是在认为:这些通过关键码算出来的index不同 的情况下设计的,然而这种理论化的设计原则在遇到冲突时,恰恰就出现了问题,而我们能做的,就是降低冲突率。虽然哈希表的使用过程中存在冲突,但是在实际的使用过程中,哈希表的冲突率是不高的,冲突的个数是可控的。

2602_95646088的博客 204

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Vue3 低代码移动表单设计器实战(二):缩放画布下的拖拽系统与树状级联数据结构

本文深入剖析Vue3低代码表单设计器在缩放画布下的拖拽失效问题,揭示SortableJS在CSS Transform下坐标崩溃的数学根源。通过自研独立视觉克隆壳层与逆向几何补偿算法,实现精准拖拽;采用扁平数据存储+运行时树状计算结构,解决级联依赖与深克隆难题,确保逻辑一致性与性能优化,为复杂低代码系统提供可复用的工程范式。

NanChen的博客 343

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

排序算法深度笔记(上):比较类排序的思想演进与代码实现

与。本文聚焦前者 —— 也就是通过元素间两两比较来确定相对顺序的排序算法,从最朴素的 O (n²) 基础排序,到工业级主流的 O (nlogn) 进阶排序,逐层拆解设计思想、带注释的代码实现与边界细节。当我们理解了比较排序的性能边界,也就自然引出了非比较排序的存在意义。所有代码均遵循统一的实现规范:入口函数前置空数组与单元素边界校验,基于数组原地修改,主函数附带可直接运行的测试用例,与练习代码风格完全对齐。

2401_87069538的博客 626

CF2283F[数据结构]

首先考虑一种暴力解法,当我们建好i之前的图后,当我们添加i的时候,区间[li,ri]中的点都会向i建边,但是这些点中,如果有某两个顶点l,r,满足l<r,那么l就可以通过r间接到达i,因此可以删除l到i的边;初始时我们令所有点放入set中,然后对于每一个i的处理,我们将集合中仍在[l,r]的范围的点弹出,并且将f设置为i,这样我们就得到了所有点的最小跳板;对于每个区间[l,r] 我们要计算这下下标中的f(v)中大于r的数目有多少个;我们令f(v)表示顶点v可到达的最小的顶点;

蒟蒻 144

笔记-论数据结构2

typedef 数据类型 别名return 0;typedef也经常用在结构体上:每次声明结构体变量都要写struct关键字,很麻烦,而且逻辑上也很难受,typedef可以解决这个问题。int x;int y;p.x = 5;p.y = 10;return 0;而利用typedef解决有两种解法:typedef struct 结构体名数据类型 变量名;数据类型 变量名;……}别名;数据类型 变量名;数据类型 变量名;……}别名;实际的运用int x;

fish_zzzz的博客 113

【数据结构-3】算法美学之降复杂度

在while循环的循环体内,首先用临时变量保存最后一个位置的数据,再通过for循环把所有元素往后移动一位,最后把tmp中保存的值放到下标为0的位置上去。方法二的思路是:创建新数组,让原数组中后k个数据移动到新数组中前面的位置,让原数组中前numsSize-k个数据移动到新数组中后面的位置,这。这段代码的思路是:三次逆置,第一次逆置前numsSize-k个数据,第二次逆置后k个数据,最后整体逆置。这篇博文分享一道解法不一的算法题,求解过程的目的在于降低算法的时间复杂度,题源力扣。,属于空间换时间的操作。

weixin_44218929的博客 85

【数据结构-2】顺序表的实现

线性表是一种数据结构,它分为逻辑结构和物理结构,在逻辑结构上线性表是呈线性的,数据是是连续存储的;在物理结构(物理空间)上,线性表不一定是连续存储的。线性表的实现,主要分为数组和链式结构。顺序表是线性表的一种实现方式,顺序表在逻辑结构和物理结构上都是连续的。顺序表的底层实现是数组。

weixin_44218929的博客 211

数据结构:排序

将一组无序的记录(数据元素),按照某个关键字(key)递增或递减的顺序重新排列。

2502_92937908的博客 469

Python 开发的实践:从数据结构选型到框架决策

规模多大?决定用list还是set,Pandas 还是 Polars。瓶颈在哪?I/O 密集用异步,CPU 密集用进程/自由线程,内存受限用列式与惰性执行。代价是什么?消除手动维护窗口的出错面,TaskGroup消除失败任务不被取消的泄漏,消除 N+1,Protocol消除为类型约束而引入的继承层级——每个选择都在消除某类代价,同时也引入新的约束。能回答这三个问题,比记住更多 API 更有用。愿你我都能在各自的领域里不断成长,勇敢追求梦想,同时也保持对世界的好奇与善意!

weixin_45809780的博客 381

头歌 数据结构——C&C++线性表实训

本系列任务围绕线性表的链式实现,依次完成顺序构建、逆序构建、排序插入、查找、删除、求长度及栈、队列、集合等应用。通过动态内存分配与指针操作,掌握单链表的基本操作与实际应用,涵盖插入、删除、遍历、搜索等核心功能,最终实现数据结构在典型场景中的灵活运用。

一名敲代码的苦13程序员 239

CDGA DMBOK 第5章——数据建模和设计:如何将业务需求转化为规范的数据结构

本章系统阐述数据建模与设计的核心方法,强调将业务需求转化为规范数据结构的全过程。重点涵盖数据模型三层次(概念、逻辑、物理)、实体关系模型(ER)及主键、外键等核心要素,深入解析第一至第三范式,阐明规范化在消除冗余、保障数据一致性的关键作用,并介绍反规范化在性能优化中的合理应用。通过“概念看业务、逻辑看结构、物理看实现”的逻辑框架,实现从需求到数据库落地的完整闭环。

积跬步,慕至千里的博客 309

数据结构第三课:单链表与双向链表

单链表是基于结点的非连续存储结构,由数据域和指针域组成,逻辑上连续但物理上可不连续。其核心优势在于动态增删高效,适合频繁插入删除场景;相较顺序表,虽有指针开销且访问需遍历,但灵活性更高。常见算法包括反转、中间节点查找、合并有序链表及环检测等。双向链表通过前后指针提升操作效率,实际应用中常采用带头循环双向链表结构。

2503_93549121的博客 213

数据结构——图的基础

图是由顶点集和边集构成的非线性数据结构,用于描述多对多关系。根据边的方向分为有向图与无向图,按连通性分为连通图与非连通图,按边是否带权分为有权图(网)与无权图。关键术语包括:简单图(无重边、自环)、完全图(边数最多)、稀疏/稠密图、路径、回路、子图、连通分量(极大连通子图)、强连通分量及生成树(包含所有顶点的极小连通子图,不唯一)。

2401_89246663的博客 174
上一篇: 朝花夕拾 · 数据结构 | 二叉树篇
下一篇: Linux C语言文件操作:从标准IO到文件IO的全面解析
剑指offer.
博客等级 码龄3年 15粉丝 38原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值