哈希表
散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。(定义来自百度百科)
哈希表将关键值映射到一个表中,是通过对当前的数进行进行模运算,并以运算后的值作为下标来映射。当然这也就不可避免的会使多个值同时映射成同一个数,就产生了冲突,而我们就需要对冲突进行处理。
根据处理冲突的方式将哈希表分成了两种方式:1.开放寻址法 2.拉链法。
开放寻址法:
对一个数进行求模构造之后,判断这个下标的值是否存在,如果不存在则将这个数映射到这个下标,如果存在则向后查找直至查找到一个不存在的下标,然后将这个数映射到这个下标。
其核心代码就是一个find函数
1 int find(int x) 2 { 3 int t=(x%N+N)%N; 4 while(q[t]!=null&&q[t]!=x)//当这个数映射的下标代表的值不存在或者这个数已经存在时结束循环 5 { 6 t++;//当前下标代表的值存在则向下继续查找 7 if(t==N) t=0; //当已经找到最后之后要从最开始继续找 8 } 9 return t;//返回这个下标 10 }
拉链法:
拉链法的存储方式和树和图的存储方式一模一样,就是使用一个邻接表来储存,将每个数映射成一个下标,并在这里建立一个链表,将这个数插入到头结点位置。
包含两个操作:1.插入 2.查询。
1 int h[N],ne[N],e[N],idx;//使用链表来储存 2 void insert(int x)//插入到头结点的位置 3 { 4 int t=(n%N+N)%N; 5 e[idx]=t; 6 ne[idx]=h[t]; 7 h[t]=idx++; 8 } 9 bool find(int x) 10 { 11 int t=(x%N+N)%N; 12 for(int i=h[t];i!=-1;i=ne[i])//从头节点开始查找 13 if(e[i]==x) return true;//如果查找到返回true 14 return false;//否则返回false 15 }