c - 搜索哈希表不起作用,for 循环不在 c 中执行

标签 c search for-loop hash hashtable

<分区>

我有一个带有单独链接列表的哈希表。我成功地将我的元素存储在哈希表中,但是当我尝试搜索我存储的元素时它失败了。我的函数 lookup_string 应该在哈希表中找到正确的列表,如果多个元素存储有相同的哈希键,则使用 for 循环遍历链表。

lookup_string 函数中,我发现 for 循环从不执行(我使用 prints 来检查)并且该函数跳过 for 循环并直接返回 NULL。这种行为真的很奇怪,我不知道为什么它会跳过那个循环,但这就是为什么我在存储它们之后找不到我的元素的原因,至少我是这么认为的。

如果有人能阐明这个问题,我们将不胜感激!

我有删除哈希表中元素的函数,但这些不是必须考虑的,我只是上传它们以供理解。我在菜单中选择选项 1 以添加一个元素,然后在菜单中选择选项 3,这时我找不到我存储的元素。

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

struct post                 // structure of node
{       
    char name[30];          // stored data
    int tel;                // stored data
    struct post *next;      // reference to next node
};

typedef struct post Post;   // Post = struct post

struct list
{
    Post *head;         
    Post *current;              
};

typedef struct list List;

struct hash_table
{
    List *table;
    int size;
};

typedef struct hash_table Post_table;

Post* CreateList(char tempname[30], int temptel)
{   
    Post *ptr = (Post*)malloc(sizeof(Post));

    strcpy(ptr->name, tempname);    
    ptr->tel = temptel;
    ptr->next = NULL;

    printf("\n creating list with headnode as [%s]\n",tempname);

    return ptr;
}

Post* AddList(char tempname[30], int temptel, Post *current)
{
    if( current == NULL )
    {
        return (CreateList(tempname, temptel));
    }

    printf("\n Adding node to end of list with value [%s]\n",tempname);
    Post *ptr = (Post*)malloc(sizeof(Post));

    strcpy(ptr->name, tempname);
    ptr->tel = temptel;
    ptr->next = NULL;

    current->next = ptr;

    return ptr;
}

unsigned int Hash(Post_table *hash_table, char tempname[30])
{
    int i, sum, key;

    for(i = 0; i < strlen(tempname); i++)
    {
        sum += (int)tempname[i];
    }

    key = abs(sum % hash_table->size);
    return key;
}

Post_table *create_hash_table(int size)
{
    Post_table *new_table;

    if (size < 1)
    {return NULL;}

    // attempt to allocate memory for the table structure
    if ((new_table = malloc(sizeof(Post_table))) == NULL)
    {return NULL;}

    // attempt to allocate memory for the table itself
    // calloc() = all head and current are initialized with NULL
    if ((new_table->table = calloc(size,sizeof(List *) * size)) == NULL)
    {return NULL;}

    new_table->size = size;
    return new_table;
}

Post *lookup_string(Post_table *hash_table, char tempname[30])
{
    Post *list;
    unsigned int hashkey = Hash(hash_table, tempname);
    printf("testprint-1");

    // Go to the correct list based on the hash value and see if str is
    // in the list.  If it is, return return a pointer to the list element.
    // If it isn't, the item isn't in the table, so return NULL.
    for(list = hash_table->table[hashkey].head; list != NULL; list = list->next)
    {
        printf("testprint-2");
        if (strcmp(tempname, list->name) == 0)
        {
            return list;
        }
    }
    return NULL;
}

int add_string(Post_table *hash_table, char tempname[30], int temptel)
{    
    Post *current_list;

    unsigned int hashkey = Hash(hash_table, tempname);
    printf("\nHash-key: %d\n", hashkey);

    // if item already exists, don't insert it again
    current_list = lookup_string(hash_table, tempname);
    if (current_list != NULL)
    {
        return 2;
    }

    hash_table->table[hashkey].current = AddList(tempname, temptel, hash_table->table[hashkey].current);

    // if the list has been created just now, then both head and current must point to the only list element
    if( hash_table->table[hashkey].head == NULL )
    {
        hash_table->table[hashkey].head = hash_table->table[hashkey].current;
    }
    return 0;
}

