《算法导论》第11章 散列表 (3)开放寻址

来源:互联网 发布:穿越火线辅助软件 编辑:程序博客网 时间:2024/06/05 09:04


前一节介绍是最简单的冲突解决方法-链接法。开放寻址与链接法不同,所有元素都放在散列表内。
在这种方法中,散列表可能会被填满。开放寻址不需要指针,只需要计算出要存取的各个槽。
由于不用存储指针而节省的空间可以提供更多的槽。

有三种技术常用来计算开放寻址法中的探查序列:线性探查、二次探查和双重探查。
下面的实现中,三种方法的差别只在计算探查序列的那一行代码。

#include <stdio.h>#include <stdlib.h>#include <string.h>#define SIZE 20typedef struct _Entry {         char *key;     char *val;} Entry;// 指针数组Entry *hashmap[SIZE];// Same as hashcode when String put to HashMapunsigned hashcode(char *key){     // Ensure >> is logical shift     unsigned h = 0;     // String.hashcode()     do h = 31 * h + *key++;     while (*key != '\0');         // HashMap.hash()     h ^= (h >> 20) ^ (h >> 12);     return h ^ (h >> 7) ^ (h >> 4);}Entry * hashmap_search(char *key){     unsigned h = hashcode(key) % SIZE;     unsigned h2 = h;     Entry *entry = hashmap[h];     while (entry != NULL) {          if (strcmp(entry->key, key) == 0) {               return entry;          }          // 线性探查。不同探查方法差别只在这一行。          h = (h + 1) % SIZE;          entry = hashmap[h];          if (h == h2)               break;     }     return NULL;}char * hashmap_insert(char *key, char *val){     unsigned h = hashcode(key) % SIZE;     printf("Insert %s - %s to bucket %d\n", key, val, h);         // Find duplicate key, replace it then return old value     unsigned h2 = h;     Entry *entry = hashmap[h];     while (entry != NULL) {          if (strcmp(entry->key, key) == 0) {               char *oldVal = entry->val;               entry->val = val;               return oldVal;          }          // Linear search          h = (h + 1) % SIZE;          entry = hashmap[h];          // Check if loop to initial bucket          if (h == h2)               break;     }     // Not found, create new node to save key&val pair     if (entry == NULL) {          entry = malloc(sizeof(Entry));          entry->key = key;          entry->val = val;          hashmap[h] = entry;     }         return val;}void hashmap_print(){         Entry *entry;     int i;     for (i = 0; i < SIZE; i++) {          entry = hashmap[i];          if (entry == NULL)               printf("%d: null\n", i);          else               printf("%d: %s - %s\n", i, entry->key, entry->val);     }     printf("\n");    }int main(void){     // Compare to String.hashcode() in JDK     printf("%d\n", hashcode("helloworld"));     hashmap_insert("aabb", "value1");     hashmap_insert("ccdd", "value2");     hashmap_insert("i'mcdai", "value3");     int i;     for (i = 0; i < 2 * SIZE + 5; i++) {          char *key = calloc(sizeof(char), 10);          char *val = calloc(sizeof(char), 10);          sprintf(key, "%s%d", "aabbcc", i);          sprintf(val, "%s%d", "val ", i);          hashmap_insert(key, val);     }     // Insert duplicate key     printf("%s\n", hashmap_insert("i'mcdai", "dupdup"));     hashmap_print();     printf("%s\n", hashmap_search("i'mcdai")->val);         hashmap_print();     return 1;}





原创粉丝点击