【数据结构】散列表-hash

散列表-hash

散列表的直观感受就是用一个有几个分格的书架摆放一堆各种各样的书。
我们试图把同一类书放到一起,
又试图把他们成尽可能多的类,以方便我们能完全按照格子的分类检索。


对于使用不同分类方法生成的各个分类的集合而言,
分类方法即是散列函数,由散列函数给出某个对象<数字字符等>在这个集合中所属的类。
这个时候就可以说散列表这个概念了,散列表就是上面那个集合。

哈哈哈这种说法也太次奥了。


设计散列函数

h(key)= code

  • 直接定址
    由关键词的某个线性函数获得地址

  • 除留余数法
    一堆数字 34 456 7 78 231 456 75 423 21 44
    看起来没有什么联系,是否就要用上几百个位置按他们的值的顺序
    放置呢?
    如果让他们对11取余,则是完全能把他们分成有限的几组的

  • 数字分析法
    身份证号码,不同的位上的数字组合代表着不同的意义,根据这些意义我们就能把一些数字分类

  • 折叠法
    分割关键字后叠加
    如同 123456
    分割成 12 34 56
    加起来: 12+34+56 = 102 就生成了123456对应的分类码

  • 平法取中法
    和前者都是使取定的位更为多变
    <受到更多位上数字的影响-降低冲突概率>


简单实现
-

联系实际,牛津词典就是妙绝的散列表

至少我们使用词典时不会有“遍历词典”的奇怪想法

我们会根据某个单词的拼写顺序检索字典中对应的部分
这样,即使考虑到不是一下就能翻到我们想要的那一页,我们查词典时翻动的次数在很大程度也取决于单词的长度,而和词典中单词的总量无关。

仿照字典的思路,我们可以完成一个简单的名字表
把所有人的名字散列成26类,相同类的人名放到一起。

typedef struct hashNode{
public:
    hashNode* _front,*_behind;//节点串接
    string name;
}*hashTable;
1、取名字的首拼,取整形对26取余(众所周知,英文字母只有26)2、获得的整数对26取余,获得分类。
3、相同分类的人名组成一个链表。
int hashFunc(string name)
{
    return ((int)name[0])%26;
}

当然,这并不让人满意,毕竟相较于可能的人名数量,26这个分类数还是太小,那么我们可以对人名的第二个字母做同样的操作,把第一次的分类再分成26组,以此类推,直到你满意为止。

void addName(hashNode ht[],string& name)
{
    int Loc = hashFunc(name);
    hashTable htxd;
    hashTable htx = &ht[Loc];
    if(htx->name.empty()){
        htx->name = name;cout<<"here0,fill the name you gave at "<<Loc<<endl;
    }else{
        while(htx->_behind != NULL){
            htx = htx->_behind;
        }
        htxd = new hashNode;///malloc和含有string成员的结构冲突<并没有调用string的 cstr初始化string>
        htx->_behind = htxd;
        htx = htx->_behind;
        if(htx!=NULL)
            htx->name = name;
    }

}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值