哈希表的构建(作为电子笔记,不具备参考价值)

1.建立哈希函数(由关键字集合到数组下标集合的映射),理想情况为单射。

2.往往难以构建单射,这就需要遇到这种情况:“装填数据时,利用哈希函数计算出的地址已被占用”时,做出相应的调整。通常有4种方法:

法1,探测序列法

search[100]=[-1,1,-2,2……]若遇到空间占用,向上移动1,若仍被占用,向下移动1,……依次类推。

注意:要记录探测序列使用到了哪一个,不妨记其下标k。因为后续查找时,如果使用到了k仍然没有找到关键字,则查找失败。

typedef struct Hash{
  string inf;
};
int main(){
//freopen("/config/workspace/answer/test","r",stdin);
int n;
cin>>n;
int longestsearch=0;//记录最后一个试探标号
Hash hash[10];
for(int i=0;i<10;i++){
    hash[i].inf="#";
}
for(int i=0;i<n;i++){
    string key;
    cin>>key;
    int num=0;
    for(int j=key.size()-1;j>=key.size()-4;j--){
        num+=(int(key[j])-'0');
    }
    
    num=num%10;//哈希函数运算结果存入num;
    int put=0;
    longestsearch=0;
    while(hash[num+put].inf!="#"){
     
        put++;
        if(hash[num+put].inf=="#")
        {longestsearch=put;
            break;
        }
        else if(hash[num-put].inf=="#")
        {   longestsearch=-put;
            break;
            
        }

    }
    
    hash[num+longestsearch].inf.append(key);

}
    //输出哈希表
    for(int i=0;i<10;i++){
        if(hash[i].inf!="#"){
            for(int j=1;j<hash[i].inf.size();j++){
                cout<<hash[i].inf[j];
            }
        }
            else 
            cout<<"#";
            cout<<endl;
        
    }
return 0;}

法2,二次散列

建立两个哈希函数H1,H2,若装填数据时,使用H1计算出的地址已被占用,则使用H2计算,存入H2.

查找时,使用H1计算地址没有关键字,失败。若存入数据不是关键字,则使用H2计算地址,若地址没有数据,失败;若有数据,但不是关键字,失败。

注意:该方法不适用于装填数据存在两个数据元素,两个哈希函数计算结构一样的数据。

法三,链式存储

地址存放一个指针,指针指向一个节点,该节点数据域是记录第一个通过H 计算结果为该地址的数据元素,指针域存放另一个指针,指向第二个通过H计算结果为该地址的数据元素(尾插法)。

//哈希节点和哈希表,构成哈希表-链表数据结构
typedef struct  HashNode{
    string Inf;
    HashNode* next;
};

typedef struct HashTabel{
    HashNode*first;
};

//哈希函数用于计算直接映射
int hashf(string key){
    int num=0;
    for(int i=key.size()-1;i>key.size()-5;i--)
    num+=(key[i]-'0');
    return num%10;
}

//将映射成index的key放入table的指的位置
void place(string key,int index,HashTabel tabel[]){
    HashNode* p=new HashNode;
    p->Inf=key;
    p->next=tabel[index].first;
    tabel[index].first=p;
    }
int main(){
//freopen("/config/workspace/answer/test","r",stdin);
int n;
HashTabel tabel[30];
cin>>n;



//初始化哈希表
for(int i=0;i<10;i++){
    tabel[i].first=NULL;
}
for(int i=0;i<n;i++){
    string key;
    cin>>key;
    int index=hashf(key);
    place(key,index,tabel);

}

//输出
for(int i=0;i<10;i++){
    if(tabel[i].first!=NULL)
    {
        HashNode*p=tabel[i].first;
        while(p){
            cout<<p->Inf<<" ";
            p=p->next;
        }
    }
    else 
    cout<<'#';
    cout<<endl;
}

return 0;}

法四,公共溢出区域

分为基本区,溢出区。通过H 计算数据元素的对应地址存入,若空间占用,则存入该基本区对应溢出区。

找到基本区,只要通过(下标相同则能找到溢出区)

(表述一个算法思路的自然语言多种多样,但是笔记应该更新为和算法代码能够建立直接对映的语言)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值