哈希表的地址冲突解法
  • 板块学术版
  • 楼主VaguesInvisibles
  • 当前回复16
  • 已保存回复16
  • 发布时间2022/9/17 13:56
  • 上次更新2023/10/27 11:16:41
查看原帖
哈希表的地址冲突解法
707377
VaguesInvisibles楼主2022/9/17 13:56

//测试数据1:14 36 42 38 40 15 19 12 51 65 34 25

//测试数据2:14 36 42 38 40 15 19 12 51 65 34 18

#include<iostream>
#include<cstring>
using namespace std;
#define m 15//哈希表的表长
#define NULLKEY 0//单元为空的标记
int HT[m], HC[m];

int H(int key) { //哈希函数
    return key % 13;
}

// 线性探测法
// 在哈希表中找出一个可以放置冲突数据的位置


int Linedetect(int HT[], int H0, int key, int &cnt) { //线性探测
    // 哈希表,起冲突的地址,存入的关键字,统计比较次数
    int Hi; //可能的新地址
    for (int i = 1; i < m; ++i) {
        cnt++; //被比较了几次cnt+几次
        Hi = (H0 + i) % m; //按照线性探测法计算下一个哈希地址Hi
        // (原地址 + i) % 表长
        if (HT[Hi] == NULLKEY || HT[Hi] == key) //新地址没用
            //或者新地址有相同元素
            return Hi;    //线性探测就返回这个新地址
    }
    return -1; // 找不到新地址
}




bool InsertHash(int HT[], int key) {
    int H0 = H(key); //根据哈希函数H(key)
    // 计算哈希地址
    int Hi = -1, cnt = 1;
    if (HT[H0] == 0) { //若H0为空,不冲突
        HC[H0] = 1; //统计比较次数
        HT[H0] = key;    //放入H0中
        return 1; //表示这个值可以存入哈希表
    } else {
        Hi = Linedetect(HT, H0, key, cnt); //线性探测 解决冲突的核心代码
        // 返回一个新的不冲突的地址给key

        //Hi=Seconddetect(HT,H0,key,cnt);//二次探测
        if (Hi != -1 && HT[Hi] == 0) { //若Hi为空
            HC[Hi] = cnt;
            HT[Hi] = key;
            return 1; //找到一个可以放进去的地址
        }
    }
    return 0; // 没有在哈希表中找到可以放置的地址
}



int main() {
    int x;
    cout << "输入12个关键字,存入哈希表中:" << endl;
    for (int i = 0; i < 12; i++) {
        cin >> x; // 输入关键字
        if (InsertHash(HT, x) == 0) { //如果关键字无法存入哈希表
            cout << "创建哈希表失败!" << endl;
            return 0;
        }
    }
    cout << "输出哈希表:" << endl; // 输出哈希表
    for (int i = 0; i < m; i++)
        cout << HT[i] << "\t"; //输出
    cout << endl;
    return 0;
}

二次探测法

int Seconddetect(int HT[],int H0,int key,int &cnt){//二次探测
    int Hi;
    for(int i=1;i<=m/2;++i){
        int i1=i*i;
        int i2=-i1;
        cnt++;
        Hi=(H0+i1)%m; //按照二次探测法计算下一个哈希地址
        if(HT[Hi]==NULLKEY || HT[Hi]==key)//若单元Hi为空或查找成功
            return Hi;
        cnt++;
        Hi=(H0+i2)%m; //按照二次探测法计算下一个哈希地址
        if(Hi<0)
            Hi+=m;
        if(HT[Hi]==NULLKEY || HT[Hi]==key)//若单元Hi为空或查找成功
            return Hi;
    }
    return -1;
}
2022/9/17 13:56
加载中...