概念:
散列表(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. HttpSession具体解释

    session的机制 http是无状态的协议,客户每次读取web页面时,server都打开新的会话,并且server也不会自己主动维护客户的上下文信息,那么要怎么才干实现会话跟踪呢?session就是 ...

  2. INFORMIX 时间函数大全

    http://publib.boulder.ibm.com/infocenter/idshelp/v115/index.jsp?topic=/com.ibm.sqls.doc/ids_sqs_0187 ...

  3. QT 4.2.2的安装(安装完还要再编译,注意设置Windows Path)

    (安装篇)前奏: 提到C++的GUI Framework估计大多数人都会想到MFC.VCL,因为在十年前的COM时代,这两个大家伙几乎垄断了整个C++ windows平台上应用程序的开发市场, 但是最 ...

  4. 与众不同 windows phone (21) - Device(设备)之摄像头(拍摄照片, 录制视频)

    原文:与众不同 windows phone (21) - Device(设备)之摄像头(拍摄照片, 录制视频) [索引页][源码下载] 与众不同 windows phone (21) - Device ...

  5. gtk+blade+anjuta 的简单实例

    gtk+blade+anjuta 的简单实例我的系统 ubuntu 12.04   1>  选择源 不正确会有很多问题,速度慢,找不到安装的软件.163的源就不错 http://mirrors. ...

  6. phpStorm打开提示 failed to create JVM 的解决的方法

    phpStorm 软件打开执行提示 failed to create JVM的解决的方法. 改动文件 D:\Program Files (x86)\JetBrains\PhpStorm 7.1.3\b ...

  7. Unity3D游戏开发之开发游戏带来的问题

    昨日曾就某投资人把移动团队失败原因之中的一个归于选择Unity引擎进行了一番评论,工具本身无罪,但怎样理解工具.正确使用Unity引擎确实须要讨论,在选择Unity之前你也许须要了解下这个引擎实际开发 ...

  8. 欧舒丹 L'Occitane 活力清泉保湿面霜 - 男士护肤 - 香港草莓网StrawberryNET.com

    欧舒丹 L'Occitane 活力清泉保湿面霜 - 男士护肤 - 香港草莓网StrawberryNET.com 欧舒丹 活力清泉保湿面霜 50ml/1.7oz

  9. CacheHelper工具类的使用

    package com.bbcmart.util; import net.sf.ehcache.Cache; import net.sf.ehcache.CacheManager; import ne ...

  10. [linux]ubuntu apt-get安装软件失败

    1.首先查看 dns 配置 sudo vi /etc/resolv.conf nameserver 114.114.114.114 nameserver 8.8.8.8 2.修改 apt-get 源 ...