【问题标题】:Wrong implementation search a record using hash tables. No results found?错误的实现使用哈希表搜索记录。未找到结果?
【发布时间】:2016-02-12 04:17:39
【问题描述】:

我正在尝试逐个字段搜索结构数组 (id)。 代码编译,但不起作用。我认为这是创建哈希表的问题。但是无法解决问题,我是哈希表的初学者,可以创建一个元素数量大小的哈希表吗?无论如何,访问时间是 O(1) 所以我只使用了很多内存对吗?

这是我的完整代码,在此先感谢您的每条建议/评论。

这些是我的广告:

typedef struct _SPerson {
    char name[20];
    char surname[20];
    char id[20];
    char telephone[20];
} SPerson;

typedef struct SInfo {
    int key;
    SPerson value;
} TInfo;

struct SNode_list {    /*list node*/
    TInfo information;          /*data->key and value*/                            
    struct LNode *next; /*pointer to next element*/
};

typedef struct SNode_list LNode;    // LNode single element of list 
typedef LNode *List;

/*hash table struct*/
typedef struct _HashTable {
    int bucket_number;
    List *bucket;
} HashTable;

我加载了一个包含 20000 条记录的数组 SPerson Archive[20000];

在我搜索数据的函数中,我这样做:

void search_using_hash_table(SPerson Archive[], int ne) {
    HashTable *ht = hashtable_create(ne);
    SPerson *app_record
    char *app = get_string();
    for (i = 0; i < ne; i++)       /*Creating Hash-Table*/
        hashtable_insert(ht, i, Archive[i]);
    app_record = hashtable_search(ht, app);
    if (app != NULL)
        printf("\n\nFound.\n %s %s %s %s\n",
               app->id, app->surname, app->name, app->telephone);
    else
        printf("\n\nNot found.\n");
}

这些是我的功能:

插入

void hashtable_insert(HashTable *ht, int key, SPerson value) {
    TInfo info;
    LNode *node;
    unsigned h;
    info.key = key;
    info.value = value;
    h = hash(value.id) % ht->bucket_number;

    node = list_search_unordered(ht->bucket[h], info);  

    if (node == NULL)   /*no collision*/
        ht->bucket[h] = list_insert_at_index(ht->bucket[h], info);
    else                /*push*/
        node->information = info;
}                       

搜索

SPerson *hashtable_search(HashTable *ht, char *key) {
    unsigned h = hash(key) % ht->bucket_number;      
    TInfo info;
    info.key = key;
    LNode *node = list_search_unordered(ht->bucket[h], info);   
    if (node == NULL)
        return NULL;                                             
    else
        return &node->information.value;
}

列表搜索

LNode *list_search_unordered(List list, TInfo info) {
    LNode *curr;
    curr = list;

    while ((curr != NULL) && !equal(info, curr->information)) {
        curr = curr->next;
    }
    if (curr == NULL)
        return NULL;
    else
        return curr;
}

相等

bool equal(TInfo a, TInfo b) {
    return a.key == b.key;
}

创建

HashTable *hashtable_create(int buckets) {
    int i;
    HashTable *p = (HashTable *)malloc(sizeof(HashTable));  /*allocation*/
    assert(p != NULL);      /*assert verificate if allocation went ok*/
    assert(buckets > 0);        

    p->bucket_number = buckets;
    p->bucket = (List *)malloc(sizeof(List)*buckets);   
    assert(p->bucket != NULL);

    for (i = 0; i < buckets; i++)
        p->bucket[i] = NULL;    

    return p;
}

哈希算法

unsigned long hash(unsigned char *str) { /*djb algorithm*/
    unsigned long hash = 5381;
    int c;

    while (c = *str++)
        hash = ((hash << 5) + hash) + c; /* hash * 33 + c */

    return hash;
}

【问题讨论】:

    标签: c list hash hashtable bucket


    【解决方案1】:

    您在存储时对ids 进行哈希处理,在搜索时您使用哈希处理keys 来搜索尚未哈希处理的对象,因此它们永远不会相等。

     void hashtable_insert(HashTable *ht, int key, SPerson value)
      {
       TInfo info;
       LNode *node;
       unsigned h;
       info.key = key;
       info.value = value;
       h = hash(value.id) % ht->bucket_number;...
    
     SPerson *hashtable_search(HashTable *ht, char* key)
     {
       unsigned h = hash(key) % ht->bucket_number;       
       TInfo info;
       info.key = key;
       LNode *node = list_search_unordered(ht->bucket[h], info);...
    

    【讨论】:

    • 所以我应该用 char* 键代替 int 键?
    • hashtable_search 中,您使用unsigned h = hash(key) % ht-&gt;bucket_number;key 获得h 值。 但是hashtable_insert中,您以不同方式计算h不是使用键而是使用值来代替:h = hash(value.id) % ht-&gt;bucket_number;。这就是@MajeedSiddiqui 所说的。您应该在两个函数中以相同的方式计算 h
    猜你喜欢
    • 2017-11-23
    • 1970-01-01
    • 1970-01-01
    • 2012-04-15
    • 2014-04-07
    • 1970-01-01
    • 2016-01-11
    • 1970-01-01
    • 2014-05-24
    相关资源
    最近更新 更多