数据结构HASH总结二:程序学习篇

在理论学习篇中,我提到要学会Hash表初始化、插入元素、查找元素三大操作。
在介绍三大操作之前,首先介绍所用到的数据结构。
一、数据结构
     1.hash表的结构
          接下来介绍的都是hash表的拉链法。有两种hash表的结构,推荐使用结构二。详细说明见下面。
          结构一
//hash table
typedef   struct  _HASH_TABLE{
      NODE * HashTb[HASH_LEN];
}HASH_TABLE;
          结构二
struct  yk_hash_counter_entry {
        unsigned   int  hit_count;
        unsigned   int  entry_count;
        struct  yk_hash_key *keys;
};
     2.hash表的桶的结构,即hash表中链表的结点结构
     结构一
//node
typedef   struct  _NODE{
      type           data;
        struct  _NODE * next;
}NODE;
     结构二
struct  yk_hash_key {
        type  key;
        struct  yk_hash_key *next;
};
     说明:
          1)hash表中链表的结点结构是一样的,即包含数据(未hash过的真实数据)及next指针。
          2)hash表的结构推荐结构二,因为在结构二中,包含了除了链表以外的其他信息,更加方便使用。
那么接下来详细论述一下三大操作。
二.Hash表初始化
     1.固定长度的Hash表初始化
               固定长度的Hash表初始化是最简单的也是最常用的一种初始化方式。
                Hash表初始化:就是为hash表数组分配空间,并都赋值为0. 
               给出结构二的Hash表初始化
               
void  hashtest_init()
{
        int  i;

      hash_call_count = 0;
      hlist = (  struct  yk_hash_counter_entry *) malloc (  sizeof (  struct yk_hash_counter_entry) *  backet_len);
        if  (NULL == hlist)
      {
            perror(  "malloc in hashtest_init"  );
              return  ;
      }
        for  (i = 0; i < backet_len; i++)
      {
            hlist[i].hit_count = 0;
            hlist[i].entry_count = 0;
            hlist[i].keys = NULL;
      }
}
     2.长度动态变化的Hash表初始化
          目前我只在Nginx的Hash实现中看到长度动态变化的Hash表的初始化。其原理是根据要插入的元素的数目,动态调整Hash表数组的长度。
          详见文章:


三、插入元素
          插入元素key的原理:
               记hash函数为hash_func,要插入元素为key。
               1)对于每一个元素key,首先计算其Hash值,hash_value=hash_func(key)。通过hash_value定位到hash表的第hash_value个元素。
               2)如果hash表的第hash_value个元素为空,那么直接插入一个结点,结点内容就是该key
               3)如果hash表的第hash_value个元素不为空,那么检查hash表中是否存在相同元素key,如果存在就退出,不存在的话继续执行。
               4)遍历完整个hash表,依旧不存在相同元素key,那么就新建一个结点,结点内容是该key,然后将该结点插入到链表的末尾。
           函数实现:
            
STATUS insert_data_into_hash(HASH_TABLE * HashTb,type data)
{
        unsigned   long  key;
      NODE * pNode,*pNewNode;
        if  (HashTb == NULL)
              return  FALSE;
      key = HashInt(data);
        if  ((pNode = HashTb->HashTb[key]) == NULL){

              if  ((pNewNode = (NODE*)malloc( sizeof  (NODE))) == NULL)
                    return  FALSE;
            memset(pNewNode,0,  sizeof  (NODE));
            pNewNode->data = data;
            pNewNode->next = NULL;

            HashTb->HashTb[key] = pNewNode;
            printf(  "insert succeed \n"  );
              return  TRUE;
      }  /*if*/

        if  ( (find_data_from_hash(HashTb,data)) ){  /*if data exits in hash table,it should return FALSE*/
            printf(  "data %d exits in hash table\n"  ,data);
              return  FALSE;
      }

        for  (;pNode->next;){
            pNode = pNode->next;
      }  /*for*/

        if  ((pNewNode = (NODE*)malloc( sizeof  (NODE))) == NULL)
                          return  FALSE;
      memset(pNewNode,0,  sizeof  (NODE));
      pNewNode->data = data;
      pNewNode->next = NULL;

      pNode->next = pNewNode;  /*insert data to end of chain*/
        return  TRUE;
}


四、查找元素
           插入元素key的原理:
               记hash函数为hash_func,要插入元素为key。
               1)对于每一个元素key,首先计算其Hash值,hash_value=hash_func(key)。通过hash_value定位到hash表的第hash_value个元素。
               2)如果hash表的第hash_value个元素为空,返回NULL,不存在该结点
               3)如果hash表的第hash_value个元素不为空,那么检查hash表中是否存在相同元素key,如果存在就返回该结点的地址,不存在的话返回NULL。
               
NODE* find_data_from_hash(HASH_TABLE * HashTb,type data)
{

        unsigned   long  key;
      NODE * pNode;

        if  (HashTb == NULL)
              return  NULL;
      key = HashInt(data);
        if  ((pNode = HashTb->HashTb[key]) == NULL){
            printf(  "NO CHAIN\n"  );
              return  NULL;
      }
        for  (;pNode;pNode = pNode->next){
              if  (data == pNode->data)
                    return  pNode;
      }
      printf(  "NO Data\n"  );
        return  NULL;
}

五、总结
          这是Hash的基础内容,要想进一步学习,就必须先学会这些基本内容。
          这部分程序的完整代码,请到下面网址进行下载 http://download.csdn.net/detail/yankai0219/4768791
















  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值