数据结构算法-哈希表技术点
引言
小森是一名 “ikun科技大制作创作者” 但有自己的团队 团队有20个人, 4个人为一组 ,一共有五组
分别为 策划组, 制作组, 配音组 ,编剧组, 调音组
为了方便就为每一个组的人就起了编号 以后方便"考察每个人是否工作"
可以看到效率大大的提高工作效率 ,当然真ikun 是真的为爱发电做出来:第一个 “科你太美PV”" 来致敬科比,
当然由于科技含量,最大化 最终真正出来"科技小森寻找科比"这个"游戏"
接下来 “科技小森寻找科比” 可能还得扩展到"鹰酱",并且在文化和科技反复碾压",让他们非常服
突然"科技小森工作室"宣布和"米啊游"合并 并且打造 “ikun文化” 让"ikun 文化名扬万朽"
在这不愧是"我森哥的格局最大"
从这里让人明白了一个关键点: 分散的重要性 就是非常好查找数据
肯定某个组有人因为薪资问题离开,这就恰到好处,无论是哪个组哪个人都会有编号
比如说"配音组里的1002 因为薪资问题.未能得到解决",那只好辞退Ta 并且赔偿一些费用
非常快速把ta从数字存储引擎把Ta的个人档案销毁
以下这种情景,我想一定能撬开阁下的嘴(,哈哈哈,笑不活了)
好了 该到打退骚针的时候 那么 这算不算是本文章的主题?
当然算,不然我怎么可能会说出来呢 (注意看 这个作者 有点骚 需打一针 ,退骚针就好了)
哈希表原理
哈希表也称之为散列表
顺序表和链表的结合体 重温 一下 顺序表 的优点 :可控范围随机访问 链表的优点 :插入非常快 删除非常快
所以说链表和顺序表是互补的,
将二者合二为一 就变成 哈希表
可以看到,这就是一个指针数组 维护一大堆的链表
你需要知道的是: 数据如何插入和删除
难道顺着插入?
要是这样的话 还不如用链表
所以引用 “哈希函数”
“哈希函数”: 将数据转化为数字 映射到哈希表里的一种函数 也就是说 将数据转化为序号,最后插入到哈希表
哈希函数 可以多种多样 最多用的是取余
这对于通用的数据来采取的方式
哈希桶:存放链表的数组 或者 顺序表的数组
数据:采用键值(key/value)对的方式,键是哈希桶的编号 值是对应的数据,
这种非常神奇神奇到忽略不计去 哈哈
这种方式可能非常快速的找到对应的数据
通过上面的引言都知道 组就是键,数据是员工编号
我们的指纹识别就是用了这样的哈希表原理
音乐的听歌识曲也用了底层算法,所以现在知道为啥第一次办理身份证的时候就录入指纹 只要你一旦犯罪 人民警察会通过指纹快速查找到犯罪嫌疑人
哈希表算法实现
哈希链表定义
- 数据的定义
using Key = int;using Value = use define;//哈希数据
struct HashValue{Key key;Value value;
};struct LinkNode{HashValue MyHashValue;LinkNode*Next;
};
//哈希表元素类型
using HashElement=LinkNode*;
哈希表定义
//默认桶空间容量
const int default_BucketSpaceSize = 16;//哈希桶
using HashBucket = HashElement*;//哈希表
struct HashTable{HashBucket BucketSpace;//桶空间size_t BucketSpaceSize;//桶空间大小
};
哈希链表创建算法
bool CreateHashTable(HashTable& HashTable, int BucketSpaceSize) {BucketSpaceSize = BucketSpaceSize <= 0 ? default_BucketSpaceSize : (BucketSpaceSize > default_BucketSpaceSize ? BucketSpaceSize : default_BucketSpaceSize);HashBucket BucketSpace = HashTable.BucketSpace = (HashElement*)malloc(sizeof(HashBucket) * (HashTable.BucketSpaceSize = BucketSpaceSize));if (BucketSpace) {for (size_t i = 0; i < BucketSpaceSize; i++) {BucketSpace[i] = (HashElement)malloc(sizeof(HashElement));*BucketSpace[i] = { };}return true;}return false;}
哈希链表插入算法
首先 我们需要数据 那么得需要创建 按照我以前的骚操作文章,肯定得用创建哈希数据函数
创建哈希数据
//创建哈希数值类型
HashValue CreateHashValue(Key key, Value value){return { key,value };
}
创建哈希数据 之后该插入了
bool HashTableInsert(HashTable& HashTable, HashValue &&Val){HashBucket BucketSpace = HashTable.BucketSpace;//查找哈希表里的key是否能找到HashElement Find = HashTablFind(HashTable, Val.key);if (Find){RunNotFound(__func__, std::string("调用出现了问题! 问题的 \n") + "原因是" + std::to_string(Val.key) + "存在");return false;}int HashIndex = Hash(Val, HashTable);HashElement elementList = BucketSpace[HashIndex];HashElement Newelement = CreateHashElement(Val, elementList->Next);//采用前面插入elementList->Next = Newelement;return true;
}
首先 查找不用看 一开始有数据可查? 并没有吧 这里就跳过 不要在意这些细节
int HashIndex = Hash(Val, HashTable);
从哈希函数提取哈希表 的 索引
int Hash(const HashValue& hashValue, const HashTable& HashTable){return hashValue.key % HashTable.BucketSpaceSize;
}
获取哈希表的元素(当然你们也知道,就不必要介绍这些骚操作)
HashElement elementList = BucketSpace[HashIndex];
你们都懂 就没必要可说的
HashElement Newelement = CreateHashElement(Val, elementList->Next);
//声明 Next默认是空指针
static HashElement CreateHashElement(HashValue& val, LinkNode* Next = nullptr);static HashElement CreateHashElement(HashValue& val, LinkNode*Next){HashElement Element = (LinkNode*)malloc(sizeof(LinkNode));if (Element){*Element = { val ,Next };}else{std::cout << (std::string(__func__) + "调用失败! 原因是分配内存失败") << std::endl;abort();}return Element;
}
优化 创建哈希表函数
bool CreateHashTable(HashTable& HashTable, int BucketSpaceSize) {BucketSpaceSize = BucketSpaceSize <= 0 ? default_BucketSpaceSize : (BucketSpaceSize > default_BucketSpaceSize ? BucketSpaceSize : default_BucketSpaceSize);HashTable.BucketSpace = CreateHashBucket((HashTable.BucketSpaceSize = BucketSpaceSize));if (HashTable.BucketSpace){return true;}HashTable.BucketSpaceSize = 0;return false;}
增加 CreateHashBucket函数
static HashBucket CreateHashBucket(size_t& BucketSpaceSize) {//分配哈希桶空间HashBucket BucketSpace = (HashElement*)malloc(sizeof(HashBucket) * ( BucketSpaceSize));HashValue TempVal = {};//创建临时值if (BucketSpace) {//创建哈希元素并且保存到哈希桶空间内//初始化哈希桶空间for (size_t i = 0; i < B ucketSpaceSize; i++) {BucketSpace[i]= CreateHashElement(TempVal);}}return BucketSpace;
}
此操作只是优化 并不代表没有什么,保持原来的就好了
头部插入最简单高效的办法
在这里不考虑扩大,哈希桶的容量
哈希链表查找算法
通过key对应的哈希元素
HashElement HashTablFind(const HashTable& HashTable, Key key){HashBucket BucketSpace = HashTable.BucketSpace;int HashIndex = Hash({ key }, HashTable);HashElement HashElementList = BucketSpace[HashIndex];HashElementList = HashElementList->Next;while (HashElementList && HashElementList->MyValue.key!=key){HashElementList = HashElementList->Next;}return HashElementList;
}
通过key找到对应的value
Value HashTableKeyToValue(const HashTable& HashTable, Key key){HashElement Element = HashTablFind(HashTable, key);if (!Element) {RunNotFound(__func__, (std::string(" 函数 出错误 :没有这个键值为: ") + std::to_string(key) + " 的数据"));//记住销毁哈希表abort();}return Element->MyValue.value;
}
哈希表删除算法
//查找key的元素前驱结点 带删除的结点
static HashElement HashTablFindElementNodePrev(const HashTable& HashTable, Key key,LinkNode*&Node) {HashBucket BucketSpace = HashTable.BucketSpace;int HashIndex = Hash({ key }, HashTable);HashElement HashElementList = BucketSpace[HashIndex];HashElement Prev = HashElementList;HashElementList = HashElementList->Next;Node = nullptr;while (HashElementList && HashElementList->MyValue.key != key) {Prev = HashElementList;HashElementList = HashElementList->Next;}Node = HashElementList;return Prev;
}//哈希表删除算法
void HashTableDelete(HashTable& HashTable, Key key) {HashElement DeleteNode;HashElement DeleteNodePrev = HashTableFindElementNodePrev(HashTable, key, DeleteNode);if (DeleteNode) {DeleteNodePrev->Next = DeleteNode->Next;free(DeleteNode);}
}
哈希表销毁算法
//
static void HashElementDestroy(HashElement& HashElementList);void HashTableDestroy(HashTable& HashTable){if (HashTable.BucketSpace ) {for (size_t i = 0; i < HashTable.BucketSpaceSize; i++) {HashElementDestroy(HashTable.BucketSpace[i]);}free(HashTable.BucketSpace);HashTable = {};}
}void HashElementDestroy(HashElement& HashElementList) {while (HashElementList) {LinkNode* Next = HashElementList->Next;free(HashElementList);HashElementList = Next;}}
哈希顺序表算法实现
虽然链表方式最骚的实现,但插入和删除效率极高 我也无法反驳 但放松了一个月的我来说:虽然 效率不高但实现起来也并不复杂,但我一直没找到,虽然有二分查找法但用了之后的…就没法展开,所以停顿了一段时间,
(好吧,其实我是玩GPT 还有new Bing 虽然说可能没啥可建议的 但也有点帮助)
总之这一个月.我啥也没干[
数据结构算法-哈希表技术点相关推荐
- 【数据结构】哈希表的概念及应用
[数据结构]哈希表的概念及应用 前言 1.写出哈希表的基本概念 2.列出常用的哈希函数构造方法,并阐述各自的特点. 直接定址法 除留余数法 数字分析法 其他构造整数关键字的哈希函数的方法: 平方取中法 ...
- 图书馆管理系统(C、数据结构、哈希表、文件IO)
目录 技术路线 实现效果展示 程序主体 1.头文件部分 2.自定义函数定义部分 3.main函数部分 注意 技术路线 数据结构.哈希表.文件IO 通过C语言进行程序设计,有用到数据结构中的哈希表,通 ...
- 用c语言实现基本数据结构(哈希表)
用c语言实现基本数据结构(哈希表) 写这个哈希表总是段错误,找了半天的bug...原来是各种小错误不断,写得很蛋疼. 我是是用数组实现的,数组的最大值定义成的宏.一共只有四个函数,分别为初始化哈希表, ...
- C++八股文分享---数据结构其二---哈希表
C++八股文分享-数据结构其二-哈希表 前言 什么是哈希表? 搜索二叉树对值的查找是通过从根节点开始,逐个节点与目标值做比较,向下查找,直至找到目标值或是到达根节点未查找到,时间复杂度为O(logn) ...
- 「Redis数据结构」哈希表(Dict)
「Redis数据结构」哈希表(Dict) 文章目录 「Redis数据结构」哈希表(Dict) @[toc] 一.概述 二.结构 三.哈希冲突 四.链式哈希 五.rehash 六. 渐进式 rehash ...
- 数据结构之哈希表以及常用哈希的算法表达(含全部代码)
目录 为什么要有哈希 哈希表 含义 创建哈希表需要注意的点 算法的选择 哈希冲突的处理 线性探测法 再哈希法 链表法 哈希表的实现(代码部分) 确定结构体(节点) 准备一个哈希算法 创建一个哈希表(即 ...
- 数据结构与算法——哈希表与字符串
文章目录 1.预备知识 1.1 最简单的哈希--统计字符个数 1.2 哈希表排序整数 1.3 哈希映射的问题 2.最长回文串 2.1 题目描述 2.2 C++代码实现 3.单词规律 3.1 题目描述 ...
- python hash表_python数据结构与算法——哈希表
哈希表 学习笔记 参考翻译自:<复杂性思考> 及对应的online版本:http://greenteapress.com/complexity/html/thinkcomplexity00 ...
- 【技术点】数据结构(六) -- 哈希表
文章目录 简介 哈希函数 直接寻址法 取模法 其他 冲突的处理 链地址法 开放地址法 其他 实例 JAVA中的哈希表 Entry对象 & 哈希映射方法 映射计算方法 冲突解决办法 - Hash ...
最新文章
- 谷歌AI专家爆料:90%的人都不知道,写不出好代码,是输在了这点上!
- 关于欧盟的芯片法案,ASML是这样看的!
- Building High Performance Websites (1) CDN
- c# export server 调用sql_[转]使用C#调用cmd来执行sql脚本
- ES6箭头函数中的this指向
- linux怎么删干净mysql,linux怎么干净卸载mysql
- PHP方向+go+rpc+swoole,瞅瞅 PHP+Swoole 作为网络通信框架
- Android官方开发文档Training系列课程中文版:OpenGL绘图之图形定义
- pd调节规律_pid算法原理及调整规律解析
- IM开发基础知识补课:正确理解前置HTTP SSO单点登陆接口的原理
- 啃碎并发(二):Java线程的生命周期
- java 小根堆 排序_堆排序(java实现)
- 彻底卸载删除微软Win10易升方法
- 汽车自动驾驶是人工智能吗,自动驾驶是人工智能
- ES6 --promise了解
- 通过域名查询该域名的ip
- 计算机学后感作文400,科技展观后感作文400字(精选7篇)
- 神经网络的5个应用场景,人工神经网络实际应用
- 微信怎么更改绑定的游戏服务器,注意啦!微信号可以改了!这里还有一个新功能...
- stm32f072的spi的设置注意事项。
热门文章
- Mastering_the_FreeRTOS_Real_Time_Kernel-A_Hands-On_Tutorial_Guide 阅读翻译(一)
- 成功解决 无法访问服务器端口问题
- java bitmap图片_Bitmap图片的处理
- S7-1200与S7-200SMART S7通信
- MySQL数据库1067 问题
- [转载]海康摄像头sdk与web教程
- extjs4 ie6 ie7 ie8 显示异常解决
- Consider defining a bean of type 'redis.clients.jedis.JedisPool' in your configuration.
- html播放url音乐,什么是正确的音乐播放URL地址
- 那些值得收藏的神奇的网站,使用RSS阅读器订阅喜欢的网站 --授人以鱼不如授人以渔...