概念:
散列表(Hash table。也叫哈希表),是依据关键码值(Key value)而直接进行訪问的数据结构

也就是说,它通过把关键码值映射到表中一个位置来訪问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。给定表M,存在函数f(key)。对随意给定的keyword值key。代入函数后若能得到包括该keyword的记录在表中的地址,则称表M为哈希(Hash)表。函数f(key)为哈希(Hash)
函数

散列函数的选取:
1. 直接寻址法:取keyword或keyword的某个线性函数值为散列地址。

即H(key)=key或H(key) = a·key + b,当中a和b为常数(这样的散列函数叫做自身函数)。

若当中H(key)中已经有值了,就往下一个找。直到H(key)中没有值了。就放进去。

2. 数字分析法:分析一组数据。比方一组员工的出生年月日。这时我们发现出生年月日的前几位数字大体同样,这种话。出现冲突的几率就会非常大,可是我们发现年月日的后几位表示月份和详细日期的数字区别非常大,假设用后面的数字来构成散列地址,则冲突的几率会明显减少。因此数字分析法就是找出数字的规律,尽可能利用这些数据来构造冲突几率较低的散列地址。
3. 平方取中法:取keyword平方后的中间几位作为散列地址。
4. 折叠法:将keyword切割成位数同样的几部分,最后一部分位数能够不同,然后取这几部分的叠加和(去除进位)作为散列地址。数位叠加能够有移位叠加和间界叠加两种方法。移位叠加是将切割后的每一部分的最低位对齐,然后相加。间界叠加是从一端向还有一端沿切割界来回折叠,然后对齐相加。
5. 随机数法:选择一随机函数。取keyword的随机值作为散列地址。通经常使用于keyword长度不同的场合。
6. 除留余数法:取keyword被某个不大于散列表表长m的数p除后所得的余数为散列地址。

即 H(key) = key MOD p,p<=m。不仅能够对keyword直接取模,也可在折叠、平方取中等运算之后取模。对p的选择非常重要,一般取素数或m,若p选的不好,easy产生同义词。


处理冲突的方式:
1.开放寻址法:出现冲突时採用线性试探、伪随机试探等方式。

2.公共溢出区法:将冲突元素直接放入公共溢出区(公共溢出区也能够进行散列).
3.拉链法(链地址法):哈希表的每一个元素都是一个链表。出现冲突时直接挂到相应位置的链表上。
4.在散列法:再准备若干哈希函数。出现冲突时,使用其它哈希函数进行散列。
实现:

线性哈希表(採用了线性试探解决冲突问题)

