数据结构之hash查找

来源:互联网 发布:抓鸡软件 编辑:程序博客网 时间:2024/05/16 01:40

哈希查找,也称为散列查找(本文以哈希称呼)。提起哈希,我的第一印象就是C#中的Hashtable类,它是由一组key/value的键值对组成的集合,它就是应用了散列技术。

那么,什么是哈希查找呢?在弄清楚什么是哈希查找之前,我们要弄清楚哈希技术,哈希技术是在记录的存储位置和记录的关键字之间建立一个确定的对应关系f,使得每个关键字key对应一个存储位置f(key)。查找时,根据这个确定的对应关系找到给定值的映射f(key),若查找集合中存在这个记录,则必定在f(key)的位置上。哈希技术既是一种存储方法,也是一种查找方法。

六种哈希函数的构造方法:

1,直接定址法:

函数公式:f(key)=a*key+b (a,b为常数)

这种方法的优点是:简单,均匀,不会产生冲突。但是需要事先知道关键字的分布情况,适合查找表较小并且连续的情况。

2,数字分析法:

比如我们的11位手机号码“136XXXX7887”,其中前三位是接入号,一般对应不同运营公司的子品牌,如130是联通如意通,136是移动神州行,153是电信等。中间四们是HLR识别号,表示用户归属地。最后四们才是真正的用户号。

若我们现在要存储某家公司员工登记表,如果用手机号码作为关键字,那么极有可能前7位都是相同的,所以我们选择后面的四们作为哈希地址就是不错的选择。

3,平方取中法:

故名思义,比如关键字是1234,那么它的平方就是1522756,再抽取中间的3位就是227作为哈希地址。

4,折叠法:

折叠法是将关键字从左到右分割成位数相等的几个部分(最后一部分位数不够可以短些),然后将这几部分叠加求和,并按哈希表表长,取后几位作为哈希地址。

比如我们的关键字是9876543210,哈希表表长三位,我们将它分为四组,987|654|321|0 ,然后将它们叠加求和987+654+321+0=1962,再求后3位即得到哈希地址为962,哈哈,是不是很有意思。

5,除留余数法:

函数公式:f(key)=key mod p (p<=m)m为哈希表表长。

hash算法的精髓

hash算法精髓在key的全集较大,而实际结果集远小于全集,hash将一个大范围的结果集缩小到一个小的结果集中,hash值相同的key值放在一个数组中去,更便于key值命中,以概率论,时间复杂度为O(1),

上代码! 在vs2015上做的

hash table的创建

void CHashSearchDlg::creathash(int key){    int pos, t;    pos = func(key);                                //哈希函数确定元素的位置    t = pos;    while (hashtable[t] !=  - 1)    //如果该位置有元素存在则进行线性探测再散列    {        t = (t + 1) % Max;        if (pos == t)   //如果冲突处理后确定的位置与原位置相同则说明哈希表已满        {            m_Text += "哈希表已满\r\n";            return ;        }    }    hashtable[t] = key;                             //将元素放入确定的位置}

实现hash查找

int CHashSearchDlg::search(int key){    int pos, t;    pos = func(key);                                    //哈希函数确定出的位置    t = pos;                                        //t存放确定出的位置    while (hashtable[t] != key && hashtable[t] !=  - 1) //如果该位置上不等于要查找的关键字且不为空    {        t = (t + 1) % Max;                              //利用线性探测求出下一个位置        if (pos == t)   //如果经多次探测又回到原来用哈希函数求出的位置则说明要查找的数不存在        {            return  - 1;        }    }    if (hashtable[t] ==  - 1)   //如果探测的位置是-1则说明要查找的数不存在    {        return NULL;    }    else    {        return t;    }}
原创粉丝点击