C语言实现哈希表

C语言实现哈希表

简介:
哈希表在根据内容查找时,它的时间复杂度相对于要逐一遍历的数组或者链表要小。

散列算法:主要由md5(消息摘要算法),sha1(安全散列) ,这两者不可靠。sha2(安全散列2 sha256/512)目前还没冲突,较为可靠。

散列冲突:多个数据,进行散列之后的散列值相同,此时会存在散列冲突。
常见的解决方法:有线性探测、平方探测、二次散列、链表分离、链表分离改良实现(链表+红黑树)。

该程序:采用链表分离的方法解决散列冲突。适合初学者学习。
哈希表
该图为本程序的图解,结合此图看程序时有对哈希表有较好的理解。

//sanlie.c 哈希表的实现
//采用链表的方式
//遇到散列冲突时,采用链表分离的方式

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

//哈希表中数据元素的结构体
typedef struct
{
    char *key; //关键字
    char *value;
} Element;

//数据元素单链表
typedef struct Node
{
    Element student;   //数据元素
    struct Node *next; //next指针
} Node;

//哈希表
typedef struct
{
    Node *head; //数据元素存储
    int size;   //当前表中的大小,表长
    int count;  //哈希表中的数据元素的个数
} HashTable;

//初始化哈希表
HashTable *inittable(int tablesize)
{
    HashTable *table = (HashTable *)malloc(sizeof(HashTable));
    table->size = tablesize;
    //分配和初始化单链表数据元素的头结点
    table->head = (Node *)malloc((table->size) * sizeof(Node));
    memset(table->head, 0, sizeof(Node) * (table->size));
    table->count = 0; //现有的元素的个数

    return table;
}

//哈希函数
int hash(HashTable *table, char *key)
{
    int sum = 0; //字符串的ASNI之和
    for (int i = 0; i < strlen(key); i++)
    {
        sum += key[i];
    }

    return sum % table->size;
}

//在哈希表中查找关键字
Node *find(HashTable *table, char *key)
{
    int ii = hash(table, key);

    Node *node = table->head[ii].next;

    //遍历单链表
    while ((node != NULL) && (node->student.key != key))
    {
        node = node->next;
    }

    return node;
}

//往哈希表中插入元素
int put(HashTable *table, char *key, char *value)
{
    //从哈希表中查找元素
    Node *ee = find(table, key);

    if (ee != NULL)
    {
        printf("元素已经存在。\n");
        return 0;
    }

    int ii = hash(table, key);

    Node *node = (Node *)malloc(sizeof(Node));
    node->student.key = key;
    node->student.value = value;

    //追加在对应位置的头结点后面
    node->next = table->head[ii].next;
    table->head[ii].next = node;

    table->count++;
    return 1;
}

//遍历哈希表
void Print(HashTable *table)
{
    for (int i = 0; i < table->size; i++)
    {
        Node *node = table->head[i].next;

        while (node)
        {
            printf("%s-%s  ", node->student.key, node->student.value);
            node = node->next;
        }
        printf("\n");
    }

    printf("\n");
}

//从哈希表中删除元素
int get(HashTable *table, char *key)
{
    int ii = hash(table, key);

    Node *node = &table->head[ii];

    //遍历单链表,node停留在待删除关键结点key的前一结点
    while ((node != NULL) && (node->next->student.key != key))
    {
        node = node->next;
    }

    if (node->next == NULL)
        return 0; //查找失败

    Node *tmp = node->next; //tmp为将要删除的结点

    node->next = tmp->next;

    free(tmp); //释放结点

    table->count--;

    return 1;
}

int main(int argc, char const *argv[])
{
    HashTable *table = inittable(5);

    put(table, "alice", "alice info");
    put(table, "bob", "bob info");
    put(table, "hack", "hack info");

    Print(table);

    get(table, "bob");
    Print(table);

    Node *node = find(table, "hack");
    if (node != NULL)
        printf("找到%s-%s\n", node->student.key, node->student.value);

    Node *node1 = find(table, "bob");
    if (node1 != NULL)
        printf("找到%s-%s\n", node1->student.key, node1->student.value);

    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值