1. 目标:实现一个简易哈希表

期望构建一个这样的简易哈希表:

  • √ 长度为10(实际长度应该有质数,这样更不容易碰撞)
  • √ 使用time33散列函数
  • √ key使用16位字符串
  • √ data使用int
  • √ 用单向链表处理哈希碰撞
  • X 暂不支持扩容重哈希

2. 代码实现

2.1 哈希节点结构体

#define HASHSIZE 10

typedef struct HashNode {
    char   key[16];
    int    data;//数据域
    struct HashNode *next;//指针域,哈希碰撞时候的后继结点
} HashNode;

static HashNode *HashTable[HASHSIZE];

2.2 time33散列函数

这里因为要放在长度为HASHSIZEHashTable里,故而对HASHSIZE取余

typedef struct HashNode {
    char   key[16];
    int    data;//数据域
    struct HashNode *next;//指针域,哈希碰撞时候的后继结点
} HashNode;

static HashNode *HashTable[HASHSIZE];

2.3 set函数

  • 考虑该槽为NULL时直接插入
  • 考虑该槽不为空时,则遍历链表寻找目标key, 找得到就更新, 找不到就尾插新节点
void *set(char *key, int data)
{
    struct HashNode *node;
    unsigned int hash_key = time33(key);
    printf("set key:%s val:%d hash:%d\n", key, data, hash_key);
    
    struct HashNode *new_node;
    new_node = (struct HashNode *)malloc(sizeof(struct HashNode));
    strcpy(new_node->key, key);
    new_node->data = data;
    new_node->next = NULL;
    
    node = HashTable[hash_key];
    //先看在不在
    if (NULL == node)
    {
        HashTable[hash_key] = new_node; 
        return NULL;
    }else if(strcmp(node->key, key) == 0){
        printf("update key:%s %d => %d \n",key,node->data, data);
        //update
        node->data = data;
        free(new_node);
    }else{
        //碰撞
        while(node->next != NULL){
            node = node->next;
            if(strcmp(node->key, key) == 0){
                //update
                node->data = data;
                printf("update key:%s %d => %d \n",key,node->data, data);
                free(new_node);
            }
        }
        node->next = new_node;
    }
}

2.4 get函数

  • 考虑该槽为NULL时返回NULL
  • 考虑该槽不为空时,则遍历链表寻找目标key, 找得到就返回该节点, 找不到返回NULL
HashNode *get(char *key)
{
    unsigned int hash_key = time33(key);
    struct HashNode *node;
    node = HashTable[hash_key];
    while(NULL != node){
        if (strcmp(key, node->key) == 0)
        {
            printf("get %s :%d \n", key, node->data);
            return node;
        }
        node = node->next;
    }
    return NULL;
}

2.5 遍历哈希getAll函数 用于验证代码

void getAll(){
    struct HashNode *node;
    for (int i = 0; i < HASHSIZE; ++i)
    {
        if (HashTable[i] != NULL)
        {
            node = HashTable[i];
            while(node != NULL){
                printf("%d %s %d \n", i,node->key,node->data);
                node = node->next;
            }
        }        
    }
}

3 测试代码

int main(int argc, char const *argv[])
{
    set("zhangsan", 100);
    set("zhangsan", 200);//update
    set("lisi", 200);
    set("wangwu", 300);
    set("maliu", 400);
    set("qianer", 500);
    set("zhaojiu", 600);
    set("sunzi",700);
    set("wangwu", 3000);//update
    getAll();
    return 0;
}

Res:

terence@k8s-master:/mydata/c$ gcc hashTable.c
terence@k8s-master:/mydata/c$ ./a.out
set         key:zhangsan val:100     hash:1
set         key:zhangsan val:200     hash:1
update         key:zhangsan 100 => 200 
set         key:lisi     val:200    hash:6
set         key:wangwu   val:300     hash:0
set         key:maliu    val:400     hash:1
set         key:qianer   val:500     hash:5
set         key:zhaojiu  val:600     hash:7
set         key:sunzi    val:700     hash:4
set         key:wangwu   val:3000     hash:0
update         key:wangwu   300 => 3000 
0 wangwu 3000 
1 zhangsan 200 
1 maliu 400 
4 sunzi 700 
5 qianer 500 
6 lisi 200 
7 zhaojiu 600

Done!


tfzh
231 声望17 粉丝

code what u love & love what u code


引用和评论

0 条评论