[轉]HASH查找的程序實現及性能分析

 本文轉自:http://www.169it.com. html

1 HASH查找基本原理 算法

  在哈希表上進行查找的過程和建表的過程基本一致。假設給定的值爲K,根據建表時設定的哈希函數H,計算出哈希地址H(K),若表中該地址對應的空間未被佔用,則查找失敗,不然將該地址中的結點與給定值K比較,若相等則查找成功,不然按建表時設定的處理衝突方法找下一個地址,如此反覆下去,直到找到某個地址空間未被佔用(查找失敗)或者關鍵字比較相等(查找成功)爲止。 函數

2 查找算法演示 性能

著名的ELFhash算法: spa

1
2
3
4
5
6
7
8
9
10
11
12
13
int ELFhash(char *key)
{
unsigned long h=0;
while(*key)
{
h=(h<<4)+*key++;
unsigned long g=h&0Xf0000000L;
if(g)
h^=g>>24;
h&=~g;
}
return h%MOD;
}

開放尋址法: 指針

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
HashTable InitializeTable( int TableSize )
{
    HashTable H;
    int i;
    /* 爲散列表分配空間。 */
    /* 有些編譯器不支持爲 struct HashTable 分配空間,聲稱這是一個不徹底的結構, */
    /* 可以使用一個指向 HashTable 的指針爲之分配空間。 */
    /* 如:sizeof( Probe ),Probe 做爲 HashTable 在 typedef 定義的指針。 */
    H = malloc( sizeof( struct HashTable ) );
    /* 散列表大小爲一個質數。 */
    H->TableSize = Prime;
    /* 分配表全部地址的空間。 */
    H->Cells = malloc( sizeof( Cell )  * H->TableSize );
    /* 地址初始爲空。 */
    for( i = 0; i < H->TableSize; i++ )
        H->Cells[i].info = Empty;
    return H;
}


查找空單元並插入:                        htm

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Position Find( ElementType Key, HashTable H )
{
    Position Current;
    int CollisionNum;
    /* 碰撞次數初始爲0。 */
    /* 經過表的大小對關鍵字進行處理。 */
    CollisionNum = 0;
    Current = Hash( Key, H->TableSezi );
    /* 不爲空時進行查找。 */
    while( H->Cells[Current].info != Empty &&
        H->Cells[Current].Element != Key )
    {
        Current = ++CollosionNum * ++CollisionNum;
        /* 向下查找超過表範圍時回到表開頭。 */
        if( Current >= H->TableSize )
            Current -= H->TableSize;
    }
    return Current;
}

3 性能分析 ci

   散列表的查找過程基本上和造表過程相同。一些關鍵碼可經過散列函數轉換的地址直接找到,另外一些關鍵碼在散列函數獲得的地址上產生了衝突,須要按處理衝突的方法進行查找。在介紹的三種處理衝突的方法中,產生衝突後的查找仍然是給定值與關鍵碼進行比較的過程。因此,對散列表查找效率的量度,依然用平均查找長度來衡量。 get

  查找過程當中,關鍵碼的比較次數,取決於產生衝突的多少,產生的衝突少,查找效率就高,產生的衝突多,查找效率就低。所以,影響產生衝突多少的因素,也就是影響查找效率的因素。影響產生衝突多少有如下三個因素: 編譯器

(1)散列函數是否均勻;

(2)處理衝突的方法;

(3)散列表的載荷因子。

相關文章
相關標籤/搜索