哈希查找

91 阅读3分钟

1 题目

功能:哈希查找 描述: 哈希表长度 11 哈希函数 (key)=key%11 采用线性探测再散列的方法处理冲突

2 思路

哈希函数简要介绍

哈希函数的构造方法

哈希函数的构造方法常用的有5种,分别是数字分析法、平方取中法、分段叠加、伪随机数法和余数法,其中余数法比较常用。 例子中已给出哈希函数,按照给出的哈希函数进行了构造

避免哈希冲突的方法

分别有开放定址法(包括线性探测再散列和二次探测再散列入、链地址法、再哈希法和建立公共溢出区 开放定址法中的线性探测再散列比较常用,该方法的特点是在冲突发生时,顺序查看表中的下一单元,直到找出一个空单元或査遍全表。

3 代码

#include <stdio.h> 
#include <stdlib.h>
#include <time.h>
#define Max 11
#define N 8/**
功能:哈希查找
描述:
  哈希表长度 11
  哈希函数 (key)=key%11
  采用线性探测再散列的方法处理冲突
**/
​
int hashtable[Max];
​
int func(int value) {
    return value % Max;               // 哈希函数
}
​
int 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 -1;
    else
        return t;
}
​
void creathash(int key) {             // 自定义函数创建哈希表
​
    int pos, t;
    pos = func(key);                // 哈希函数确定元素的位置
    t = pos;
    while (hashtable[t] !=  - 1) {
    // 如果该位置有元素存在则进行线性探测再散列
        t = (t + 1) % Max;
        if (pos == t) {
          // 如果冲突处理后确定的位置与原位置相同则说明哈希表已满
            printf("哈希表已满\n");
            return ;
        }
    }
    hashtable[t] = key;               // 将元素放入确定的位置
}
​
int main(int argc, char const *argv[]) {
​
    int flag[50];
    int i, j, t;
    for (i = 0; i < Max; i++)
        hashtable[i] =  - 1;        // 哈希表中初始位置全置-1
                        
    for (i = 0; i < 50; i++)
        flag[i] = 0;
                        // 50以内所有数未产生时均标志为0
    srand((unsigned long)time(0));      // 利用系统时间做种子产生随机数
    i = 0;
    printf("建立 Hash 表: \n");
    while (i != N) {
        t = rand() % 50;          // 产生一个50以内的随机数赋给t
        if (flag[t] == 0) {           // 查看t是否产生过
            creathash(t);           // 调用函数创建哈希表
            printf("%2d:", t);          // 将该元素输出
            for (j = 0; j < Max; j++)
                printf("(%2d) ", hashtable[j]);
                              // 输出哈希表中内容
            printf("\n");
            flag[t] = 1;            // 将产生的这个数标志为1
            i++;                // i自加
        }
    }
    printf("请输入你想查找的元素:");
    scanf("%d", &t);              // 输入要查找的元素
    if (t > 0 && t < 50) {
        i = search(t);              // 调用search进行哈希查找
        if (i !=  - 1)
            printf("查找成功!其位置是:%d\n", i);  // 若查找到该元素则输出其位置
        else
            printf("查找失败!");          // 未找到输出提示信息
    }
    else
        printf("输入有误!");
}

示例结果:

$ gcc ex066.c -o demo
$ ./demo
建立 Hash 表:
 7:(-1) (-1) (-1) (-1) (-1) (-1) (-1) ( 7) (-1) (-1) (-1)
22:(22) (-1) (-1) (-1) (-1) (-1) (-1) ( 7) (-1) (-1) (-1)
16:(22) (-1) (-1) (-1) (-1) (16) (-1) ( 7) (-1) (-1) (-1)
29:(22) (-1) (-1) (-1) (-1) (16) (-1) ( 7) (29) (-1) (-1)
44:(22) (44) (-1) (-1) (-1) (16) (-1) ( 7) (29) (-1) (-1)
37:(22) (44) (-1) (-1) (37) (16) (-1) ( 7) (29) (-1) (-1)
 3:(22) (44) (-1) ( 3) (37) (16) (-1) ( 7) (29) (-1) (-1)
 9:(22) (44) (-1) ( 3) (37) (16) (-1) ( 7) (29) ( 9) (-1)
请输入你想查找的元素:9
查找成功!其位置是:9