首先,哈希表的大致作用就是将一个较大值域中的值映射到另一个较小的范围内,这样做最直观的好处就是节省储存空间和减少查询的时间复杂度,鉴于作用对象的不同可以大致分为对整数的“存储结构”和对字符的“字符串哈希方式”。
我们先讨论整数哈希表,其中所用到的核心方法就是对大值域中的值取模,以此让它们来对应一个新的较小的值,但也因此必然会出现多个值映射到同一个值的情况,为此我们有两种方法来帮助我们梳理储存关系:“拉链法”和“开放寻址法”。
一、拉链法:
基本思想:构造出一条空值单链,也就是要投影的“小范围值域”,我称其为主链,当有重复的只出现时,就令它在接在对应主链位置已有值的旁边,形成一条新的支链,后来的重复值依次接在对应支链后面。
主要模板:
#include<iostream>
using namespace std;
const int N=100003;
int h[N],e[N],ne[N],idx;
memset(h,-1,sizeof h);
拉链法中N的取值标准:大于题目所给“小范围”数据的第一个质数,可以使得取模后对应值重复的情况最少。h为主链位置值,e为当前位置储存值。memset(h,-1,sizeof h)作用为将主链函数h中的值都清空。
向主链插入x值:
int k=(x%N+N)%N;
e[idx]=x;
ne[idx]=h[k];
h[k]=idx++;
k为x要插入的主链位置值,(x%N+N)%N是为使k为正数。原理与单链插入相同。
查询x是否出现过: