1. 程式人生 > >雜湊:線性探測再雜湊+除留餘數法

雜湊:線性探測再雜湊+除留餘數法

#include <bits/stdc++.h>
using namespace std;
#define MAXSIZE 100
typedef struct//雜湊表的結構體型別
{
    int data[MAXSIZE];//一個數組
    int sum;//sum存的是當前雜湊表中的元素個數
}HashTable;

void Init(HashTable &H)//雜湊表的初始化操作
{
    memset(H.data,0,MAXSIZE);
    H.sum=0;
}

int Hash(int n,int p)//雜湊函式,返回一個雜湊值,這裡採用除留餘數法(嚴書225頁)
{
    return n%p;
}

int InsertHash(HashTable &H,int key,int p)//在雜湊表H中插入一個關鍵字key,其中%p
{
    int k,d;
    d=0;//本次採用的是線性探測再雜湊,初始為0,如果發現衝突,就d++繼續進行探測,如果發現沒有元素,就插入
    k=Hash(key+d,p);//計算雜湊值
    while(H.sum!=MAXSIZE)//只要雜湊表沒有滿我就可以進行插入
    {
        if(!H.data[k])//如果這個地方空了,就插入
        {
            H.data[k]=key;
            H.sum++;
            return 1;
        }
        else//說明這個地方有別人了,那我得換一個地方,根據線性探測再雜湊的原則,我的d需要++然後再計算,直到找到一個空地方為止
        {
            d++;
            k=Hash(key+d,p);
        }
    }
    return 0;
}

int FindHash(HashTable H,int key,int p)//在雜湊表H中找到關鍵字key的陣列下標並返回,如果查詢失敗返回-1.查詢失敗有兩種情況,一是雜湊表是空的,二是表中該位置沒有記錄,即H.data[i]==0,也屬於查詢失敗的情況。
{
    int k,d;
    d=0;
    k=Hash(key+d,p);
    while(H.sum)//只要表不空
    {
        if(!H.data[k])
            return -1;//這個地方不存在元素,查詢失敗
        else if(H.data[k]==key)
            return k;
        else
        {
            d++;
            k=Hash(key+d,p);
        }
    }
    return -1;//空表啥也查不到,查詢失敗
}

int main()
{
    HashTable H;
    int x,n,p,i,t;
    while(scanf("%d%d",&n,&p)!=EOF)
    {
        Init(H);
        for(i=0;i<n;i++)
        {
            scanf("%d",&x);
            InsertHash(H,x,p);
        }
        printf("輸入你想查詢的數,返回其陣列下標,若查詢失敗則返回-1,如果你不想查了就輸入-999\n");
        scanf("%d",&t);
        while(t!=-999)
        {
            printf("%d\n",FindHash(H,t,p));
            scanf("%d",&t);
        }
    }
}