编程中常用的重要的数据结构实现(一)之哈希表

来源:互联网 发布:百度地图js api周边 编辑:程序博客网 时间:2024/04/29 02:59

结构定义如下:  (注:实现方式有很多种,这只是其中一种,但大体思路都差不多)

 

typedef struct {

    void* data;

   unsigned int len;

}chashdatum;

 

struct chashcell {

    unsigned int func;

    chashdatum key;

    chashdatum value;

    struct chashcell* next;

};

 

typedef struct {

   unsigned int count;

  unsinged int  size;

  chashcell** cells;

}chash;

 

typedef chashiter  chashcell;

#define  DEFAULT_HASH_SIZE  12

#define  CHASH_MAXDEPTH 3

 哈希表的函数实现:

chash*  hash_new(int size)

{

     chash* hash = (chash*)malloc(sizeof(chash));

     if (NULL == hash)

          return NULL;

    if (size <  DEFAULT_HASH_SIZE )

          size = DEFAULT_HASH_SIZE;

     hash->cells = (strcut chashcell**)malloc(size * sizeof(struct chashcell* ));

     if (NULL == hash->cells)

    {

           free(hash);

          return NULL;

     }

    hash->count = 0;

    hash->size = size;

   return hash;

}

unsigned int chash_func(const char* key,    unsigned int len)

{

     register unsigned int c = 5381;

     register const char* k = key;

    while (len --)

   {

        c = ( (c<<5) + c) + *k++;

   }

   return c;

}

int chash_get(chash* hash,  chashdatum* key,  chashdatum* result)

{

     chashiter* iter;

     unsigned int func = chash_func(key->data,  key->len );

     iter = hash->cells[func % hash->size];

     while (iter)

     {

           if (iter->key.len == key->len && func == iter->func && !memcmp(iter->key.data,  key->data, key->len))

           { 

                  *result = iter->value;

                   return 0;

          }

          iter = iter->next;

     }

     return -1;

}

 

int chash_set(chash* hash,  chashdatum* key,  chashdatum* value)

{

       int count = hash->count + 1;

       if ( count > hash->size * CHASH_MAXDEPTH)

      {

           int r = chash_resize(hash, (hash->count / CHASH_MAXDEPTH) * 2 + 1);

             if (r < 0)

                 retrurn -1;

     }

       unsigned int func = chash_func(key->data, key->len);

       unsigned int indx = func % hash->size;

       chashiter* iter = hash->cells[index];

       chashiter* cell = NULL;

       while(iter)

       {

             if (iter->key.len == key->len && func == iter->func && !memcmp(iter->key.data,  key->data, key->len))      

             {

                   iter->value = value;

                     return 0;

              }

            iter = iter->next; 

      }

      cell = (struct chashcell*) malloc (sizeof(struct chashcell));

      if (NULL == cell)

           return -1;

     cell->key.data = key->data;

     cell->key.len = key->len;

     cell->value.data = value->data;

     cell->value.len = value->len;

     cell->func = func;

     cell->next = hash->cells[indx];

    hash->cells[indx] = cell;

    hash->count++; 

    return 0;

      

}

int chash_resize(chash* hash,   unsigned int size)

{

     strcut chashcell** cells;

     chashiterl* iter, *next;

     unsigned  int indx, nindx;

    if  (size == hash->size)

         return 0;

  cells = (struct chashcell**)malloc(size * sizeof(struct chashcell*));

  if (NULL == cells)

        return -1;

  for (indx = 0; indx < hash->size; indx++)

  {

        iter = hash->cells[indx];

        while (iter)

       {

             next = iter->next;

             nindx = iter->func % size;

            iter->next = cells[nindx];

            cells[nindx] = iter;

           iter = next;

       }

  }

 free(hash->cells);

 hash->cells = cells;

 hash->size = size;

  return 0; 

}

void chash_free(chash* hash)

{

     int indx;

     chashiter* iter, *next;

      for (indx = 0; indx < hash->size; indx++)

     {

            iter = hash->cells[indx];

            while (iter)

            {

                   next = iter->next;

                   free(iter);

                  iter = next;

            }

    }

  free(hash->cells);

  free(hash);

}

int chash_delete(chash* hash, chashdatum* key)

{

      unsigned int func = chash_func(key->data, key->len);

      int indx = func % hash->size;

      chashiter* iter = hash->cells[indx];

      while (iter)

      {

              if (iter->key.len == key->len && iter->func == func && !memcmp(iter->key.data,  key->data, key->len) )

              {

                    chash->cells[indx] = iter->next;

                     free(iter);

                    chash->count--;

                     return 0;

               }    

              iter = iter->next;

      }

     return -1;

}

void chash_clear(chash* hash)

{

       int indx;

       chashiter* iter;

       for(indx = 0; indx < hash->size; indx++)

       {

             iter = hash->cells[indx];

             while (iter)

             {

                   next = iter->next;

                   free(iter);

                   iter = next;

            }

       }

       memset(hash->cells, 0, hash->size * sizeof( struct chashcell*) );

       hash->count = 0;

}

chashiter* chash_begin(chash* hash)

{

         chashiter* iter;

        int indx = 0;

       iter = hash->cells[indx];

       while (!iter)

       {

              indx++;

             if (indx >= hash->size)

                 return NULL;

           iter = hash->cells[indx];

       }

      return iter;

}

chashiter* chash_next(chash* hash,  chashiter* iter)

{

      int indx = iter->func % hash->size;

      if (!iter)

            return NULL;

      iter = iter->next;

     while(!iter)

    {

          indx++;

        if (indx >= hash->size)

           return NULL;

        iter = hash->cells[indx];

    }

 return iter;

 }

int chash_count(chash* hash)

{

    return hash->count;

int chash_size(chash* hash)

{

    return hash->size;

}

void chash_key(chashiter* iter,  chashdatum* result)

{

        *result = iter->key;

}

void chash_value(chashiter* iter, chashdatum* result)

{

     *result = iter->value;

}

原创粉丝点击