1. 程式人生 > >C語言實現雜湊表查詢演算法

C語言實現雜湊表查詢演算法

雜湊表(散列表)是直接通過關鍵字key得到要查詢的記錄的記憶體儲存位置。

雜湊技術是在記錄的儲存位置和它的關鍵字之間建立一個確定的對應關係f,使得每個關鍵字key對應一個儲存位置f(key)。

採用雜湊技術將記錄儲存在一塊連續的儲存空間中,這塊連續的儲存空間稱為散列表或者雜湊表。

整個雜湊過程分為兩步:

1.在儲存時,通過雜湊函式計算記錄的雜湊地址,並按此地址儲存該記錄。

2.當查詢記錄時,通過同樣的雜湊函式計算記錄的雜湊地址,按此地址方位記錄。

因此雜湊技術既是一種儲存方法也是一種查詢方法,資料元素之間不存在邏輯關係。

雜湊技術最合適的問題是查詢與給定值相等的記錄。

雜湊函式設計的兩個原則是計算簡單、雜湊地址分佈均勻。

最長用的方法是除留餘數法,f(key)=key mod p(p小於等於散列表的長度m)。

但雜湊函式可能會造成衝突,即兩個不同的記錄求得的雜湊地址一樣,解決雜湊衝突最常用的方法為開放定址法。一旦發生衝突,就去尋找下一個雜湊地址,只要散列表足夠大,空的雜湊地址總能找到。

以下程式在DEV C++中除錯執行通過。

#include<stdio.h>
#include<stdlib.h>

#define HASHSIZE 12
#define NULLKEY -32768
typedef struct
{
	int *elem;
	int count;
}HashTable;
int m=0;

//初始化散列表
int InitHashTable(HashTable *H)
{
	int i;
	m=HASHSIZE;
	H->count=m;
	H->elem=(int*)malloc(m*sizeof(int));
	for(i=0;i<m;i++)
		H->elem[i]=NULLKEY;
	return 1;
 }
 //雜湊函式
 int Hash(int key)
 {
 	return key%m;
  } 
  //插入關鍵字進入散列表
  void InsertHash(HashTable *H,int key)
  {
  	int addr=Hash(key);
  	while(H->elem[addr]!=NULLKEY)
  		addr=(addr+1)%m;
  	H->elem[addr]=key;
   } 
   
//散列表查詢關鍵字
int SearchHash(HashTable H,int key,int *addr)
{
	*addr=Hash(key);
	while(H.elem[*addr]!=key)
	{
		*addr=(*addr+1)%m;
		if(H.elem[*addr]==NULLKEY||*addr==Hash(key))
		{
			return -1;
		}
	}
	return *addr;
 } 
  
int main()
{
	int a[12]={12,67,56,16,25,37,22,29,15,47,48,34};
	HashTable H;
	int i;
	InitHashTable(&H);
	for(i=0;i<m;i++)
		InsertHash(&H,a[i]);
	printf("插入之後的雜湊表為:");
	for(i=0;i<m;i++)
		printf("%d,",H.elem[i]);
	int addr,j;
	j=SearchHash(H,a[5],&addr);
	printf("搜尋到a[5]的地址是:%d",j);
}

執行結果如圖所示。


如果沒有衝突,雜湊表查詢演算法的時間複雜度為O(1)。