散装学习日记之Hash表的初步理解

Hash表是什么东西

说白了就是数据存储的一种方式,一般存储方式都有变量,直接int a = 0;
数组int a[2] = {0,1};
链表,
typedef struct Node {
int a ;
struct Node *Node};
好像是这么写,知道有这个就行
连续的内存空间,用一个指针表示首地址,int *p = malloc();

这种类型的吧,存数据也是往这里面存,比如你想存好多人的手机号,
张三,13866660001
李四,13866660020
王五,13866660053

这几个人你可以定义一个结构体存,也可以定义一个长度为3的链表存储,也可以定义二维数组存储,有好多种方式可以存。

但问题出现了,我现在想要王五的联系方式,而且就给你1秒钟,你给我找出来,1秒钟就让你找一次,怎么找?

如果是普通的存储方式,你得一个个的去比对,哪个是王五啊,比对上了,找到王五了,再把手机号取出来,但如果是你们村里人的手机号呢,你找的那个人正好存在最后一个,那你不得比对全村人的名字才能找到,多浪费时间。

有个办法可以减少一些时间,把名称按拼音顺序排列起来,然后通过二分查找的办法,能节省一些时间,反正不用一个一个的比对了,大致可以判断王五在哪个区域,然后判断是在前面还是在后面,再继续查找。

但是还想更快一旦,所以发明出了这一种办法,我按照你名字的第二个字顺序存储手机号,然后我建立一个长度为5的存储空间,把手机号存进去,这样我查王五,直接就可以查找第五个数据就是王五的手机号了,把王五映射为第五个数据的映射关系叫做哈希函数,长度为5的存储空间叫做哈希表,说白了就是存数据的一种方式。

但问题又来了,我有整个村子的人名和手机号,该怎么存,也不能每个人都叫数字吧,万一叫李铁柱呢,怎么存储呢,方法总是有的,其实映射关系是最重要的,怎么取这个映射,也就是怎么取这个哈希函数,我们可以把李铁柱的ASCII码拿出来,然后进行取余运算,或者取中间几位,反正村子里的人运算之后的值都不一样就可以,然后顺序存储,也可以直接找到某个人的手机号。

但问题又出现了,万一两个人无论怎么取哈希函数,计算得到的数都一样,怎么办,那也就是说无论我们怎么映射这个李铁柱,最后结果和王狗蛋的值都一样,他俩分不开了怎么办,没关系还有办法,分不开就分不开,我们把他俩紧挨着存储,计算之后的值放一个李铁柱,紧接着地址+1存储王狗蛋的手机号,剩下的都往后顺延一个,这样你如果找王狗蛋,会先找到李铁柱,发现不是,那你就往后找一个,就会找到王狗蛋,如果还不是,那就再往后找一个,肯定能找到,如果找太多怎么办,那我建议你换个函数做映射, 假如你这100个人,最后计算的值都一样,都往后顺延,那和数组存储没啥区别了,也别提啥缩短时间了,这个叫做哈希冲突,两个数据冲突了,另一个数据只能接着上一个存储,往后顺延,这是个解决办法。

最后要说明的是,我们对数据存储的目标就是,我想要查找哪个数据,必须以最快的速度找出来,越快越好,存储空间还不能太大,要不浪费,在这个基础上发展出来的哈希表的存储方式,时间挺快,存储空间不大,这是我们需要的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值