1. 程式人生 > 其它 >雜湊表設計

雜湊表設計

技術標籤:資料結構c語言演算法雜湊表

實驗 雜湊表設計

資料結構課設 發出來分享 水平有限 希望各位網友多多交流和指正

一、實驗目的
熟練掌握雜湊表的構造方法,深刻理解雜湊表與其他結構表的實質性差別。

二、實驗原理
程式的功能是對一批關鍵字集合採用除留餘數法和線性探測再雜湊的方法解決衝突來建立相應的雜湊表和完成查詢過程及平均查詢長度的計算。
【問題描述】
研究雜湊(HAXI)表查詢技術的兩個重要問題是:構造HAXI函式和處理衝突。現在要求針對某個資料集合中的關鍵字設計一個雜湊表(選擇合適的雜湊函式和處理衝突的方法),完成HAXI表的建立、查詢,並計算HAXI表查詢成功的平均查詢長度。HAXI函式的構造方法有多種,其中除留餘數法是一種最簡單和最常用的方法。

考慮具體問題的關鍵字集合,如{19,14,23,1,68,20,84,27,55,11,10,79}這樣一組資料和給定的雜湊表長m 或雜湊表的裝填因子a,選用除留餘數法和線性探測再雜湊技術解決衝突所形成的雜湊表以及該雜湊表在查詢成功時的平均查詢長度ASL。
三、演算法分析與設計
1、演算法分析
HAXI表是根據設定的HAXI函式和處理衝突的方法將一組關鍵字對映到一個有限的連續的地址區間上,並以關鍵字在地址區間的“象”作為記錄在表中的儲存位置。因此我們可以採用動態分配的順序儲存結構表示HAXI表。
2、資料結構設計

typedef struct {
    KeyType key ;
}ElemType;
//元素型別的定義 ElemType *HAXI;//動態分配的雜湊表的首地址

3、演算法過程設計
要採用先存入資料後建立雜湊表,為了解決衝突的問題
(1)void InPut(ElemType **ST,int n)輸入n個數據存入採用動態分配的陣列空間的資料表ST。
(2)void Creat(ElemType **HAXI,ElemType ST,int n,int m)根據資料表ST,構造雜湊表HAXI,n,m分別為資料集合ST和雜湊表的長度。在雜湊表建立的過程中用線性探測再雜湊技術確定存放位置,即while( (*HAXI)[j].key!=NULL) j=(j+1)%m;
(3)int haxi(KeyType key,int m)在建立雜湊表的時候為了解決衝突需要找到P,即小於或等於HAXI 表長的最大質數。

(4)int search(ElemType *HAXI,KeyType key,int m,int &time)在表長為m的雜湊表中查詢關鍵字等於key的元素,並用 time記錄比較次數,若查詢成功,函式返回值為其在雜湊表中的位置,否則返回-1。
四、演算法實現
1、源程式(見附錄)
2、測試結果截圖
在這裡插入圖片描述

附錄:
源程式:

#include <iostream>
#include <bits/stdc++.h>
#define NULL 0
using namespace std;
typedef int KeyType;//元素的型別 
typedef struct {
    KeyType key ;
}ElemType;      //元素型別的定義

int haxi(KeyType key,int m)
{
	int i,p,flag=1;
	for(p=m;p>=2;p--)
	{
		for(i=2,flag=1;i<p/2&&flag;i++)
		{
			if(p%i==0) flag=0;
		}
		if(flag==1) break;
	}
	return key%p;
}
int search(ElemType *HAXI,KeyType key,int m,int &time)
{
	int i;
	time=1;
	i=haxi(key,m);
	while(HAXI[i].key!=0 && HAXI[i].key!=key)
	{
		i++;
		time++;
	}
	if(HAXI[i].key==0) return -1;
	else return i;
}
void InPut(ElemType **ST,int n)
{
	KeyType key;
	(*ST)=(ElemType*)malloc(n*sizeof(ElemType));
	cout<<"請輸入各個關鍵字"<<endl;
	for(int i=0;i<n;i++)
	{
		cin>>(*ST)[i].key;
	}
}
void Creat(ElemType **HAXI,ElemType *ST,int n,int m)
{
	int i,j;
	(*HAXI)=(ElemType*)malloc(m*sizeof(ElemType));
	for(i=0;i<m;i++)
	{
		(*HAXI)[i].key=NULL;
	}
	for(i=0;i<n;i++)
	{
		j=haxi(ST[i].key,m);
		while( (*HAXI)[j].key!=NULL)
		{
			j=(j+1)%m;
		}
		(*HAXI)[j].key=ST[i].key;
	}
}
int main()
{
	ElemType *ST,*HAXI;
	KeyType key;
	int n,m,stime=0,time=1;
	cout<<"輸入關鍵字個數和表長(n m且n<=m)"<<endl;
	cin>>n>>m;
	InPut(&ST,n);
	Creat(&HAXI,ST,n,m);
	for(int i=0;i<m;i++)
	{
		printf("%5d",i);
	}
	cout<<endl;
	for(int i=0;i<m;i++)
	{
		printf("%5d",HAXI[i].key);
	}
	cout<<endl;
	cout<<"輸入要查詢的關鍵字"<<endl;
	cin>>key;
	int k;
	k=search(HAXI,key,m,time);
	if(k!=-1)
	{
		cout<<"查詢次數為:"<<time<<endl;
	}
	else
	{
		cout<<"查詢失敗"<<endl;
	}
	int i;
	for(stime=0,i=0;i<n;i++)
	{
		search(HAXI,ST[i].key,m,time);
		stime+=time;
	}
	cout<<"平均查詢長度為:"<<(float)stime/n;
	return 0;
}
/*
19 14 23 1 68 20 84 27 55 11 10 79
*/