C数据结构——哈希表/散列表 创建与基本使用

源码+注释

//
// Created by Lenovo on 2022-06-07-下午 4:42.
// 作者:小象
// 版本:1.0
//

#include <malloc.h>
#include <stdio.h>

#define HASHSIZE 60 // 散列表的表长
#define NULLKEY 0 // 单元为空的标记

// 散列表
typedef struct {
    int *elem; // 数据元素的基址,动态分配数组
    int count; // 当前数据元素的个数
} HashTable;

int InitHashTable(HashTable *table); // 初始化散列表
int Hash(int key); // 除留余数法
void InsertHash(HashTable *table, int key); // 插入关键字到散列表
char *SearchHash(HashTable table, int key, int *add); // 散列表查找关键字
void PrintHashTable(HashTable table); // 打印哈希表

int main() {

    // 定义散列表
    HashTable table;

    // 初始化
    InitHashTable(&table);

    // 生成散列表
    for (int i = 50; i > 0; i--) {
        InsertHash(&table, (i + 1));
    }

    // 打印生成的哈希表
    PrintHashTable(table);

    // 测试哈希表寻找指定值
    int index = 8; // 第几个位置开始找
    int key = 5; // 需要查找的数
    char *result = SearchHash(table, key, &index);
    printf("%s", result);

    return 0;
}

int InitHashTable(HashTable *table) {
    table->count = HASHSIZE; // 散列表长度初始化
    table->elem = (int *) malloc(sizeof(int) * HASHSIZE); // 给散列表分配空间地址
    if (!table->elem) {
        return -1; // 如果没有申请到地址,退出
    }
    for (int i = 0; i < HASHSIZE; i++) {
        table->elem[i] = NULLKEY; // 所有单元全部初始化为空
    }
    return 0; // 初始化成功
}

// 除留取余法
int Hash(int key) {
    // 求出最大素数
    for (int i = HASHSIZE; i > 0; i--) {
        int j = 2;
        for (; j <= i; j++) {
            if (i % j == 0) {
                break;
            }
        }
        if (i == j) {
            return key % i;
        }
    }
    return -999; // 抛出一个错误
}

// 插入关键字到散列表
void InsertHash(HashTable *table, int key) {
    int add;
    add = Hash(key); // 使用除留取余法给新插入的值分配位置
    while (table->elem[add] != NULLKEY) { // 如果不为空,则冲突出现
        add = (add + 1) % HASHSIZE; // 开放定址法的线性探测
    }
    table->elem[add] = key;
}

// 在散列表table中查找关键字为key的元素,若查找成功,返回散列表的单元标号,否则返回-1
char *SearchHash(HashTable table, int key, int *add) {
    int count = 0;
    while (table.elem[*add] != key) { // 不是关键字,说明被其他key占用了
        count++;
        printf("冲突第 %d 次\n", count);
        *add = (*add + 1) % HASHSIZE; // 循环查找
        if (table.elem[*add] == NULLKEY || *add == Hash(key)) { // 如果回到原点,或者找到了默认值,说明表里没有这个key
            return "没找到";
        }
    }
    return "找到了";
}

// 打印
void PrintHashTable(HashTable table) {
    printf("========= 哈希表 =========\n");
    for (int i = 0; i < table.count; i++) {
        printf("%d ", table.elem[i]);
    }
    printf("\n");
}
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小丶象

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值