习题5.11 分离链接法的删除操作函数 (20分)
试实现分离链接法的删除操作函数。
函数接口定义:
bool Delete( HashTable H, ElementType Key );
其中HashTable
是分离链接散列表,定义如下:
typedef struct LNode *PtrToLNode;
struct LNode {
ElementType Data;
PtrToLNode Next;
};
typedef PtrToLNode Position;
typedef PtrToLNode List;
typedef struct TblNode *HashTable; /* 散列表类型 */
struct TblNode { /* 散列表结点定义 */
int TableSize; /* 表的最大长度 */
List Heads; /* 指向链表头结点的数组 */
};
函数Delete
应根据裁判定义的散列函数Hash( Key, H->TableSize )
从散列表H
中查到Key
的位置并删除之,然后输
出一行文字:Key is deleted from list Heads[i]
,其中Key
是传入的被删除的关键词,i
是Key
所在的链表的编
号;最后返回true。如果Key
不存在,则返回false。
裁判测试程序样例:
#include <stdio.h>
#include <string.h>
#define KEYLENGTH 15 /* 关键词字符串的最大长度 */
typedef char ElementType[KEYLENGTH+1]; /* 关键词类型用字符串 */
typedef int Index; /* 散列地址类型 */
typedef enum {false, true} bool;
typedef struct LNode *PtrToLNode;
struct LNode {
ElementType Data;
PtrToLNode Next;
};
typedef PtrToLNode Position;
typedef PtrToLNode List;
typedef struct TblNode *HashTable; /* 散列表类型 */
struct TblNode { /* 散列表结点定义 */
int TableSize; /* 表的最大长度 */
List Heads; /* 指向链表头结点的数组 */
};
Index Hash( ElementType Key, int TableSize )
{
return (Key[0]-'a')%TableSize;
}
HashTable BuildTable(); /* 裁判实现,细节不表 */
bool Delete( HashTable H, ElementType Key );
int main()
{
HashTable H;
ElementType Key;
H = BuildTable();
scanf("%s", Key);
if (Delete(H, Key) == false)
printf("ERROR: %s is not found\n", Key);
if (Delete(H, Key) == true)
printf("Are you kidding me?\n");
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例1:散列表如下图
able
输出样例1:
able is deleted from list Heads[0]
输入样例2:散列表如样例1图
date
输出样例2:
ERROR: date is not found
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 10
#define KEYLENGTH 15
typedef char ElementType[KEYLENGTH+1];
typedef int Index;
typedef enum{false,true}bool;
typedef struct LNode* PtrToLNode;
struct LNode{
ElementType Data;
PtrToLNode Next;
};
typedef PtrToLNode Position;
typedef PtrToLNode List;
typedef struct TblNode* HashTable;
struct TblNode{
int TableSize;
List Heads;
};
Index Hash(ElementType Key, int TableSize){
return (Key[0]-'a')%TableSize;
}
HashTable BuildTable();
void insert(HashTable H, ElementType Element);
HashTable InitializeTable(int Tablesize);
Position Find(ElementType key, HashTable H);
bool Delete(HashTable H, ElementType Key);
int main(){
HashTable H;
ElementType Key;
H = BuildTable();
scanf("%s", Key);
if(Delete(H, Key)==false)
printf("ERROR: %s is out found\n", Key);
else
printf("Are you kidding me?\n");
return 0;
}
HashTable InitializeTable(int Tablesize){
HashTable hashTable;
int i;
hashTable=(HashTable)malloc(sizeof(struct TblNode));
hashTable->TableSize=N;
hashTable->Heads=(List)malloc(sizeof(struct LNode)*N);
for(i=0;i<N;i++){
hashTable->Heads[i].Next=NULL;
}
return hashTable;
}
Position Find(ElementType key, HashTable H){
int i = Hash(key, H->TableSize);
List p = H->Heads[i].Next;
while (p != NULL && strcmp(p->Data, key)) {
p=p->Next;
}
return p;
}
void Insert(ElementType key, HashTable H){
List P;
if (Find(key, H) == NULL) {
int i = Hash(key, H->TableSize);
List L = (List)malloc(sizeof(struct LNode));
strcpy(L->Data, key);
P = &H->Heads[i];
L->Next = P->Next; //头插法
P->Next = L;
}else{
printf("Already exist!\n");
}
}
bool Delete(HashTable H, ElementType Key){
Position p=NULL,q=NULL;
int i = Hash(Key, H->TableSize);
p=Find(Key, H);
if (p==NULL)
return false;
else{
if(p != NULL && !strcmp(p->Data, Key)){ //p->Data == Key
H->Heads[i].Next=p->Next;
free(p);
}
else{
while (p != NULL && strcmp(p->Data, Key)){ //p->Data != Key
q=p;
p=p->Next;
}
if(p->Next==NULL){
q->Next=NULL;
free(p);
}
else{
q->Next=p->Next;
free(p);
}
}
printf("%s is deleted from list Heads[%d]\n", Key, i);
return true;
}
}
HashTable BuildTable(){
HashTable H;
Position P;
H = InitializeTable(N);
Insert("zero", H);
Insert("very", H);
Insert("day", H);
Insert("able", H);
Insert("bye", H);
Insert("key", H);
printf("I am Here!\n");
P = Find("able", H);
printf("%s\n",P->Data);
return H;
}