1. 程式人生 > 其它 >演算法與資料結構實驗五 查詢

演算法與資料結構實驗五 查詢

實驗專案名稱:實驗    查詢  

一、 實驗目的
1.掌握散列表的建立
2.掌握雜湊查詢演算法的實現。

二、 實驗內容

6-2 線性探測法的查詢函式

試實現線性探測法的查詢函式。

函式介面定義:

Position Find( HashTable H, ElementType Key );

其中HashTable是開放地址散列表,定義如下:

#define MAXTABLESIZE 100000  /* 允許開闢的最大散列表長度 */

typedef int ElementType;     /* 關鍵詞型別用整型 */

typedef int Index;           /* 雜湊地址型別 */

typedef Index Position;      /* 資料所在位置與雜湊地址是同一型別 */

/* 雜湊單元狀態型別,分別對應:有合法元素、空單元、有已刪除元素 */

typedef enum { Legitimate, Empty, Deleted } EntryType;

 

typedef struct HashEntry Cell; /* 散列表單元型別 */

struct HashEntry{

    ElementType Data; /* 存放元素 */

    EntryType Info;   /* 單元狀態 */

};

 

typedef struct TblNode *HashTable; /* 散列表型別 */

struct TblNode {   /* 散列表結點定義 */

    int TableSize; /* 表的最大長度 */

    Cell *Cells;   /* 存放雜湊單元資料的陣列 */

};

函式Find應根據裁判定義的雜湊函式Hash( Key, H->TableSize )從散列表H中查到Key的位置並返回。如果Key不存在,則返回線性探測法找到的第一個空單元的位置;若沒有空單元,則返回ERROR。

裁判測試程式樣例:

#include <stdio.h>#define MAXTABLESIZE 100000  /* 允許開闢的最大散列表長度 */typedef int ElementType;     /* 關鍵詞型別用整型 */typedef int Index;           /* 雜湊地址型別 */

typedef Index Position;      /* 資料所在位置與雜湊地址是同一型別 *//* 雜湊單元狀態型別,分別對應:有合法元素、空單元、有已刪除元素 */typedef enum { Legitimate, Empty, Deleted } EntryType;typedef struct HashEntry Cell/* 散列表單元型別 */struct HashEntry{    ElementType Data; /* 存放元素 */    EntryType Info;   /* 單元狀態 */};typedef struct TblNode *HashTable/* 散列表型別 */struct TblNode {   /* 散列表結點定義 */    int TableSize; /* 表的最大長度 */    Cell *Cells;   /* 存放雜湊單元資料的陣列 */};HashTable BuildTable(); /* 裁判實現,細節不表 */Position Hash( ElementType Key, int TableSize ){    return (Key % TableSize);}#define ERROR -1Position Find( HashTable H, ElementType Key );int main(){    HashTable H;    ElementType Key;    Position P;    H = BuildTable();     scanf("%d", &Key);    P = Find(H, Key);    if (P==ERROR)        printf("ERROR: %d is not found and the table is full.\n", Key);    else if (H->Cells[P].Info == Legitimate)        printf("%d is at position %d.\n", Key, P);    else        printf("%d is not found.  Position %d is returned.\n", Key, P);    return 0;}/* 你的程式碼將被嵌在這裡 */

輸入樣例1:(注:-1表示該位置為空。下同。)

11

11 88 21 -1 -1 5 16 7 6 38 10

38

輸出樣例1:

38 is at position 9.

輸入樣例2:

11

11 88 21 -1 -1 5 16 7 6 38 10

41

輸出樣例2:

41 is not found.  Position 3 is returned.

輸入樣例3:

11

11 88 21 3 14 5 16 7 6 38 10

41

輸出樣例3:

ERROR: 41 is not found and the table is full.

7-1 整型關鍵字的雜湊對映

給定一系列整型關鍵字和素數P,用除留餘數法定義的雜湊函式H(Key)=Key將關鍵字對映到長度為P的散列表中。用線性探測法解決衝突。

輸入格式:

輸入第一行首先給出兩個正整數N(≤1000)和P(≥N的最小素數),分別為待插入的關鍵字總數、以及散列表的長度。第二行給出N個整型關鍵字。數字間以空格分隔。

輸出格式:

在一行內輸出每個整型關鍵字在散列表中的位置。數字間以空格分隔,但行末尾不得有多餘空格。

輸入樣例:

4 5

24 15 61 88

輸出樣例:

4 0 1 3

三、 設計文件

 

 

四、 源程式

6-2 線性探測法的查詢函式

Position Find( HashTable H, ElementType Key ){

    int x=Hash(Key,H->TableSize);

    int a=0;

    while(a<H->TableSize){

        if( H->Cells[x].Info==Empty//題目裡還給了個Deleted,沒有測試點不鳥它了

           ||H->Cells[x].Data == Key){//可不能等於Legitimate

            return x;

        }

        x=(x+1)%H->TableSize;

        a++;

    }

    return ERROR;

}

 

 

 

 

 

 

7-1 整型關鍵字的雜湊對映

//輸入第一行首先給出兩個正整數N(≤1000)和P(≥N的最小素數)

//分別為待插入的關鍵字總數、以及散列表的長度。第二行給出N個整型關鍵字。數字間以空格分隔。

#include <iostream>

using namespace std;

const int MAX = 1000;

int main()

{

    int N,P;

    cin >> N >> P; //P為散列表的長度

    int data[MAX];//輸入資料

    for(int i = 0;i<N;i++)

    {

        cin >> data[i];

    }

    int HashList[P];

    int index[MAX];

    for(int i = 0;i<P;i++)

        HashList[i] = -1;

    for(int i = 0;i<N;i++)

    {

        int d,j = 0;//j為移動的位置

        d = data[i]%P;

        if(data[i]==HashList[d])

        {

            index[i] = d;

            continue;

        }

        while((HashList[d]!=-1)&&(j<P)&&(data[i]!=HashList[d]))//說明該位置沒有元素

        {

            j++;

            d = (d+1)%P;

        }

        HashList[d] = data[i];

        index[i] = d;

    }

    for(int i = 0;i<N-1;i++)

    {

        cout << index[i] << ' ';

    }

    cout << index[N-1];

    return 0;

}