構造一種儲存結構,通過某種函式(hashfunc)使元素的儲存位置與它的關鍵碼之間能夠建立一一對映的關係,那麼在查詢時通過該函式可以很快找到該元素。
說到雜湊表,,首先就得說到雜湊函式,雜湊函式是用來得到給定key值的在雜湊表中的儲存位置的。
雜湊函式也並不是固定的,可以自己根據情況來定,一般常用常見的有直接定製法,除留餘數法,平方取中法,摺疊法,隨機數法,數學分析法。
當向該結構插入元素時,存入根據關鍵碼以此函式計算出的位置,當搜尋時,也是先要將給定的關鍵碼用函式轉換成儲存位置進行查詢,將得到位置處的元素進行比較,若關鍵碼相同,則搜尋成功。
但是通過乙個雜湊函式得到的位置,一定是會有衝突的,
例如用除留餘數法,雜湊函式為key/100。在此情況下數字1與數字101得到的儲存位置就是相同的,這樣就是雜湊衝突, 雜湊衝突一般有兩種解決方式,一種是閉雜湊,另一種是開雜湊。
開雜湊(鏈位址法):首先對關鍵碼集合用雜湊函式計算雜湊表中的偏移位置,具有相同位址的關鍵碼歸於同一子集合,每乙個子集合稱為乙個桶,各個桶中的元素通過乙個單鏈表鏈結起來,各鍊錶的頭結點儲存在雜湊表中。
以下是閉雜湊實現的雜湊表:
閉雜湊就是用雜湊函式將每個值的所對應的下標算出,將每乙個元素放入雜湊表對應的下標元素中,若出現衝突則將當前的值放入算出的位置的下乙個空位中。
例如下圖中,假設使用的雜湊函式是用除留餘數法,用需要插入的陣列為arr=,雜湊表的最大長度為100,則1對應的下標就為1,2的下標就是2,這時出現了101,101的位置算出來也是1,這樣它就與1發生了雜湊衝突,101就需要繼續向後尋找空位,找到下標為3的地方,只要插入的元素數量沒有超過雜湊表的負載,就能一直往雜湊表中插入元素,如果當找到最後乙個元素還沒有找到空位,則需要將其下標設定為1,再繼續進行尋找知道找到第乙個空位。
雜湊表的標頭檔案:
#pragma once
#define hashmaxsize 1000 //巨集定義雜湊表的最大容量
#define loadfactor 0.8 //巨集定義負載因子,用於表示雜湊表的負載能力。
typedef int keytype;
typedef int valuetype;
typedef size_t(*hashfunc)(keytype key); //重定義雜湊函式
typedef enum stat //用於表示每個元素的狀態
stat;
typedef struct hashelem //雜湊表的元素結構體
hashelem;
typedef struct hashtable //雜湊表
hashtable;
//////
//////
//////
//////
///雜湊表的相關操作///
//////
//////
//////
//////
//////
//////
void hashtableinit(hashtable* ht,hashfunc hashfunc);
int hashtableinsert(hashtable* ht, keytype key, valuetype value);
//雜湊表的查詢,找到返回1,並返回這個結點的value值,未找到返回0
int hashtablefind(hashtable* ht, keytype key,valuetype* value,size_t* cur);
//刪除值為key的結點
void hashremove(hashtable* ht, keytype key);
///判斷雜湊表是否為空
int hashempty(hashtable* ht);
//求雜湊表的大小
size_t hashsize(hashtable* ht);
//銷毀雜湊表
void hashtabledestroy(hashtable* ht);
下面是對各類功能的實現:
size_t hashfuncdefault(keytype key)
//////
//////
//////
//////
//////
//////
//////
//////
//////
//////
//////
//////
//////
//////
void hashtableinit(hashtable* ht)
}//雜湊表的插入 ,插入成功返回1,插入失敗返回0
int hashtableinsert(hashtable* ht, keytype key, valuetype value)
cur++;
}}//雜湊表的查詢 找到返回1,沒找到返回0
int hashtablefind(hashtable* ht, keytype key, valuetype* value)
//若當前下標所對應的值不是key,則繼續向後進行查詢,直到找到stat等於empty
else
else
else
offset++;}}
return
0; }
}//刪除節點
int hashtablefindcur(hashtable* ht, keytype key, size_t* cur)
}return0;}
void hashremove(hashtable* ht, keytype key)
}int hashempty(hashtable* ht)
//求雜湊表的大小
size_t hashsize(hashtable* ht)
ht->size = 0;
}void hashprint(hashtable* ht,const
char* msg) //列印雜湊表
}
**測試結果如下:
該檔案的測試**:
#define __testhead__ printf("\n-----------------------%s--------------------------\n",__function__);
void testhashtableinsert(hashtable* ht)
void testhashtablefind(hashtable* ht)
void testhashremove(hashtable* ht)
void test()
}
雜湊表 C語言實現
這裡不講高深理論,只說直觀感受。雜湊表的目的就是為了根據資料的部分內容 關鍵字 直接計算出存放完整資料的記憶體位址。void list find by key list,key return p 為了解決根據關鍵字快速找到元素的存放位址,雜湊表應運而生。它通過某種演算法 雜湊函式 直接根據關鍵字計算...
c語言實現雜湊表
雜湊表大家都在資料結構中學習過,應該是查詢最快的一種資料結構了,最好的情況下可以達到線性的時間複雜度。鍵key的狀態碼如果為 vt undefined 的話那麼就是這個槽位沒有被占用或者已經被刪除了 值value的狀態碼有vt true和vt false兩種,只要這個槽位已經被占用過了,那麼valu...
資料結構 順序表(C語言實現)
順序表的定義是 把線性表中所有表項按照其邏輯順序依次儲存到從計算機儲存中指定儲存位置開始的一塊連續的儲存空間中。這樣,線性表中第乙個表項的儲存位置就是被指定的儲存位置,第i個表項 2 i n 的儲存位置緊接在第i 1個表項的儲存位置的後面。假設順序表中每個表項的資料型別為t,則每個表項所占用儲存空間...