【问题标题】:What is wrong with my hash function?我的哈希函数有什么问题?
【发布时间】:2017-04-26 18:23:50
【问题描述】:

我正在尝试创建一个哈希表。这是我的代码:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define N 19
#define c1 3
#define c2 5
#define m 3000
int efort;
int h_table[N];

int h(int k, int i)
{
    return (k + i*c1 + i*i*c2) % N;
}
void init()
{
    for (int i = 0; i < N; i++)
        h_table[i] = -1;
}
void insert(int k)
{
    int position, i;
    i = 0;
    do
    {
        position = h(k, i);
        printf("\n Position %d \n", position);
        if (h_table[position] == -1)
        {       
            h_table[position] = k;
            printf("Inserted :elem %d at %d \n", h_table[position], position);
            break;
        }
        else
        {
            i += 1;
        }
    } while (i != N);
}
void print(int n)
{
    printf("\nTable content: \n");
    for (int i = 0; i < n; i++)
    {
        printf("%d ", h_table[i]);
    }

 }


void test()
 {
    int a[100];
    int b[100];
    init();
    memset(b, -1, 100);
    srand(time(NULL));
    for (int i = 0; i < N; i++)
    {
        a[i] = rand() % (3000 + 1 - 2000) + 2000;
    }
    for (int i = 0; i < N ; i++)
    {
        insert(a[i]);
    }
    print(N);
}
 int main()
{   
    test();
    return 0;
}

哈希(“h”)函数和“插入”函数取自“算法简介”一书(Cormen)。我不知道 h 函数或插入函数发生了什么。有时它会完全填满我的数组,但有时不会。这意味着它不能很好地工作。我究竟做错了什么?

【问题讨论】:

  • 您是否使用调试器单步调试过您的代码?
  • 请注意memset(b, -1, 100) 不会将所有b[] 设置为-1。
  • 不要停留在while (i != N),而是继续寻找。也许在i &gt;= N/2 之后,只需线性查找下一个空闲单元格。
  • for(i=0;i&lt;100;i++) b[i]=-1; 替换memset() 语句并不能解决明显的问题。
  • 我使用了类似于调试器的东西。我使用了 printf("Position %d",position) ,我很清楚哈希函数正在跳过一些值。我可以看到这是错误的,但我不知道为什么......我需要使用哈希的二次函数:(

标签: c hash hashtable


【解决方案1】:

简而言之,您经常为position 生成重复值,足以防止h_table[] 在仅N 尝试后被填充...

伪随机数生成器不能保证生成一组唯一的数字,您的h(...) 函数也不能保证生成一组互斥的位置值。在生成所有 19 个位置之前,您很可能生成相同位置的次数足够多,以至于您用完循环。 h(...) 平均必须调用多少次才能获得未使用位置的价值? 应该回答这个问题。这可能有助于引导您解决问题。

作为一个实验,我将循环索引从N 增加到100,除了h(...) 函数(以免超出@987654329 @)。正如预期的那样,前 5 个职位立即填补了。下一个在 3 次尝试后填充。下一个 10 次尝试后,以此类推,直到 100 次尝试结束时,仍有一些未写入的位置。
下一次运行,所有表职位已满。

2 种可能的解决方案:
1) 修改哈希以提高唯一值的概率。
2) 增加迭代以填充h_table

【讨论】:

    【解决方案2】:

    good_hash_function() % N 可能会在 N 重新散列中重复。一个好的散列在其输出中看起来几乎是随机,即使它是确定性的。所以在N 尝试它可能不会循环遍历所有数组元素。

    在多次尝试(例如 N/3 次尝试)后未能找到空闲数组元素后,建议使用不同的方法。只需寻找下一个免费元素。

    【讨论】:

      猜你喜欢
      • 2015-10-25
      • 1970-01-01
      • 1970-01-01
      • 2016-09-19
      • 2020-07-05
      • 1970-01-01
      • 2020-10-18
      • 1970-01-01
      • 2012-02-26
      相关资源
      最近更新 更多