試實現線性探測法的查找函數。
函數接口定義:
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 -1
Position 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.
解題思路:
明確哈希表的創建過程,理清線性探測法的過程。
根據裁判定義的散列函數Hash( Key, H->TableSize ),從散列表H中查到Key的位置,如果找到則返回。注意若第一次查找未找到,繼續向後找,即代碼中用到的循環。如果第一次找時,該位置爲Empty,說明這個數不在該散列表裏面,因爲在創建過程中,如果該位置已被佔用,則應按公式尋找下一個空位置,如果沒被佔用,則該數存在此位置,所以不存在該數存在且第一次查找位置爲空的情況。
代碼
Position Find( HashTable H, ElementType Key )
{
Position p,m;
p=Hash( Key, H->TableSize );
if(H->Cells[p].Data==Key||H->Cells[p].Info==Empty)
return p;
else
{
for(int i=1;i<H->TableSize;i++)
{
m=(p+i)%H->TableSize;
if(H->Cells[m].Data==Key||H->Cells[m].Info==Empty)
return m;
}
return ERROR;
}
}