[資料結構]-散列表(雜湊表)

來源:互聯網
上載者:User
      在這裡沒有新的原創性的東西。該部分內容主要取材於《軟體設計師教程》部分的內容。
      我想強調一種資料結構,散列表。它是基於快速存取的角度設計的,也是一種典型的“空間換時間”的做法。顧名思義,該資料結構可以理解為一個線性表,但是其中的元素不是緊密排列的,而是可能存在空隙。也就是說,比如我們儲存70個元素,但我們可能為這70個元素申請了100個元素的空間。70/100=0.7,這個數字稱為負載因子。我們之所以這樣做,也是為了“快速存取”的目的。我們基於一種結果儘可能隨機平均分布的固定函數H為每個元素安排儲存位置,這樣就可以避免遍曆性質的線性搜尋,以達到快速存取。但是由於此隨機性,也必然導致一個問題就是衝突。所謂衝突,即兩個元素通過散列函數H得到的地址相同,那麼這兩個元素稱為“同義字”。這類似於70個人去一個有100個椅子的飯店吃飯。散列函數的計算結果是一個儲存單位地址,每個儲存單位稱為“桶”。設一個散列表有m個桶,則散列函數的範圍應為[0,m-1]。
      解決衝突是一個複雜問題。衝突主要取決於:(1)散列函數,一個好的散列函數的值應儘可能平均分布。(2)處理衝突方法。(3)負載因子的大小。太大不一定就好,而且浪費空間嚴重,負載因子和散列函數是聯動的。
      解決衝突的辦法:
     (1)線性探查法:衝突後,線性向前試探,找到最近的一個空位置。缺點是會出現堆積現象。存取時,可能不是同義字的詞也位於探查序列,影響效率。
     (2)雙散列函數法:在位置d衝突後,再次使用另一個散列函數產生一個與散列表桶容量m互質的數c,依次試探(d+n*c)%m,使探查序列跳躍式分布。

      下面例子,為c語言一共32個關鍵字建立散列表,為簡單每個桶的容量為1,取負載因子=0.7,因此散列表大小32/0.7=47。雙散列函數解決衝突,補償函數H2的基數取和47互質的數為43。
       主要散列函數H1,取每三個字母為一段,每個字母佔據一個位元組,摺疊累加,取餘演算法。H2取每兩個字母為一段疊加。
      

Code
#define P1 47
#define P2 43
/* Compute Hash */
int GetHashCode(char *key,int iSection,int iBase, int offset)
{
    long k=0,d;
    int c;
    while(*key)
    {
        for(d=0,c=0; *key != '\0' && c < iSection; c++)
        {
            d=(d<<8)+(*key++);
        }
        k+=d;
    }
    return (k % iBase + offset);
}

/* Double Hash Function */
int H1(char *key)
{
    return GetHashCode(key, 3, P1, 0);
}
int H2(char *key)
{
    return GetHashCode(key, 2, P2, 1);
}

32個關鍵字,注意,volatile可能是使用不多的一個關鍵字,指示變數是易變的,禁止編譯器對取值進行最佳化。Code
char tbl[N][LEN];
char *kWord[]=
    {
        "auto",        "break",        "case",        "char",        "const",
        "continue",    "default",    "do",            "double",    "else",
        "enum",        "extern",    "float",        "for",        "goto",
        "if",            "int",        "long",        "register",    "return",
        "short",        "signed",    "sizeof",   "static",    "struct",
        "switch",    "typedef",    "union",        "unsigned",    "void",
        "volatile",    "while"
    };

        對散列表進行儲存的作業碼。尋找代碼是類似的。用count數組記錄每個位置的衝突次數。Code
for(i=0;i< sizeof(kWord)/sizeof(kWord[0]); i++)
    {
        pos= H1(kWord[i]);
        c  = H2(kWord[i]);
        while(tbl[pos][0]!='\0' && strcmp(tbl[pos],kWord[i]))
        {
            count[pos]++;
            pos=(pos+c)%N;
            printf(",%d",pos);
        }
        strcpy(tbl[pos],kWord[i]);
    }

------------------------------------------------------------
儲存時,每個元素的探查序列如下(數字為數組元素索引值):
auto      : 12
break     : 11
case      : 40
char      : 41
const     : 33
continue  : 45
default   : 37
do        : 2
double    : 15
else      : 25
enum      : 30
extern    : 34
float     : 23
for       : 4
goto      : 41,37,33,29
if        : 4,26
int       : 39
long      : 23,13
register  : 28
return    : 16
short     : 13,25,37,2,14
signed    : 25,0
sizeof    : 0,43
static    : 18
struct    : 38
switch    : 15,18,21
typedef   : 26,7
union     : 6
unsigned  : 11,38,18,45,25,5
void      : 7,31
volatile  : 33,17
while     : 32

可見,最長的探查序列為6次。
-----------------------------------------------------
各元素在散列表中的分布如下:
 0: signed      2: do          4: for         5: unsigned    6: union
 7: typedef    11: break      12: auto       13: long       14: short
15: double     16: return     17: volatile   18: static     21: switch
23: float      25: else       26: if         28: register   29: goto
30: enum       31: void       32: while      33: const      34: extern
37: default    38: struct     39: int        40: case       41: char
43: sizeof     45: continue

存在衝突的位置的衝突計數如下:
count[ 0]=1    count[ 2]=1    count[ 4]=1    count[ 7]=1    count[11]=1
count[13]=1    count[15]=1    count[18]=2    count[23]=1    count[25]=3
count[26]=1    count[33]=2    count[37]=2    count[38]=1    count[41]=1
count[45]=1

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.