C语言 实现hash哈希表构造 插入 查找

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

typedef struct Node {
    char *str;
    struct Node *next;
} Node;

typedef struct HashTable {
    Node **data;
    int size;
} HashTable;

Node *initNode(char *str) {
    Node *n = (Node *)malloc(sizeof(Node));
    //n->str = (char *)malloc(strlen(str) + 1); strcpy(n->str, str);//还要多存结束标志'\0'
    n->str = strdup(str); //此行语句和上一行等价 需包含string.h
    n->next = NULL;
    return n;
}

void freeNode(Node *p) {
    if (!p) return ;
    free(p->str);
    free(p);
    return ;
}

void freeList(Node *head) {
    if (!head) return ;
    Node *k;
    while (head) {
        k = head;
        head = head->next;
        freeNode(k);
    }
    return ;
}

HashTable *initHashTable(int n) {
    HashTable *h = (HashTable *)malloc(sizeof(HashTable));
    h->size = n + n; //哈希表的空间一般都会比存值大数量大 减少哈希碰撞
    h->data = (Node **)calloc(h->size, sizeof(Node *)); //比malloc多了一个赋初始值0
    return h;
}

void freeHashTable(HashTable *h) {
    for (int i = 0; i < h->size; ++i)
        freeList(h->data[i]);
    free(h->data);
    free(h);
    return ;
}

Node *insertNode(Node *head, Node *p) {
    p->next = head;
    return p;
}

int BKDHash(char *str) {//哈希算法
    int hash = 0, seed = 31; //seed任意取一个质数
    while (*str) {
        hash = hash * seed + str[0]; //哈希公式
        ++str;
    }
    return hash & 0x7fffffff; //32位整型的最高位置为0
}

int insertHash(HashTable *h, char *str) { //插入哈希表
    if (!h) return 0;
    int hash = BKDHash(str), ind = hash % h->size;
    h->data[ind] = insertNode(h->data[ind], initNode(str));
    return 1;
}

Node *searchList(Node *p, char *str) {
    while (p && strcmp(p->str, str))
        p = p->next;
    return p;
}

Node *searchHash(HashTable *h, char *str) { //查找哈希表
    if (!h) return NULL;
    int hash = BKDHash(str), ind = hash %h->size;
    return searchList(h->data[ind], str);
}

//生成随机长度字符串
char *makeStr(char *str, int n) {
    int len = rand() % (n - 1) + 1; //n-1:保留最后一位存\0, +1:不能让字符串有len=0的空字符串
    char c;
    for (int i = 0; i < len; ++i) {
        switch (rand() % 3) {
        case 0:
            c = 'A' + rand() % 26;
            break;
        case 1:
            c = 'a' + rand() % 26;
            break;
        case 2:
            c = '0' + rand() % 10;
            break;
        default:
            c = '1';
            break;
        }
        str[i] = c;
    }
    str[len] = 0; // \0的ASCII值为0
    return str;
}

int main() {
    srand(time(0)); //设定随机数种子
    char str[8];
    int cnt = 10;
    HashTable *h = initHashTable(10);
    while (cnt--) {
        makeStr(str, 8);
        insertHash(h, str);
        printf("%s ", str);
    }
    putchar(10); //换行符\n的ASCII码的值为10
    while (~scanf("%s", str)) {
        if (!strcmp(str, "q")) break; //退出循环的字符串
        Node *n = searchHash(h, str);
        if (n) printf("hash=%d addr=%p, str=%s", BKDHash(str), n, n->str);
        else printf("%s is not found! ", str);
    }
    freeHashTable(h);
    return 0;
}
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值