3.2 鏈地址法
鏈地址法就是將相應(yīng)位置上沖突的所有關(guān)鍵詞存儲(chǔ)在同一個(gè)單鏈表中。
設(shè)關(guān)鍵字序列為 47 , 7 , 29 , 11 , 16 , 92 , 22 , 8 , 3 , 50 , 37 , 89 , 94 , 21 47, 7, 29, 11, 16, 92, 22, 8, 3, 50, 37, 89, 94, 2147,7,29,11,16,92,22,8,3,50,37,89,94,21,散列函數(shù)取為h ( k e y ) = k e y m o d ?? 11 h(key) = key \mod 11h(key)=keymod11,用分離鏈接法處理沖突。

表中有9個(gè)結(jié)點(diǎn)只需1次查找,5個(gè)結(jié)點(diǎn)需要2次查找,所以查找成功的平均查找次數(shù)為:
A S L s = ( 9 + 5 ? 2 ) / 14 ≈ 1.36
參考代碼:
#include
#include
#include
#include
#include
using namespace std;
#define MAXTABLESIZE 10000 //允許開(kāi)辟的最大散列表長(zhǎng)度
#define KEYLENGTH 100 //關(guān)鍵字的最大長(zhǎng)度
typedef int ElementType;
struct LNode
{
ElementType data;
LNode *next;
};
typedef LNode *PtrToNode;
typedef PtrToNode LinkList;
struct TblNode
{
int tablesize; //表的最大長(zhǎng)度
LinkList heads; //存放散列單元數(shù)據(jù)的數(shù)組
};
typedef struct TblNode *HashTable;
/返回大于n且不超過(guò)MAXTABLESIZE的最小素?cái)?shù)/
int NextPrime(int n)
{
int p = (n % 2) ? n + 2 : n + 1; //從大于n的下一個(gè)奇數(shù)開(kāi)始
int i;
while (p <= MAXTABLESIZE)
{
for (i = (int)sqrt(p); i > 2; i--)
{
if ((p % i) == 0)
break;
}
if (i == 2)
break; //說(shuō)明是素?cái)?shù),結(jié)束
else
p += 2;
}
return p;
}
/創(chuàng)建新的哈希表/
HashTable CreateTable(int table_size)
{
HashTable h = (HashTable)malloc(sizeof(TblNode));
h->tablesize = NextPrime(table_size);
h->heads = (LinkList)malloc(h->tablesize * sizeof(LNode));
//初始化表頭結(jié)點(diǎn)
for (int i = 0; i < h->tablesize; i++)
{
h->heads[i].next = NULL;
}
return h;
}
/查找數(shù)據(jù)的初始位置/
int Hash(ElementType key, int n)
{
//這里只針對(duì)大小寫(xiě)
return key % 11;
}
/查找元素位置/
LinkList Find(HashTable h, ElementType key)
{
int pos;
pos = Hash(key, h->tablesize); //初始散列位置
LinkList p = h->heads[pos].next; //從鏈表的第一個(gè)節(jié)點(diǎn)開(kāi)始
while (p && key != p->data)
{
p = p->next;
}
return p;
}
/插入新的元素/
bool Insert(HashTable h, ElementType key)
{
LinkList p = Find(h, key); //先查找key是否存在
if (!p)
{
//關(guān)鍵詞未找到,可以插入
LinkList new_cell = (LinkList)malloc(sizeof(LNode));
new_cell->data = key;
int pos = Hash(key, h->tablesize);
new_cell->next = h->heads[pos].next;
h->heads[pos].next = new_cell;
return true;
}
else
{
cout << "鍵值已存在!" << endl;
return false;
}
}
/銷毀鏈表/
void DestroyTable(HashTable h)
{
int i;
LinkList p, tmp;
//釋放每個(gè)節(jié)點(diǎn)
for (i = 0; i < h->tablesize; i++)
{
p = h->heads[i].next;
while (p)
{
tmp = p->next;
free(p);
p = tmp;
}
}
free(h->heads);
free(h);
}
int main(int argc, char const *argv[])
{
int a[] = {47, 7, 29,29, 11, 16, 92, 22, 8, 3, 50, 37, 89, 94, 21};
int n = 15;
HashTable h = CreateTable(n);
for (int i = 0; i < n; i++)
{
Insert(h, a[i]); //插入元素
}
for (int i = 0; i < h->tablesize; i++)
{
LinkList p = h->heads[i].next;
while (p)
{
cout << p->data << " "; //打印哈希表元素
p = p->next;
}
cout << endl;
}
return 0;
}
審核編輯:符乾江
-
代碼
+關(guān)注
關(guān)注
30文章
4977瀏覽量
74419 -
哈希函數(shù)
+關(guān)注
關(guān)注
0文章
43瀏覽量
9773
發(fā)布評(píng)論請(qǐng)先 登錄
塊RAM存儲(chǔ)器中的地址沖突場(chǎng)景
RK3562 單板機(jī)系統(tǒng)開(kāi)發(fā)完全手冊(cè):U-Boot/Kernel/Rootfs 開(kāi)發(fā)與性能優(yōu)化
C編譯器錯(cuò)誤與解決方法
ADI Trinamic如何讓伺服系統(tǒng)開(kāi)發(fā)化繁為簡(jiǎn)
瑞芯微 RK3588 平臺(tái) Debian 系統(tǒng)開(kāi)發(fā)案例與使用說(shuō)明
程序加載過(guò)程中遇到的問(wèn)題及其解決方法
睿擎混合部署方案:基于QT的電機(jī)驅(qū)動(dòng)系統(tǒng)開(kāi)發(fā)|技術(shù)集結(jié)
IP地址沖突導(dǎo)致德國(guó)站群服務(wù)器斷網(wǎng)的解決方法?
明遠(yuǎn)智睿SSD2351:開(kāi)啟嵌入式系統(tǒng)開(kāi)發(fā)新時(shí)代
明遠(yuǎn)智睿SSD2351:嵌入式系統(tǒng)開(kāi)發(fā)的卓越之選
國(guó)產(chǎn)主板無(wú)法開(kāi)機(jī)的狀況及解決方法
泰克MSO2024B混合信號(hào)示波器在嵌入式系統(tǒng)開(kāi)發(fā)中的應(yīng)用
電機(jī)常見(jiàn)的噪音、振動(dòng)問(wèn)題及解決方法
鴻蒙5開(kāi)發(fā)寶藏案例分享---一多開(kāi)發(fā)實(shí)例(游戲)
瑞芯微RK3506 3核A7@1.5GHz+雙網(wǎng)口+雙CAN-FD 工業(yè)開(kāi)發(fā)板—Linux系統(tǒng)開(kāi)發(fā)手冊(cè)
MASS競(jìng)猜幸運(yùn)哈希游戲系統(tǒng)開(kāi)發(fā)中沖突的解決方法
評(píng)論