hash table相關2

前面的講述瞭如何用鏈地址法實現一個哈希表,那麼今天來分析一下另外一種解決哈希衝突的作法,即爲每一個Hash值,創建一個Hash桶(Bucket),桶的容量是固定的,也就是隻能處理固定次數的衝突,如1048576個Hash桶,每一個桶中有4個表項(Entry),總計4M個表項。其實這兩種的實現思路雷同,就是對Hash表中每一個Hash值創建一個衝突表,即將衝突的幾個記錄以表的形式存儲在其中。html

大體的思路是這樣的:算法

首先哈希桶的個數是固定的,有用戶構建的時候輸入,一旦構建,個數就已經固定;查找的時候首先將key值經過哈希函數獲取哈希值,根據哈希值獲取到對應的哈希桶,而後遍歷哈希桶內的pairs數組獲取。數組

主要的數據結構:數據結構

01 struct Pair {
02     char *key;
03     char *value;
04 };
05  
06 struct Bucket {
07     unsigned int count;
08     Pair *pairs;
09 };
10  
11 struct StrMap {
12     unsigned int count;
13     Bucket *buckets;
14 };
  • 本小節主要是學習一下國外大牛是如何實現哈希表的。完整的代碼,請看: 這裏,一位聖安德魯斯大學的講師: KRISTENSSON博客

strmap.happ

001 #ifndef _STRMAP_H_
002 #define _STRMAP_H_
003  
004 #ifdef __cplusplus
005 extern "C"
006 {
007 #endif
008  
009 #include <stdlib.h>
010 #include <string.h>
011  
012 typedef struct StrMap StrMap;
013  
014 /*
015  * This callback function is called once per key-value when iterating over
016  * all keys associated to values.
017  *
018  * Parameters:
019  *
020  * key: A pointer to a null-terminated C string. The string must not
021  * be modified by the client.
022  *
023  * value: A pointer to a null-terminated C string. The string must
024  * not be modified by the client.
025  *
026  * obj: A pointer to a client-specific object. This parameter may be
027  * null.
028  *
029  * Return value: None.
030  */
031 typedef void(*sm_enum_func)(const char *key, const char *value, const void*obj);
032  
033 /*
034  * Creates a string map.
035  *
036  * Parameters:
037  *
038  * capacity: The number of top-level slots this string map
039  * should allocate. This parameter must be > 0.
040  *
041  * Return value: A pointer to a string map object,
042  * or null if a new string map could not be allocated.
043  */
044 StrMap * sm_new(unsigned int capacity);
045  
046 /*
047  * Releases all memory held by a string map object.
048  *
049  * Parameters:
050  *
051  * map: A pointer to a string map. This parameter cannot be null.
052  * If the supplied string map has been previously released, the
053  * behaviour of this function is undefined.
054  *
055  * Return value: None.
056  */
057 void sm_delete(StrMap *map);
058  
059 /*
060  * Returns the value associated with the supplied key.
061  *
062  * Parameters:
063  *
064  * map: A pointer to a string map. This parameter cannot be null.
065  *
066  * key: A pointer to a null-terminated C string. This parameter cannot
067  * be null.
068  *
069  * out_buf: A pointer to an output buffer which will contain the value,
070  * if it exists and fits into the buffer.
071  *
072  * n_out_buf: The size of the output buffer in bytes.
073  *
074  * Return value: If out_buf is set to null and n_out_buf is set to 0 the return
075  * value will be the number of bytes required to store the value (if it exists)
076  * and its null-terminator. For all other parameter configurations the return value
077  * is 1 if an associated value was found and completely copied into the output buffer,
078  * 0 otherwise.
079  */
080 int sm_get(const StrMap *map, const char *key, char *out_buf, unsigned intn_out_buf);
081  
082 /*
083  * Queries the existence of a key.
084  *
085  * Parameters:
086  *
087  * map: A pointer to a string map. This parameter cannot be null.
088  *
089  * key: A pointer to a null-terminated C string. This parameter cannot
090  * be null.
091  *
092  * Return value: 1 if the key exists, 0 otherwise.
093  */
094 int sm_exists(const StrMap *map, const char *key);
095  
096 /*
097  * Associates a value with the supplied key. If the key is already
098  * associated with a value, the previous value is replaced.
099  *
100  * Parameters:
101  *
102  * map: A pointer to a string map. This parameter cannot be null.
103  *
104  * key: A pointer to a null-terminated C string. This parameter
105  * cannot be null. The string must have a string length > 0. The
106  * string will be copied.
107  *
108  * value: A pointer to a null-terminated C string. This parameter
109  * cannot be null. The string must have a string length > 0. The
110  * string will be copied.
111  *
112  * Return value: 1 if the association succeeded, 0 otherwise.
113  */
114 int sm_put(StrMap *map, const char *key, const char *value);
115  
116 /*
117  * Returns the number of associations between keys and values.
118  *
119  * Parameters:
120  *
121  * map: A pointer to a string map. This parameter cannot be null.
122  *
123  * Return value: The number of associations between keys and values.
124  */
125 int sm_get_count(const StrMap *map);
126  
127 /*
128  * An enumerator over all associations between keys and values.
129  *
130  * Parameters:
131  *
132  * map: A pointer to a string map. This parameter cannot be null.
133  *
134  * enum_func: A pointer to a callback function that will be
135  * called by this procedure once for every key associated
136  * with a value. This parameter cannot be null.
137  *
138  * obj: A pointer to a client-specific object. This parameter will be
139  * passed back to the client's callback function. This parameter can
140  * be null.
141  *
142  * Return value: 1 if enumeration completed, 0 otherwise.
143  */
144 int sm_enum(const StrMap *map, sm_enum_func enum_func, const void *obj);
145  
146 #ifdef __cplusplus
147 }
148 #endif
149  
150 #endif

