哈希就是将数组的易访问和链表的易查询和修改结合在一起了。
试想这样的场景,你很想学太极拳,听说学校有个叫张三丰的人打得特别好,于是你到学校学生处找人,学生处的工作人员可能会拿出学生名单,一个一个地查找,最终告诉你,学校没这个人,并说张三丰几百年前就已经在武当山作古了。可如果你找对了人,比如片在操场上找那些爱运动的同学,人家会告诉你,"哦,你找张三丰呀,有有有,我带你去。"于是他把你带到了体育馆内,并告诉你,那个教大家打太极的小伙子就是"张三丰",原来"张三丰"是因为他太极拳打得好而得到的外号。
一、基础概念

大概就是先创建一个数组用来放关键字(因为将要存的数据对10求余可以将其全部控制在0-9之间,那么这个值其实就是相当于前面举例中爱运动的同学)然后再通过链表存储跟这个关键字有关的数据。当然肯定不能不管多少数都只用这10个哈希桶数组,具体使用如下。

哈希就相当于是对数据做了一些处理(这里主要是指某些计算,例如直接定址法,数字分析法,平方取中法,折叠法,随机数法,除留取余法),能让他们和放他们地址的下标对应起来,那么在找数据的时候只要对你要找的数据做相同处理,就能直接找到下标,然后一次就能找到数据。
二、代码实现
1.结构体创建

这里我们需要一个链表节点的结构体,和一个创建在栈上的数组。
2.创建

将所有的数据依次进行处理,然后为其开一块空间,然后将其插入链表中。主要还是要理解前面第一张图,数组里面放的是链表的首地址,链表中存的数据,方便增删。
3.打印

即遍历整个哈希表,将其打印出来
打印效果如下

4.查找

查找需要先算出查找的值的addr然后再判断这个链表是否有这个值,如果链表中没有这个数据最后p会指向NULL,所以直接返回p即可,如果有这个值则直接返回这个值的地址。
5.更新

更新就是在找到这个值之后再对这个值进行修改,与查找只有一点点区别。
6.删除

这里要分的情况比较多,首先根据待删除数据对哈希表长度取余算出对应的哈希下标,若该下标对应的链表为空,则说明数据不存在,直接返回删除失败;若链表存在,先判断链表仅有单个节点且该节点即为目标数据时,将哈希数组对应下标置空并释放节点内存;若链表存在多个节点且头节点就是待删数据,则将哈希表头指针后移并释放原头节点;若目标数据在链表中间或尾部,就循环遍历链表,不断移动指针直至后继节点为空或是找到目标数据,遍历结束后若无匹配数据则删除失败,找到后暂存待删节点,修改前驱节点指针跳过该节点,释放节点内存,最终删除完成返回成功。
7.销毁

销毁需要先销毁链表部分,因为数组是在栈上创建的,可以做到自动申请自动释放,所以仅需销毁链表。