zoukankan      html  css  js  c++  java
  • 《算法导论》第11章 散列表 (3)开放寻址


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

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

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define SIZE 20
    
    typedef struct _Entry {    
         char *key;
         char *val;
    } Entry;
    
    // 指针数组
    Entry *hashmap[SIZE];
    
    // Same as hashcode when String put to HashMap
    unsigned 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;
    }
    





  • 相关阅读:
    MySQL 的连接时长控制--interactive_timeout和wait_timeout
    查看MySQL 连接信息--连接空闲时间及正在执行的SQL
    mysql timestamp为0值时,python读取后的对象为None
    MySQL基础普及《MySQL管理之道:性能调优、高可用与监控》
    读《大秦帝国》第三部
    golang mysql 如何设置最大连接数和最大空闲连接数
    如何查看MySQL connection id连接id
    JAVA配置环境变量
    PB常见功能实现代码
    PB中数据窗口自动换行
  • 原文地址:https://www.cnblogs.com/xiaomaohai/p/6157854.html
Copyright © 2011-2022 走看看