strmap.cide

001 #include "strmap.h"
002  
003 typedef struct Pair Pair;
004  
005 typedef struct Bucket Bucket;
006  
007 struct Pair {
008     char *key;
009     char *value;
010 };
011  
012 struct Bucket {
013     unsigned int count;
014     Pair *pairs;
015 };
016  
017 struct StrMap {
018     unsigned int count;
019     Bucket *buckets;
020 };
021  
022 static Pair * get_pair(Bucket *bucket, const char *key);
023 static unsigned long hash(const char *str);
024  
025 StrMap * sm_new(unsigned int capacity)
026 {
027     StrMap *map;
028      
029     map = malloc(sizeof(StrMap));
030     if (map == NULL) {
031         return NULL;
032     }
033     map->count = capacity;
034     map->buckets = malloc(map->count * sizeof(Bucket));
035     if (map->buckets == NULL) {
036         free(map);
037         return NULL;
038     }
039     memset(map->buckets, 0, map->count * sizeof(Bucket));
040     return map;
041 }
042  
043 void sm_delete(StrMap *map)
044 {
045     unsigned int i, j, n, m;
046     Bucket *bucket;
047     Pair *pair;
048  
049     if (map == NULL) {
050         return;
051     }
052     n = map->count;
053     bucket = map->buckets;
054     i = 0;
055     while (i < n) {
056         m = bucket->count;
057         pair = bucket->pairs;
058         j = 0;
059         while(j < m) {
060             free(pair->key);
061             free(pair->value);
062             pair++;
063             j++;
064         }
065         free(bucket->pairs);
066         bucket++;
067         i++;
068     }
069     free(map->buckets);
070     free(map);
071 }
072  
073 int sm_get(const StrMap *map, const char *key, char *out_buf, unsigned intn_out_buf)
074 {
075     unsigned int index;
076     Bucket *bucket;
077
相關文章
相關標籤/搜索