哈希表的java實現


哈希表的java實現

什么是哈希表?

1.哈希表是通過關鍵碼key來直接進行訪問的一種數據結構
2.也就是它通過關鍵碼來值映射到表中的一個位置來訪問記錄,進而加快訪問的速度
3.存放記錄的數組叫做散列表(哈希表)

哈希表的根據解決沖突方式不同分為的兩種樣式

1.分離鏈接法

2.線性探測法

散列函數

1.什么是散列函數?

簡單的說,就是已知一個值value,通過將value代入散列函數就可以知道其在散列表中所存放的位置。

2.散列函數的例子

1.一般情況下如果輸入的數字是整數,那么合理的方法就是直接返回key mod tablesize,也就是散列函數是f(x)=x%tablesize
2.其中x是數值,而tablesize則是整個表的大小
3.假如x=13,tablesize=4,那么通過將x代入散列函數可以得到13 mod 4=1,那么由此可以得出13應當放在散列表的1這個下標的位置

沖突的問題

為什么會產生沖突?

1.假如同時又兩個值13,和17,tablesize=4,那么將這兩個值都代入散列函數,分別得到他們的下標分別是1,1。
2.你會發現他們放的位置是一樣的,但是table[1]這個位置只能放一個值,咋辦?如果硬放的話一個值會把另外一個值覆蓋掉,肯定不行

解決沖突的方法

1.分離鏈接法

這種方法,比較符合直接的思路,既然沖突,我們都將這兩個元素放到這個位置,摞起來不就行了,的確這是一種好方法,其實現是建立一張比較大的索引表,每一個
位置存放一個指向單鏈表的指針,沖突的元素依次插入這個單鏈表的末尾

2.開放尋址法

因為開放定址法必須放在表內,所以開放定址法所需要的表要比分離鏈接散列用表大。

代碼的實現

分離鏈接法

# include <iostream>
using namespace std;
 int MAXSIZE=20000;
 int Max=19999;
typedef struct node{
	int elem;
	struct node* next;
}NODE,*PNODE;//定義節點
typedef struct hash{
	struct node** hash_table;//哈希表 
}HASH; 
void Init_Hash(HASH  &HS);//初始化哈希表
int  Hash_function(int n);//哈希函數
void print_Hash(HASH &HS);//打印哈希表 
int main(void)
{
	HASH HS;
	Init_Hash(HS);
	print_Hash(HS);
	
	return 0;
}
void Init_Hash(HASH& HS)//將散列表輸入數據 
{
	int num;
	int site;
	cout<<"請輸入"<<MAXSIZE<<"個介於0-19999的整數"<<endl;
	HS.hash_table=new PNODE[MAXSIZE];
	//初始化散列表
	for(int i=0;i<MAXSIZE;i++)
	{
		HS.hash_table[i]=NULL;
	} 
	//依次輸入相應的值
	for(int i=0;i<MAXSIZE;i++)
	{
		cout<<"請輸入第"<<i+1<<"個數字:"<<endl;
		cin>>num;
		site=Hash_function(num);
		//cout<<site<<endl;
		if(HS.hash_table[site]==NULL)//不沖突的條件之下 
		{
			PNODE pnew=new NODE;
			pnew->elem=num;
			pnew->next=NULL;
			HS.hash_table[site]=pnew;		
		}
		else
		{
			PNODE visit=HS.hash_table[site];
			while(visit->next!=NULL)
			{
			//	cout<<"1"<<" "; 
				visit=visit->next;
			}
			PNODE pnew=new NODE;
			pnew->elem=num;
			pnew->next=NULL;
			visit->next=pnew;
		}
		
	}
	 
} 
int  Hash_function(int n)
{
	return n/2;
} 
void print_Hash(HASH &HS)
{
	cout<<"打印的哈希表為:"<<endl;
	for(int i=0;i<Max/2;i++)
	{
		if(HS.hash_table[i]!=NULL)
		{
			cout<<"下標為 "<<i+1<<" ";
			PNODE visit=HS.hash_table[i];
			while(visit!=NULL)
			{
				cout<<visit->elem<<" ";
				visit=visit->next;
			}
			cout<<"\n";
		}
	}
} 

開放尋址法

DateItem類

package hash;

public class DateItem {
	private int iData;

	public DateItem(int iData) 
	{

		this.iData = iData;
	}
	


	public int getKey() {
		// TODO Auto-generated method stub
		return this.iData;
	}
}

OpenAdressHashtable類

package hash;


public class OpenAdressHashtable {
	
	private DateItem[] hashArray;
	private int arraySize;
	private DateItem nonItem;
	
	public OpenAdressHashtable(int size)
	{
		arraySize=size;
		hashArray=new DateItem[arraySize];
		nonItem=new DateItem(-1);
	}
	
	public void showTable()//顯示哈希表
	{
		System.out.println("Table:");
		for(int j=0;j<arraySize;j++)
		{
			if(hashArray[j]!=null)
			{
				System.out.print(hashArray[j].getKey()+"");
			}
			else
			{
				System.out.print("*");
			}
		}
		System.out.println();
	}
	
	public int hashFunc(int key)//哈希函數
	{
		return key%arraySize;
	}
	
	public void insertIntoTable(DateItem item)//插入哈希表
	{
		int key=item.getKey();
		int hashVal=hashFunc(key);
		while(hashArray[hashVal]!=null&&hashArray[hashVal].getKey()!=-1)
		{
			hashVal++;//被占了,探測下一個位置
			hashVal%=arraySize;//防止越界
		}
		hashArray[hashVal]=item;//插入
	}
	
	//哈希表刪除
	public DateItem deleteItem(int key)
	{
		int hashVal=hashFunc(key);
		while(hashArray[hashVal]!=null)
		{
			if(hashArray[hashVal].getKey()==key)
			{
				DateItem temp=hashArray[hashVal];
				hashArray[hashVal]=nonItem;//刪除它
				return temp;
			}
			++hashVal;
			hashVal%=arraySize;
		}
		return null;
	}
	
	//哈希表查找
	
	public DateItem findItem(int key)
	{
		int hashVal=hashFunc(key);
		while(hashArray[hashVal]!=null)
		{
			if(hashArray[hashVal].getKey()==key)
			{
				return hashArray[hashVal];
			}
			hashVal++;
			hashVal%=arraySize;
	
		}
		return null;
	}

}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM