數(shù)據(jù)結(jié)構(gòu)之哈希表

The night's sky is so big that you must find stars with your heart.

0_01291925244503.jpg

哈希表
基本思想:在記錄的存儲位置和它的關(guān)鍵字之間建立一個確定的對應(yīng)關(guān)系f,使得每一個關(guān)鍵字和結(jié)構(gòu)中一個唯一的存儲位置相對應(yīng)。在此,稱f為哈希函數(shù),按這個思想建立的表成為哈希表。
哈希沖突:若有不同的關(guān)鍵字key1 ,key2,并且key1 != key2,當(dāng)f(key1) = f(key2)時,這種現(xiàn)象成為哈希沖突。
哈希函數(shù)的構(gòu)造方法,一般都用的是除留余數(shù)法,即取關(guān)鍵字被某個不大于哈希表長m的數(shù)p除后所得余數(shù)為哈希地址,有如下:

 H(key) = key MOD p p <= m

用于解決哈希沖突的方法:線性探測,也就是當(dāng)產(chǎn)生哈希沖突時,后來的關(guān)鍵碼順序查找哈希表,并將它插入為空的地方。但用它刪除一個關(guān)鍵碼的時候,若被刪除的關(guān)鍵碼的前一個位置為空,就找不到要刪除的關(guān)鍵碼,并且利用線性探測容易產(chǎn)生二次聚集,所以一般建議采用鏈?zhǔn)焦#ㄦ湹刂贩ǎ﹣斫鉀Q哈希沖突。

example:一組關(guān)鍵字{19,14,23,01,68,20,84,27,55,11,10,79},將它們按哈希函數(shù)H(key) = key MOD 13和鏈地址法處理沖突,所得到的哈希表如下:


鏈?zhǔn)焦?/div>

代碼實戰(zhàn):

    //基本結(jié)構(gòu)定義
    #define M 13//選取求哈希地址(散列地址)的除數(shù)(哈希表的長度)
    typedef int KeyType;
    #define NIL -1
    typedef struct {}Record;//記錄集
    typedef struct //key_recptr
    {
         KeyType key;
         Record *recptr;
    } ElemType;
    typedef struct HashNode//哈希表中鏈表的每一個節(jié)點的定義
    {
         ElemType data;
         HashNode *next; 
    }HashNode;
    typedef struct HashTable
    {
          HashNode *table[M];//指針數(shù)組
          int sum;
    }HashTable;

  //購買節(jié)點和釋放節(jié)點
  HashNode *_BuyNode()
  {
       HashNode *s = (HashNode *)malloc(sizeof(HashNode));
       if(NULL == s)   exit(1);
       memset(s,0,sizeof(HashNode));
       return s;
  }
  
  void  _FreeNode( HashNode *p)
  {
        free(p);
  }

  //初始化
  void Init_Hash(HashTable *pt)
  {
       for(int i = 0;i < M;++i)
       {
            pt->table[i] = NULL;
       }
       pt->sum = 0;
  }

   //求哈希地址函數(shù)
   int Hash(KeyType kx)
   {
         return kx % M;
   }
   //查找函數(shù)
   int SearchNot(HashTable *pt,KeyType kx)
   {
        int pos = Hash(kx);
        HashNode *p = pt->table[pos];
        while(p != NULL && p->data.key != kx)
                     p = p->next;
        if(p == NULL)  return pos;
        else return -1;
   }
   //插入函數(shù)
    bool Insert(HashTable *pt,ElemType x)//利用頭插法,時間復(fù)雜度O(1)
    {
          bool res = false;
          int pos = SearchNot(pt,x.key);
          if(pos != -1)
          {
                HashNode *s = _BuyNode();
                s->data = x;
                s->next = pt->table[pos];
                pt->table[pos] = s;
                pt->sum += 1;
                res = true;
          }
          return res;
    }
    //刪除函數(shù)
    bool Remove(HashTable *pt,KeyType kx)
    {
          bool res = false;
          int pos = Hash(kx);
          HashNode *pr =  NULL,*p = pt->table[pos];
          while(p != NULL)
          {
                if(p->data.key == kx)
                {
                      if(pr == NULL)
                              pt->table[pos] = p->next;
                       else
                              pr->next = p->next;
                _FreeNode(p);
                res = true;
                break;
                }  
          pr = p;
          p = p->next;
          }
     return res;
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 概念 散列技術(shù): 在記錄的存儲位置和它的關(guān)鍵字之間建立一個確定的對應(yīng)關(guān)系f,使得每個關(guān)鍵字key對應(yīng)一個存儲位置f...
    liangxifeng833閱讀 2,677評論 1 3
  • clojure 新手指南-目錄 - climbdream的個人空間 - 開源中國社區(qū)https://my.osch...
    葡萄喃喃囈語閱讀 2,474評論 0 3
  • 李馨辰:新手投資原油需掌握以下技巧(華益金安)6.6 如何增大賺錢的幾率呢?有時候是你方向把握的不正確。有些吃虧是...
    MM蔡芬芬閱讀 218評論 0 0
  • 淡淡夜色淡淡愁,淡淡月兒掛高樓,淡淡清風(fēng)梳柳葉,淡淡虛竹倚墻頭。 淡淡書香入詞賦,淡淡風(fēng)華難自述,淡淡人影心頭立,...
    蓋飯狗熊閱讀 172評論 0 0
  • 有幾次經(jīng)過教堂,都是在外頭望一望,拍幾張照片就走了。而今晚,第一次參加了基督教的禮拜,原來是這么回事。 8點開始的...
    林含鍵閱讀 834評論 0 3

友情鏈接更多精彩內(nèi)容