哈希表(连接法)V0.000001

哈希表(连接法)V0.000001

1,哈希函数用的上一篇文章中的第一个DJB(不知道实现正确了没 :P)
2,冲突是用的连接表
3,代码虽然能勉强运行,但是比较糟糕。。。。
  1  /*
  2   *一个简单的字符串HASH表,哈希函数是用的PHP中的DJB_Hash
  3   *冲突是用的简单的连接法解决
  4   *
  5   *代码不是一般的烂。。。。。。
  6    */
  7  #include < stdio.h >
  8  #include < stdlib.h >
  9  #include < string .h >
 10 
 11  struct  table_node{
 12       void   * value;
 13       struct  table_node  * prev, * next;
 14  };
 15  struct  hashtable{
 16       struct  table_node  * head, * tail;
 17  };
 18  struct  hashtable_head{
 19      unsigned  int  table_size;
 20      unsigned  int  end_iterator;
 21       struct  hashtable  * buckets;
 22  };
 23  /* ******************************************
 24   *
 25   *查创建HASH_TABLE
 26   *
 27    */
 28  struct  hashtable_head  *  hashtable_init(unsigned  int  size)
 29  {
 30       struct  hashtable_head  * ptr;
 31 
 32       if  ( 0   ==  size)
 33           return  NULL;
 34      ptr  =  ( struct  hashtable_head  * )calloc( 1 , sizeof ( struct  hashtable_head));
 35       if ( ! ptr)
 36           return  NULL;
 37      ptr -> table_size  =  size;
 38      ptr -> buckets  =  ( struct  hashtable  * )calloc(size, sizeof ( struct  hashtable));
 39       if ( ! ptr -> buckets){
 40          free (ptr);
 41           return  NULL;
 42      }
 43      ptr -> end_iterator  =   0 ;
 44       return  ptr;
 45  }
 46  /* ******************************************
 47   *
 48   *hash函数,
 49   *
 50    */
 51  unsigned  int  DJB_Hash( char   * str, int  len)
 52  {
 53       int  i;
 54      unsigned hash  =   0 ;
 55       for  (i  =   0 ;i  < len;i ++ )
 56       {
 57          hash  +=  (hash  <<   5  ) +  str[i];
 58 
 59      }
 60       return  hash  %   47 ;
 61  }
 62  /* *******************************
 63   *
 64   *把value插入表中
 65    */
 66  struct  hashtable_head  * hashtable_insert( struct  hashtable_head  * ptr, char   * value, int  len)
 67  {
 68       int  hash_id;
 69       struct  table_node  * node;
 70          if ( ! value)
 71              return  NULL;
 72      hash_id = DJB_Hash(value,len);
 73      node  =  ( struct  table_node  * )malloc( sizeof ( struct  table_node));
 74           if  ( ! node) {
 75           return  NULL;
 76      }
 77      node -> value = value;
 78      node -> next = NULL;
 79       if (ptr -> buckets[hash_id].head == NULL)
 80      {
 81          ptr -> buckets[hash_id].head = node;
 82          node -> prev = NULL;
 83      }
 84       if (ptr -> buckets[hash_id].tail){
 85          ptr -> buckets[hash_id].tail -> next = node;
 86          node -> prev = ptr -> buckets[hash_id].tail;
 87      }
 88      ptr -> buckets[hash_id].tail = node;
 89      ptr -> end_iterator += 1 ;
 90       return   0 ;
 91  }
 92  /* ******************************************************************
 93   *
 94   *查询HASH_TABLE中value在BUCKETS[]中的哪一个,通过计算KEY确定下标
 95   *
 96    */
 97  int  hashtable_find_buckets( struct  hashtable_head  *  ptr, char   * value, int  len)
 98  {
 99       int  key = 0 ;
100       struct  table_node  * temp;
101       if (ptr == NULL || value == NULL)
102           return   0 ;
103 
104      key = DJB_Hash(value,len);
105       if (key < 0 )
106      {
107           return   - 1 ;
108      }
109      temp = ptr -> buckets[key].head;
110       while (temp != NULL){
111           if ( ! strcmp(( const   char   * )(temp -> value),value)){
112               return  key;
113          }
114           else {
115              temp = temp -> next;
116          }
117          
118      }    
119       return   - 1 ;
120  }
121  /* ******************************************************************
122   *
123   *查询HASH_TABLE中value在BUCKETS[key]中的具体位置
124   *
125    */
126  int  hashtalbe_find_node( struct  hashtable_head  * ptr, char   *  value, int  len)
127  {
128       int  key = 0 ;
129       int  node = 1 ;
130       struct  table_node  * temp;
131       if (ptr == NULL || value == NULL)
132           return   0 ;
133 
134      key = DJB_Hash(value,len);
135       if (key < 0 )
136      {
137           return   - 1 ;
138      }
139      temp = ptr -> buckets[key].head;
140       while (temp != NULL){
141           if ( ! strcmp(( const   char   * )(temp -> value),value)){
142               return  node;
143          }
144           else {
145              node += 1 ;
146              temp = temp -> next;
147          }
148          
149      }
150  }
151  /* ******************************************************************
152   *
153   *显示HASH_TABLE里所有数据
154   *
155    */
156  int  hashtable_display( struct  hashtable_head  * ptr)
157  {
158      unsigned  int  i;
159       struct  table_node  *  node;
160       if  (ptr == NULL){
161          printf( " the table is null " );
162           return   0 ;
163      }
164       for (i = 0 ;i < ptr -> table_size;i ++ ){
165          node = ptr -> buckets[i].head;
166           if (node == NULL)
167              printf( " buckets[%d]=null\n " ,i);
168           else {
169               while (node){
170                  printf( " buckets[%d]=%s\t " ,i,node -> value);
171                  node = node -> next;
172              }
173              printf( " \n " );
174          }
175      }
176       return   1 ;
177  }
178  /* ******************************************************************
179   *
180   *删除一指定值
181   *
182    */
183  int  hashtable_del( struct  hashtable_head  * ptr, char   *  value, int  len)
184  {
185       int  key = 0 ;
186       struct  table_node  * temp;
187       if (ptr == NULL || value == NULL)
188           return   0 ;
189      key = DJB_Hash(value,len);
190       if (key < 0 ){
191           return  NULL;
192      }
193      temp = ptr -> buckets[key].head;
194       if ( ! temp){
195          printf( " NO %s FOUND\n " ,value);
196           return  NULL;
197      }
198       while (temp != NULL){
199           if ( ! strcmp(( const   char   * )(temp -> value),value)){
200               if ( ! temp -> next){
201                   if (ptr -> buckets[key].head == temp){
202                      ptr -> buckets[key].head = NULL;
203                      ptr -> buckets[key].tail = NULL;
204                  }
205                   else {
206                      temp -> prev -> next = NULL;
207                      ptr -> buckets[key].tail = temp -> prev;
208                  }
209              }
210               else {
211                   if (ptr -> buckets[key].head == temp){
212                      ptr -> buckets[key].head = temp -> next;
213                      ptr -> buckets[key].tail = temp -> next;
214                  }
215                   else {
216                  temp -> prev -> next = temp -> next;
217                  temp -> next -> prev = temp -> prev;
218                  }
219              }
220              ptr -> end_iterator -= 1 ;
221               return   1 ;
222          }
223          temp = temp -> next;
224      }
225  }
226  /* ****************************************
227   *
228   *删除整个HASH_TABLE,释放内存
229   *
230    */
231 
232  int  hashtable_remove( struct  hashtable_head  * ptr)
233  {
234          unsigned  int  i,j;
235           struct  table_node  *  node;
236           if  (ptr  ==  NULL)
237                   return   - 1 ;
238           for  (i  =   0 ; i  <  ptr -> table_size; i ++ ) {
239               if  (ptr -> buckets[i].head  !=  NULL) {
240                  node = ptr -> buckets[i].tail;
241                   while  (node){
242                      free(node -> value);
243                      free(node);
244                 }
245              }
246          }
247          free(ptr -> buckets);
248          free(ptr);
249           return   0 ;
250  }
251 
252  /* ******************************************************************
253   *
254   *A test 
255   *
256    */
257  int  main()
258  {
259       struct  hashtable_head  * ptr = NULL;
260       int  key,node,i = 0 ;
261       char   * name1[] = {
262       " hippies " , " min " , " linyun " , " chenyu " , " wenli " , " zhaoyuanyuan " , " huangjingxing " ,
263       " lishaojie " , " laoma " , " xiaoyu " , " chentao " , " guojunjie " , " xiaobanzhang " , " caizhongyuan " ,
264       " heqiang " , " wangpai " , " wangzhitong " , " yixia " , " huangxuehong " , " bodong " , " liyong " ,
265       " liujinling " , " liuyuezhong " ,     " meilijia " , " wangyinqi " , " zhangbo " , " zhangwen " , " zouyinghua " ,NULL
266      };
267      ptr = hashtable_init( 50 );
268       if ( ! ptr)
269          printf( " error\n " );
270       for (i = 0 ;name1[i] != NULL;i ++ ){
271           // printf("%s is %d\n",name1[i],strlen(name1[i]));
272          hashtable_insert(ptr,name1[i],strlen(name1[i]));
273      }
274      hashtable_display(ptr);
275       char   * name = name1[ 2 ];
276       int  len = strlen(name);
277       if ((key = hashtable_find_buckets(ptr,name,len)) >= 0 )
278          printf( " the %s is in buckets of %d\n " ,name,key);
279       else  printf( " \nthe %s not found in the hashtable \n " ,name);
280       if ((node = hashtalbe_find_node(ptr,name,len)) >= 0 )
281          printf( " the %s is in node of %d \n " ,name,node);
282       else  printf( " \nthe %s not found in the hashtable \n " ,name);
283      hashtable_del(ptr,name,len);
284      hashtable_display(ptr);
285       return   0 ;
286  }
287 


你可能感兴趣的:(哈希表(连接法)V0.000001)