/******************************
线性hash表
by Rowandjj
2014/7/14
******************************/
#include<iostream>
using namespace std;
#define MAX 20//hash表大小
typedef int DataType;
typedef struct _NODE_
{
DataType data;//方便起见,直接用int型。实际应用时应该是随意类型的
int flag;//1代表已有数据,0代表无数据
}HashNode,*pHashNode;
typedef struct _HASHTABLE_
{
pHashNode pHashNodeTemp;//实际存储数据的hash数组
int n;//hash表大小(总容量)
int cur_elem;//当前容量
}HashTable,*pHashTable;
int hashFunc(DataType key)//hash函数
{
int index = key/3+1;
index = (index < 0) ? -index : index;
return index;
}
bool CreateHashTable(pHashTable pHashTableTemp);
bool DestroyHashTable(pHashTable pHashTableTemp);
void InsertHashTable(pHashTable pHashTableTemp,DataType data,int (*hashFunc)(DataType));
int StatHashTable(HashTable HashTableTemp);//统计空项
void PrintHashTable(HashTable HashTableTemp);//输出hash表中的值
int SearchKey(HashTable HashTableTemp,DataType data,int (*hashFunc)(DataType));//依据数据查找其索引
int main()
{
int i;
int a[] = {9,31,26,1,13,2,11};
cout<<"原始序列:"<<endl;
for(i = 0; i < 7; i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
HashTable hashTable;
CreateHashTable(&hashTable);
for(i = 0; i < 7; i++)
{
InsertHashTable(&hashTable,a[i],hashFunc);
}
cout<<"散列后的序列:"<<endl;
PrintHashTable(hashTable);
DataType data;
while(cin>>data)
{
if(data == -1)
{
break;
}
cout<<"index = "<<SearchKey(hashTable,data,hashFunc);
} DestroyHashTable(&hashTable);
return 0;
}
bool CreateHashTable(pHashTable pHashTableTemp)
{
if(!pHashTableTemp)
{
return false;
}
pHashTableTemp->pHashNodeTemp = (pHashNode)malloc(sizeof(HashNode)*MAX);
if(!pHashTableTemp->pHashNodeTemp)
{
return false;
}
else
{
pHashTableTemp->n = MAX;
pHashTableTemp->cur_elem = 0;
for(int i = 0; i < pHashTableTemp->n; i++)
{
pHashTableTemp->pHashNodeTemp[i].flag = 0;
pHashTableTemp->pHashNodeTemp[i].data = -1;
}
}
return true;
}
bool DestroyHashTable(pHashTable pHashTableTemp)
{
if(pHashTableTemp != NULL)
{
free(pHashTableTemp->pHashNodeTemp);
pHashTableTemp->pHashNodeTemp = NULL;
pHashTableTemp->n = 0;
}
return true;
}
void InsertHashTable(pHashTable pHashTableTemp,DataType data,int (*hashFunc)(DataType))
{
if(!pHashTableTemp)
{
return;
}
if(StatHashTable(*pHashTableTemp) == 0)//当hash表满了的时候。能够选择扩容,这里直接返回
{
cout<<"hash表已满..."<<endl;
return;
}
int index = hashFunc(data) - 1;
while(pHashTableTemp->pHashNodeTemp[index].flag)//冲突时採用的是线性试探法
{
index = (index + 1)% pHashTableTemp->n;//防止越界
}
pHashTableTemp->pHashNodeTemp[index].data = data;
pHashTableTemp->pHashNodeTemp[index].flag = 1;
pHashTableTemp->cur_elem++;
}
int StatHashTable(HashTable HashTableTemp)
{
int i,count = 0;
for(i = 0; i < HashTableTemp.n; i++)
{
if(HashTableTemp.pHashNodeTemp[i].flag == 0)
{
count++;
}
}
return count;
}
void PrintHashTable(HashTable HashTableTemp)
{
int i;
for(i = 0; i < HashTableTemp.n; i++)
{
cout<<HashTableTemp.pHashNodeTemp[i].data<<" ";
}
cout<<endl;
}
int SearchKey(HashTable HashTableTemp,DataType data,int (*hashFunc)(DataType))
{
int index = hashFunc(data)-1;
int times = 0;
while(HashTableTemp.pHashNodeTemp[index].flag && HashTableTemp.pHashNodeTemp[index].data != data)
{
index = (index + 1)% HashTableTemp.n;
times ++;
if(times == HashTableTemp.n)
{
return -1;//没找到
}
}
return index;
}

測试:

hash表、hash算法的更多相关文章

  1. 栈 队列 hash表 堆 算法模板和相关题目

    什么是栈(Stack)? 栈(stack)是一种采用后进先出(LIFO,last in first out)策略的抽象数据结构.比如物流装车,后装的货物先卸,先转的货物后卸.栈在数据结构中的地位很重要 ...

  2. Hash表 hash table 又名散列表

    直接进去主题好了. 什么是哈希表? 哈希表(Hash table,也叫散列表),是根据key而直接进行访问的数据结构.也就是说,它通过把key映射到表中一个位置来访问记录,以加快查找的速度.这个映射函 ...

  3. 十一、从头到尾彻底解析Hash 表算法

    在研究MonetDB时深入的学习了hash算法,看了作者的文章很有感触,所以转发,希望能够使更多人受益! 十一.从头到尾彻底解析Hash 表算法 作者:July.wuliming.pkuoliver  ...

  4. 【数据结构】Hash表

    [数据结构]Hash表 Hash表也叫散列表,是一种线性数据结构.在一般情况下,可以用o(1)的时间复杂度进行数据的增删改查.在Java开发语言中,HashMap的底层就是一个散列表. 1. 什么是H ...

  5. 哈希表(Hash)的应用

    $hs=@() #定义数组 $hs=@{} #定义Hash表,使用哈希表的键可以直接访问对应的值,如 $hs["王五"] 或者 $hs.王五 的值为 75 $hs=@''@ #定义 ...

  6. Hash表算法

    出处:http://blog.csdn.net/v_JULY_v 第一部分:Top K 算法详解问题描述百度面试题:    搜索引擎会通过日志文件把用户每次检索使用的所有检索串都记录下来,每个查询串的 ...

  7. 从头到尾彻底解析Hash表算法

    作者:July.wuliming.pkuoliver 说明:本文分为三部分内容, 第一部分为一道百度面试题Top K算法的详解:第二部分为关于Hash表算法的详细阐述:第三部分为打造一个最快的Hash ...

  8. 从头到尾解析Hash表算法

    via:点击打开链接 十一.从头到尾解析Hash 表算法 作者:July.wuliming.pkuoliver   出处:http://blog.csdn.net/v_JULY_v.   说明:本文分 ...

  9. 从头到尾彻底解析Hash 表算法

    作者:July.wuliming.pkuoliver  出处:http://blog.csdn.net/v_JULY_v.  说明:本文分为三部分内容,    第一部分为一道百度面试题Top K算法的 ...

  10. (面试)Hash表算法十道海量数据处理面试题

    Hash表算法处理海量数据处理面试题 主要针对遇到的海量数据处理问题进行分析,参考互联网上的面试题及相关处理方法,归纳为三种问题 (1)数据量大,内存小情况处理方式(分而治之+Hash映射) (2)判 ...

随机推荐

  1. nmap -- write a nmap script

    漏洞扫描 --编写Nmap脚本 2006年12月份,Nmap4.21 ALPHA1版增加脚本引擎,并将其作为主线代码的一部分.NSE脚本库现在已经有400多个脚本.覆盖了各种不同的网络机制(从SMB漏 ...

  2. 系统没有“internet信息服务(IIS)管理器”

    系统没有“internet信息服务(IIS)管理器” | 浏览:8981 | 更新:2014-06-19 14:43 1 2 3 4 5 6 7 分步阅读 很多用户都在咨询:系统控制面板的管理工具中没 ...

  3. Mysql ODBC 5.1 Driver免安装脚本

    在使用Mysql 的时候,需要使用ODBC数据源的方式来连接mysql,所以常常需要用到免安装的驱动,自己参考官网的脚本, 修改了一个实用点的脚本,放出来大家一起分享: 安装mysql odbc 5. ...

  4. 解决xShell4某些情况下按删除键会输出^H的问题

    当我们用Xshell登录进入linux后,在普通模式下,对输入进行删除等操作没有问题. 而在执行中,按delete,backspace键时会产生^H等乱码问题. 这是由于编码不匹配的问题. 解决方法: ...

  5. Ello讲述Haar人脸检测:易懂、很详细、值得围观

    源地址:http://www.thinkface.cn/thread-142-1-1.html 由于工作需要,我开始研究人脸检测部分的算法,这期间断断续续地学习Haar分类器的训练以及检测过程,在这里 ...

  6. Hbase经常使用命令

    hbase shell命令的使用 再使用hbase 命令之前先检查一下hbase是否执行正常 hadoop@Master:/usr/hbase/bin$ jps 2640 HMaster 27170 ...

  7. 为什么 string.find()返回值是-1

    之前好像在哪里见到过这个问题,时间有点久,想不起来了,今天写字符串又碰到这个问题,书上给出的定义是当string.find()没有找到时返回的是一个非常大的值,网上有人说是-1,两种说法都对,由于整数 ...

  8. HDU 1231:最大连续子序列(DP)

    pid=1231">最大连续子序列 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Jav ...

  9. Computational Network Toolkit (CNTK) 是微软出品的开源深度学习工具包

    Computational Network Toolkit (CNTK) 是微软出品的开源深度学习工具包 用 CNTK 搞深度学习 (一) 入门 Computational Network Toolk ...

  10. Android的内存优化

    腾讯公司在五月三十一日开展[腾讯Bugly移动开发人员沙龙]大会.大会上面叶方正老师解说了 关于Android的内存优化的问题,只是我感觉叶老师许多其它的站在了測试的角度上去解释了这一方面,叶老师给我 ...