哈希开链法详解c++
一、概述
这是哈希的一种算法,算是冲突比较少的,但是也难免会有。
这是我们需要探究的问题,开链法就是好方法之一。
开链法原理比较简单,代码比较玄学,大家要在学习的过程之中动手模拟,才能完全掌握它。
int hash(string h)
{int seed=37,p=10007;int ans=0;int len=h.length();for(int i=0;i<n;i++){ans=(ans*seed+h[i]-'0')%p;}return ans;
}
二、原理分析
结构假如要用形象来表示,就如下图所示:
假如说我们要对以下一些数据进行哈希储存(%53):
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
0 | 3 | 51 | 53 | 55 | 105 | 106 | 2 | 52 |
0 | 3 | 51 | 0 | 2 | 52 | 0 | 2 | 52 |
*第一行是编号,第二行是原始数据,第三行是哈希后结果。
按开链法储存之后如图所示:
三、代码讲解
原理十分简明,而代码却不好实现,需要大家细细揣摩。
操作时代码从下向上看的!
首先,关于hash的大多数程序实现都离不开两个数组:
first[i]:表示哈希值为i的第一个数的下标(用来记录第i列最末的数据是第几个输入的)
next[i]:表示第i个数据的下一个数据(用来记录第i个数的上方)
就拿第一列来说吧
当读入0时 first[0]=1;next1]=0;
当读入53时 first[0]=2;next[2]=1;
当读入106时 first[0]=3;next[3]=2;
比如说我要进行查找,会从first[hash(h)]开始,逐个向上查找。
四、程序设计
对于一个程序来说,有一些基本操作是需要掌握的,难度主要是while的操作和两个数组的相关性。
部分代码个人感觉为玄学操作,建议带入模拟一下。
给个哈希简单代码,之后的程序围绕它来展开:
int hash(string h)
{int seed=37,p=10007;int ans=0;int len=h.length();for(int i=0;i<n;i++){ans=(ans*seed+h[i]-'0')%p;}return ans;
}
1、插入
尤其注意两个数之间的关系,建议带数据模拟!
int add(string h)
{int sum=hash(h);//用sum来记录该数据所存的数组 int u=first[sum];//这个主要用于下一步的去重 while(u)//这一步用来去重,原理是借组next数组枚举查找,这个while是比较巧妙的写法 {if(data[u]==h)//一模一样 return 0;//返回 u=next[u];//使用next数组接着往下(也就是上)找 }++cnt;//这是添加的第几个数据 data[cnt]=h;//将原始数据保存在data数组中,也就是在for循环时就直接对输入进行操作//下面两步个人认为有点链式结构的感觉 ,难点就是这里 next[cnt]=first[sum];//第cnt个数据的下(也就是上)一个数据是第几个cnt first[sum]=cnt;//更新本数列最下端的数为第几cnt return 1;//成功添加
}
2、查找
插入的翻版,对while判定的改变。
int find(string h)
{int sum=hash(h);//同上 int u=hash[sum];//同上 while(u)//注意改变 {if(data[u]==h)//如果有 return 1;//tureu=next[u];//接着找 }return 0;//都没有就为假
}
3、删除
本板块的难点在pre上。
void delete(string h)
{int sum=hash(h);//找到它的列 int pre,u;//pre的作用是判断删除的是不是头结点,u还是记录它上面的值 pre=u=first[sum];//记录 while(u){if(data[u]==h) break;//找到了这个数据,往下走//这两步可以使u比pre早一个版本 pre=u;u=next[u];}if(pre==u) first[sum]=next[u];//删除的节点是头结点,队列末尾位次编号修改一下 else next[pre]=next[u];//删除的节点不是头结点 ,链表中捡摘除一部分后重新链接
}
哈希开链法详解c++相关推荐
- 安卓miracast花屏_创维酷开电视多屏互动Miracast玩法详解
创维酷开电视多屏互动Miracast玩法详解 安卓手机是可以通过多屏互动Miracast玩法直接让我们手机与创维酷开电视进行无线投屏的,但是有些创维电视的Miracast功能找不到怎么办? 创维酷开电 ...
- 视频教程-沐风老师3DMAX室内建模挤出法详解-3Dmax
沐风老师3DMAX室内建模挤出法详解 沐风课堂创始人,专栏作家,独立媒体人,资深互联网从业者. 沐风老师 ¥12.00 立即订阅 扫码下载「CSDN程序员学院APP」,1000+技术好课免费看 APP ...
- 单链表的头尾插法详解
单链表头尾插法详解 头插法构造单链表 代码实现 头插法过程 尾插法构造单链表 代码实现 尾插法过程 单链表头尾插法对比 #include "stdio.h" #include &q ...
- 一致性哈希算法原理详解
一.普通 hash 算法 (取模算法): 在了解一致性哈希算法之前,我们先了解一下缓存中的一个应用场景,了解了这个应用场景之后,再来理解一致性哈希算法,就容易多了,也更能体现出一致性哈希算法的优点,那 ...
- java指数表示法_Java指数计数法详解
Java指数计数法详解 时间:2017-10-16 来源:华清远见Java培训中心 Java指数计数法并不是一个很难的运算,关键是你要理解应用,很多朋友不理解Java指数计数法,所以也无从运用 ...
- 创维linux怎么连接wifi,创维酷开电视多屏互动Miracast玩法详解
创维酷开电视多屏互动Miracast玩法详解 安卓手机是可以通过多屏互动Miracast玩法直接让我们手机与创维酷开电视进行无线投屏的,但是有些创维电视的Miracast功能找不到怎么办? 创维酷开电 ...
- 一文速学数模-时序预测模型(四)二次指数平滑法和三次指数平滑法详解+Python代码实现
目录 前言 二次指数平滑法(Holt's linear trend method) 1.定义 2.公式 二次指数平滑值: 二次指数平滑数学模型: 3.案例实现 三次指数平滑法(Holt-Winters ...
- 【算法学习】欧几里得算法详解(包括扩展、同余方程)
欧几里得算法详解(包括扩展.同余方程) 1.普通欧几里得算法(求最大公约数) 2.扩展欧几里得算法(求解a*x+b*y=c中(x,y)) 3.同余方程 1.普通欧几里得算法(求最大公约数) 欧几里得算 ...
- 机箱主板跳线接法详解(图) (机箱面板的POWER LED线,POWER SW线,HD线,RESET线,usb线)
机箱主板跳线接法详解(图) 作为一名新手,要真正从头组装好自己的电脑并不容易,也许你知道CPU应该插哪儿,内存应该插哪儿,但遇到一排排复杂跳线的时候,很多新手都不知道如何下手. 钥匙开机其实并不神秘 ...
最新文章
- Eclipse 安装 lombok
- 场效应晶体管的几点使用知识!
- OpenvSwitch — 安装部署与基本操作
- python基础语法有哪些-Python基础语法
- 产生数(floyd+高精度计算)
- Tomcat到Wildfly:配置数据库连接
- jp摩根的人都在学python么_摩根大通已要求所有资管部门员工必须学习编程
- 电机控制系统php,电机控制系统的未来发展变化趋势
- Linux 服务器高级编程ET LT代码
- [转载]在 WPF 專案中開啟 Blend
- 2017.10.5 最短母串 思考记录
- QEventLoop进行函数运行进度控制
- 核心频率个加速频率_AMD 32核心频率飞起!Intel
- HTTP协议基本原理简介(一)
- 基于Android的阳台浇花控制系统设计
- 3dmax9.0 简体中文正式版(官方非汉化版本)下载网址
- TCP网络错误Connection reset by peer,peer是啥意思呢
- 定了,6大领域93个开源任务,阿里开源导师带你参与中科院开源之夏2022
- [HTML+Bootstrap+CSS+jQuery] 时差计算器(计算时差、验证格式、当前时间、历史记录……)
- Classic Shell不起作用(失效)的解决