本文轉自: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)散列表的載荷因子。