1. 指标:实现一个繁难哈希表
冀望构建一个这样的繁难哈希表:
- √ 长度为10
- √ 应用time33散列函数
- √ key应用16位字符串
- √ data应用int
- √ 用单向链表解决哈希碰撞
- X 暂不反对扩容重哈希
2. 代码实现
2.1 哈希节点构造体
#define HASHSIZE 10typedef struct HashNode { char key[16]; int data;//数据域 struct HashNode *next;//指针域,哈希碰撞时候的后继结点} HashNode;static HashNode *HashTable[HASHSIZE];
2.2 time33
散列函数
这里因为要放在长度为HASHSIZE
的HashTable
里,故而对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.cterence@k8s-master:/mydata/c$ ./a.outset key:zhangsan val:100 hash:1set key:zhangsan val:200 hash:1update key:zhangsan 100 => 200 set key:lisi val:200 hash:6set key:wangwu val:300 hash:0set key:maliu val:400 hash:1set key:qianer val:500 hash:5set key:zhaojiu val:600 hash:7set key:sunzi val:700 hash:4set key:wangwu val:3000 hash:0update 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!