概念:
散列表(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. BZOJ 2096([Poi2010]Pilots-单调队列-差值)

    2096: [Poi2010]Pilots Time Limit: 30 Sec   Memory Limit: 162 MB Submit: 190   Solved: 97 [ Submit][ ...

  2. Html 内嵌 选择器属性 Dom操作 JavaScript 事件

    HTML标签: 一.通用标签(一般标签) 1.格式控制标签 <font color="#6699aa" face="楷体" size="24&q ...

  3. svn跨机备份

    #!/bin/sh svn_bak_dir='/svndata/cloudil' svn_server='svn://172.16.40.200:9999' user=adminread pass=a ...

  4. 多图真相:Adobe Dreamweaver CC 2014.1来了-体验卓越PSD提取和诸多精彩云功能!

     作为经典的web开发工具,DW此次版本号更新提供了更加丰富的云功能,是网页开发人员的利器! 直接发多图(来源:zoomla!逐浪CMS UED): watermark/2/text/aHR0cD ...

  5. POJ 1159 - Palindrome 优化空间LCS

    将原串和其逆序串的最长公共子序列求出来为M..那么2*n-M就是所需要加的最少字符..因为求出的M就是指的原串中"潜伏"的最长回文.. 问题转化为求LCS..但是n最大到5000. ...

  6. memwatch的使用

    博主的新Blog地址:http://www.brantchen.com 欢迎訪问:) linux下的測试工具真是少之又少,还不好用,近期试用了memwatch,感觉网上的介绍不太好,所以放在这里跟大家 ...

  7. margin 等高布局

    <div id="main"> <div id="left"> 我是左边的内容的啦啦啦啦... .<br> 我是左边的内容的 ...

  8. [android]APP启动界面——SplashActivity

    概念 当前应用程序在启动的时候都会有一个展示自己公司LOGO和APP名字的界面.这个界面成为SplashActivity. 布局 <? xml version="1.0" e ...

  9. TMS320F28335项目开发记录5_28335之CCS编程基础

    CCS开发环境已经为我们封装好了很多片内外设寄存器的结构体,我们仅仅须要包括对应的官方的头文件就能够使用了,那么它的内部详细是怎样实现的呢? 以下来一个典型的样例: 1.使用结构体和联合体 A.用st ...

  10. asp.net mvc4中自定义404页面

    原文地址:http://www.chuchur.com/asp-net-mvc4-404/ 定义404 方法当然有很多种.不同的方法所展现的形式也不一样,用户所体验也不一样.以下提供2两种 方法一: ...