哈希開鏈法詳解c++

一、概述

這是哈希的一種算法,算是衝突比較少的,但是也難免會有。

這是我們需要探究的問題,開鏈法就是好方法之一。

開鏈法原理比較簡單,代碼比較玄學,大家要在學習的過程之中動手模擬,才能完全掌握它。

int hash(string h)
{
	int seed=37,p=10007;
	int ans=0;
	int len=h.length();
	for(int i=0;i<n;i++)
	{
		ans=(ans*seed+h[i]-'0')%p;
	}
	return ans;
}

二、原理分析

結構假如要用形象來表示,就如下圖所示:

 假如說我們要對以下一些數據進行哈希儲存(%53):

1 2 3 4 5 6 7 8 9
0 51 53 55 105 106 2 52
0 3 51 0 2 52 0 2 52

*第一行是編號,第二行是原始數據,第三行是哈希後結果。

按開鏈法儲存之後如圖所示:

三、代碼講解

原理十分簡明,而代碼卻不好實現,需要大家細細揣摩。

操作時代碼從下向上看的!

首先,關於hash的大多數程序實現都離不開兩個數組:

first[i]:表示哈希值爲i的第一個數的下標(用來記錄第i列最末的數據是第幾個輸入的)

next[i]:表示第i個數據的下一個數據(用來記錄第i個數的上方)

就拿第一列來說吧

當讀入0時    first[0]=1;next1]=0;

當讀入53時   first[0]=2;next[2]=1;

當讀入106時 first[0]=3;next[3]=2;

比如說我要進行查找,慧聰first[hash(h)]開始,逐個向上查找。

四、程序設計

對於一個程序來說,有一些基本操作是需要掌握的,難度主要是while的操作和兩個數組的相關性。

部分代碼爲玄學操作,建議帶入模擬一下。

給個哈希簡單代碼,之後的程序圍繞它來展開:

int hash(string h)
{
	int seed=37,p=10007;
	int ans=0;
	int len=h.length();
	for(int i=0;i<n;i++)
	{
		ans=(ans*seed+h[i]-'0')%p;
	}
	return ans;
}

1、插入

尤其注意兩個數之間的關係,建議帶數據模擬!

int add(string h)
{
	int sum=hash(h);//用sum來記錄該數據所存的數組 
	
	int u=first[sum];//這個主要用於下一步的去重 
	while(u)//這一步用來去重,原理是借組next數組枚舉查找,這個while是比較巧妙的寫法 
	{
		if(data[u]==h)//一模一樣 
		return 0;//返回 
		u=next[u];//使用next數組接着往下(也就是上)找 
	}
	
	++cnt;//這是添加的第幾個數據 
	data[cnt]=h;//將原始數據保存在data數組中,也就是在for循環時就直接對輸入進行操作
	 
	//下面兩步個人認爲有點鏈式結構的感覺 ,難點就是這裏 
	next[cnt]=first[sum];//第cnt個數據的下(也就是上)一個數據是第幾個cnt 
	first[sum]=cnt;//更新本數列最下端的數爲第幾cnt 
	return 1;//成功添加 
}

2、查找

插入的翻版,對while判定的改變。

int find(string h)
{
	int sum=hash(h);//同上 
	int u=hash[sum];//同上 
	while(u)//注意改變 
	{
		if(data[u]==h)//如果有 
		return 1;//ture
		u=next[u];//接着找 
	}
	return 0;//都沒有就爲假 
} 

3、刪除

本板塊的難點在pre上。

void delete(string h)
{
	int sum=hash(h);//找到它的列 
	int pre,u;//pre的作用是判斷刪除的是不是頭結點,u還是記錄它上面的值 
	pre=u=first[sum];//記錄 
	while(u)
	{
		if(data[u]==h) break;//找到了這個數據,往下走
		//這兩步可以使u比pre早一個版本 
		pre=u;
		u=next[u];
	}
	if(pre==u) first[sum]=next[u];//刪除的節點是頭結點,隊列末尾位次編號修改一下 
	else next[pre]=next[u];//刪除的節點不是頭結點 ,鏈表中撿摘除一部分後重新鏈接 
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章