void free_entry(Post_table *hash_table, char tempname[30])
{
    Post *del_list;
    Post *temp;
    int ret = 0;

    unsigned int hashkey = Hash(hash_table, tempname);
    del_list = lookup_string(hash_table, tempname);
    ret = Delete(hash_table, tempname, hashkey);

    if(ret != 0)
    {
        printf("\n delete [name = %s] failed, no such element found\n",tempname);
    }
    else
    {
        printf("\n delete [name = %s]  passed \n",tempname);
    }
}

void skrivMeny(void)
{
    printf("\n1: Register name and telephone number\n");
    printf("2: Remove name and telephone number\n");
    printf("3: Search for name\n");
    printf("5: Exit\n");
}

Post* Search(Post_table *hash_table, unsigned int hashkey, char tempname[30], Post **prev)
{
    Post *ptr = hash_table->table[hashkey].head;
    Post *tmp = NULL;
    int found = 0;
    char structname[sizeof(tempname)];

    printf("\n Searching the list for value [%s] \n",tempname);

    while(ptr != NULL)
    {   
        if (strcmp(ptr->name, tempname) == 0)
        {
            found = 1;
            break;
        }

        else
        {
            tmp = ptr;
            ptr = ptr->next;
        }
    }

    if(found == 1)
    {
        if(prev)
        {
            *prev = tmp;
        }
        return ptr;
    }

    else
    {
        return NULL;
    }
}

int Delete(Post_table *hash_table, char tempname[30], unsigned int hashkey)
{
    Post *prev = NULL;
    Post *del = NULL;

    printf("\n Deleting value [%s] from list\n",tempname);
    del = Search(hash_table, hashkey, tempname, &prev);

    if(del == NULL)
    {
        return -1;
    }

    else
    {
        if(prev != NULL)
        {
            prev->next = del->next;
        }

        if(del == hash_table->table[hashkey].current && del != hash_table->table[hashkey].head)
        {
            hash_table->table[hashkey].current = prev;
        }

        else if(del == hash_table->table[hashkey].head)
        {
            hash_table->table[hashkey].head = del->next;
        }
    }

    free(del);
    del = NULL;
    return 0;
}


int main()
{
    printf("\nHej och välkommen till hashlistan\n\n");
    int menyval = 1;
    char tempname[30];
    int temptel, key;

    Post * ptr;

    Post_table *hash_table;
    int table_size = 10;
    hash_table = create_hash_table(table_size);

    while (menyval > 0 && menyval <= 5)
    {
        skrivMeny();
        scanf("%d", &menyval);

        if (menyval == 1)
        {
            printf("[Name] [Number] = ");
            scanf("%s %d", &tempname[0], &temptel);
            add_string(hash_table, tempname, temptel);
        }

        if (menyval == 2)
        {    
            printf("[Name] = ");
            scanf("%s", &tempname[0]);
            free_entry(hash_table, tempname);
        }

        if (menyval == 3)
        {
            printf("[Name] = ");
            scanf("%s", &tempname[0]);
            ptr = lookup_string(hash_table, tempname);

            if(ptr == NULL)
            {
                printf("\n Search [name = %s] failed, no such element found\n",tempname);
            }
            else
            {
                printf("\n Search passed [name = %s tel = %d]\n",ptr->name, ptr->tel);
            }
        }

        if (menyval == 5)
        {
            break;
        }

    }
    return 0;
}

最佳答案

可能出现问题的一件事是,在您的 Hash 函数中,您声明了 sum 而没有将其初始化为 0。我的猜测是 for 循环没有执行在 'lookup_string' 中,因为 'list' 一开始是 NULL,因为每次调用它时 'Hash' 不一定都相同(即使使用相同的参数)。

也许代替:

int i, sum, key;

放:

int i, key, sum = 0;

关于c - 搜索哈希表不起作用,for 循环不在 c 中执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18090850/

相关文章:

PHP:如何创建链接到我的搜索脚本的搜索表单

Java for 循环的幂

c - 带有嵌套 for 循环的简单 C 程序在 Windows Powershell 中停止工作

php - 从搜索中隐藏 Drupal 节点

Python迭代

C++ ulong到类方法指针并返回

C - fscanf 在文件结束之前引发 EOF

c - 术语和代码行的平等

c++ - 从 C 调用系统 C++ 函数

java - 如何在与 java 对象的所有成员匹配的 java 对象列表中进行关键字搜索