習題5.10 線性探測法的查找函數 (20分)
試實現線性探測法的查找函數。
函數接口定義:
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.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define N 20
#define MAXTABLESIZE 10000
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();
int insert(HashTable H, ElementType key);
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;
}
HashTable BuildTable(){
HashTable hashTable;
int i,n,Data[N];
hashTable = (HashTable)malloc(sizeof(struct TblNode));
hashTable->Cells = (Cell*)malloc(sizeof(Cell)*N);
scanf("%d", &n);
hashTable->TableSize=n;
//初始化,設置初始狀態
for(i=0;i<N;i++)
hashTable->Cells[i].Info=Empty;
//生成隨機數
srand((unsigned int)time(0));
for (i=0;i<n;i++)
Data[i]=rand()%(100-10)+1;//rand();
//將數據插入表中
for(i=0;i<n;i++)
insert(hashTable, Data[i]);
for (i=0;i<n;i++)
printf("%d ", hashTable->Cells[i].Data);
printf("\n");
return hashTable;
}
int insert(HashTable H, ElementType key) //向hash表中插入元素
{
int p;
p=Hash(key, H->TableSize);
while(H->Cells[p].Info==Legitimate){
if(p==H->TableSize)
return ERROR;
p++;
}
H->Cells[p].Data=key;
H->Cells[p].Info=Legitimate;
return 0;
}
Position Find(HashTable H, ElementType Key){
Position p;
p = Hash(Key, H->TableSize);
while(!(H->Cells[p].Info==Legitimate && H->Cells[p].Data==Key)){
if(p==H->TableSize)
return ERROR;
p++;
}
return p;
}