第一关:采用除留余数法加线性探测法建立哈希表
#include"stdio.h"
#include"stdlib.h"
#define NULL_KEY -1
#define SUCCESS 1
#define UNSUCCESS 0
#define DUPLICATE -1
#define N 100
typedef int KeyType;
struct ElemType
{
KeyType key;
};
struct HashTable
{
ElemType *elem;
int count;
int sizeindex;
};
void InitHashTable(HashTable &H);
void DestroyHashTable(HashTable &H);
unsigned Hash(KeyType K);
void collision(int &p,int d);
int SearchHash(HashTable H,KeyType K,int &p,int &c);
int InsertHash(HashTable &H,ElemType e);
void TraverseHash(HashTable H,void(*Vi)(int));
void print(int p);
int m=0;
int main()
{
ElemType r[N]={
0};
HashTable h;
int i,p,n;
int j;
KeyType k;
InitHashTable(h);
scanf("%d",&m);
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d",&r[i].key);
}
for(i=0;i<n;i++)
{
j=InsertHash(h,r[i]);
}
TraverseHash(h,print);
DestroyHashTable(h);
}
void InitHashTable(HashTable &H)
{
int i;
H.count=0;
scanf("%d",&H.sizeindex );
H.elem=(ElemType*)malloc(H.sizeindex*sizeof(ElemType));
for(i=0;i<H.sizeindex;i++)
H.elem[i].key=NULL_KEY;
}
void DestroyHashTable(HashTable &H)
{
free(H.elem);
H.elem=NULL;
H.count=0;
H.sizeindex=0;
}
unsigned Hash(KeyType K)
{
return K%m;
}
void collision(int &p,int d)
{
p=(p+1)%m;
}
int SearchHash(HashTable H,KeyType K,int &p,int &c)
{
p=Hash(K);
while( H.elem[p].key!=NULL_KEY && K!= H.elem[p].key )
{
c++;
if(c<H.sizeindex)
collision(p,c);
else
break;
}
if (K == H.elem[p].key)
return SUCCESS;
else
return UNSUCCESS;
}
int InsertHash(HashTable &H,ElemType e)
{
int c,p;
c=0;
if(SearchHash(H,e.key,p,c))
return DUPLICATE;
else if(c<H.sizeindex)
{
H.elem[p]=e;
++H.count;
return SUCCESS;
}
else
return UNSUCCESS;
}
void TraverseHash(HashTable H,void(*Vi)(int))
{
printf("哈希地址0~%d\n",H.sizeindex-1);
for(int i=0;i<H.sizeindex;i++)
Vi(i);
printf("\n");
for(int i=0;i<H.sizeindex;i++)
Vi(H.elem[i].key);
printf("\n");
}
void print(int p)
{
printf("%d\t",p);
}
第二关:在采用除留余数法加线性探测法建立的哈希表中查找数据
#include"stdio.h"
#include"stdlib.h"
#define NULL_KEY -1
#define SUCCESS 1
#define UNSUCCESS 0
#define DUPLICATE -1
#define N 100
typedef int KeyType;
struct ElemType
{
KeyType key;
};
struct HashTable
{
ElemType *elem;
int count;
int sizeindex;
};
void InitHashTable(HashTable &H);
void DestroyHashTable(HashTable &H);
unsigned Hash(KeyType K);
void collision(int &p,int d);
int SearchHash(HashTable H,KeyType K,int &p,int &c);
int InsertHash(HashTable &H,ElemType e);
void TraverseHash(HashTable H,void(*Vi)(int));
void print(int p);
int Find(HashTable H,KeyType K,int &p);
int m=0;
int main()
{
ElemType r[N]={
0};
HashTable h;
int i,p,n;
int j;
KeyType k;
InitHashTable(h);
scanf("%d",&m);
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d",&r[i].key);
}
for(i=0;i<n;i++)
{
j=InsertHash(h,r[i]);
}
TraverseHash(h,print);
scanf("%d",&k);
j=Find(h,k,p);
if(j==SUCCESS)
{
printf("查找成功:");
print(h.elem[p].key);
}
else
printf("查找失败\n");
DestroyHashTable(h);
}
void InitHashTable(HashTable &H)
{
int i;
H.count=0;
scanf("%d",&H.sizeindex );
H.elem=(ElemType*)malloc(H.sizeindex*sizeof(ElemType));
for(i=0;i<H.sizeindex;i++)
H.elem[i].key=NULL_KEY;
}
void DestroyHashTable(HashTable &H)
{
free(H.elem);
H.elem=NULL;
H.count=0;
H.sizeindex=0;
}
unsigned Hash(KeyType K)
{
return K%m;
}
void collision(int &p,int d)
{
p=(p+1)%m;
}
int SearchHash(HashTable H,KeyType K,int &p,int &c)
{
p=Hash(K);
while( H.elem[p].key!=NULL_KEY && K!= H.elem[p].key )
{
c++;
if(c<H.sizeindex)
collision(p,c);
else
break;
}
if (K == H.elem[p].key)
return SUCCESS;
else
return UNSUCCESS;
}
int InsertHash(HashTable &H,ElemType e)
{
int c,p;
c=0;
if(SearchHash(H,e.key,p,c))
return DUPLICATE;
else if(c<H.sizeindex)
{
H.elem[p]=e;
++H.count;
return SUCCESS;
}
else
return UNSUCCESS;
}
void TraverseHash(HashTable H,void(*Vi)(int))
{
printf("哈希地址0~%d\n",H.sizeindex-1);
for(int i=0;i<H.sizeindex;i++)
Vi(i);
printf("\n");
for(int i=0;i<H.sizeindex;i++)
Vi(H.elem[i].key);
printf("\n");
}
void print(int p)
{
printf("%d\t",p);
}
int Find(HashTable H,KeyType K,int &p)
{
p=Hash(K);
int c=0;
while(H.elem[p].key!=NULL_KEY&&H.elem[p].key!=K)
{
c++;
printf("哈希地址为%d,第%d次冲突\n",p,c);
if(c<H.sizeindex)
{
collision(p,c);
}
}
c++;
if(H.elem[p].key==K)
{
printf("哈希地址为%d,第%d次查找成功\n",p,c);
return SUCCESS;
}
else
{
printf("哈希地址为%d,第%d次查找为空\n",p,c);
return UNSUCCESS;
}
}
第三关:采用除留余数法加链地址法建立哈希表
#include <stdio.h>
#include <stdlib.h>
#define N 20
typedef int KeyType;
struct ElemType
{
KeyType key;
};
typedef struct Node {
ElemType r;
struct Node* next;
}Node;
typedef struct {
Node** rcd;
int size;
int count;
}HashTable;
int InitHash(HashTable& H, int size);
int DestroyHash(HashTable& H);
Node* SearchHash(HashTable H, KeyType key);
int InsertHash(HashTable& H, ElemType e);
int DeleteHash(HashTable& H, KeyType key, ElemType& e);
void HashTraverse(HashTable H);
unsigned Hash(KeyType K,int m);
int m,n,i,j;
int main()
{
HashTable h;
KeyType k;
ElemType r[N]={
0};
scanf("%d",&m);
scanf("%d",&n);
InitHash(h,m);
for(i=0;i<n;i++)
{
scanf("%d",&r[i].key);
}
for(i=0;i<n;i++)
{
InsertHash(h, r[i]);
}
printf("采用链地址法得到的哈希表为:\n");
HashTraverse(h);
DestroyHash(h);
}
unsigned Hash(KeyType K,int m)
{
return K%m;
}
int InitHash(HashTable& H, int size)
{
H.rcd = (Node**)malloc(size*sizeof(Node*));
if (H.rcd != NULL)
{
for (int i = 0; i < size; i++)
{
H.rcd[i] = NULL;
}
H.size = size;
H.count = 0;
return 1;
}
else
{
return 0;
}
}
int DestroyHash(HashTable& H)
{
if (H.rcd != NULL)
{
Node* np, * nt;
for (int i = 0; i < H.size; i++)
{
np = H.rcd[i];
while (np != NULL)
{
nt = np;
np = np->next;
free(nt);
}
}
H.size = 0;
H.count = 0;
return 1;
}
else
{
return 0;
}
}
Node* SearchHash(HashTable H, KeyType key)
{
int p;
Node* np;
p = Hash(key,H.size);
np = H.rcd[p];
while (np)
{
if(key == np->r.key)
return np ;
np = np->next;
}
return NULL;
}
int InsertHash(HashTable& H, ElemType e)
{
int p;
Node* np;
np = SearchHash(H, e.key);
if (np == NULL)
{
p = Hash(e.key,H.size);
np = (Node*)malloc(sizeof(Node));
np->r = e;
np->next = H.rcd[p];
H.rcd[p] = np;
H.count++;
return 1;
}
else
{
return 0;
}
}
void HashTraverse(HashTable H)
{
if (H.rcd != NULL)
{
Node* np, * nq;
for (int i = 0; i < H.size; i++)
{
printf("%d: ", i);
if (H.rcd [i])
{
printf("%d ",H.rcd [i]->r .key);
Node* curr=H.rcd [i]->next;
while (curr) {
printf("-> %d ", curr->r.key);
curr=curr->next;
}
printf("\n");
}
else
printf("-\n");
}
}
}
第四关:在采用除留余数法加链地址法建立的哈希表中删除数据
#include <stdio.h>
#include <stdlib.h>
#define N 20
typedef int KeyType;
struct ElemType
{
KeyType key;
};
typedef struct Node {
ElemType r;
struct Node* next;
}Node;
typedef struct {
Node** rcd;
int size;
int count;
}HashTable;
int InitHash(HashTable& H, int size);
int DestroyHash(HashTable& H);
Node* SearchHash(HashTable H, KeyType key);
int InsertHash(HashTable& H, ElemType e);
int DeleteHash(HashTable& H, KeyType key, ElemType& e);
void HashTraverse(HashTable H);
unsigned Hash(KeyType K,int m);
int main()
{
HashTable h;
KeyType k;
ElemType r[N]={
0},e;
int m,n,i,j;
scanf("%d",&m);
scanf("%d",&n);
InitHash(h,m);
for(i=0;i<n;i++)
{
scanf("%d",&r[i].key);
}
for(i=0;i<n;i++)
{
InsertHash(h, r[i]);
}
printf("采用链地址法得到的哈希表为:\n");
HashTraverse(h);
scanf("%d",&k);
if ( DeleteHash(h, k, e) )
{
printf("删除元素后哈希表为:\n");
HashTraverse(h);
}
else
printf("删除元素失败。\n");
DestroyHash(h);
}
unsigned Hash(KeyType K,int m)
{
return K%m;
}
int InitHash(HashTable& H, int size)
{
H.rcd = (Node**)malloc(size*sizeof(Node*));
if (H.rcd != NULL)
{
for (int i = 0; i < size; i++)
{
H.rcd[i] = NULL;
}
H.size = size;
H.count = 0;
return 1;
}
else
{
return 0;
}
}
int DestroyHash(HashTable& H)
{
if (H.rcd != NULL)
{
Node* np, * nt;
for (int i = 0; i < H.size; i++)
{
np = H.rcd[i];
while (np != NULL)
{
nt = np;
np = np->next;
free(nt);
}
}
H.size = 0;
H.count = 0;
return 1;
}
else
{
return 0;
}
}
Node* SearchHash(HashTable H, KeyType key)
{
int p;
Node* np;
p = Hash(key,H.size);
np = H.rcd[p];
while (np)
{
if(key == np->r.key)
return np ;
np = np->next;
}
return NULL;
}
int InsertHash(HashTable& H, ElemType e)
{
int p;
Node* np;
np = SearchHash(H, e.key);
if (np == NULL)
{
p = Hash(e.key,H.size);
np = (Node*)malloc(sizeof(Node));
np->r = e;
np->next = H.rcd[p];
H.rcd[p] = np;
H.count++;
return 1;
}
else
{
return 0;
}
}
int DeleteHash(HashTable& H, KeyType key, ElemType& e)
{
Node* n;
n = SearchHash(H, key);
if (n != NULL)
{
int p = Hash(key,H.size);
Node* np, * nq;
np = H.rcd[p];
nq = NULL;
while (np != NULL)
{
if (np->r.key != key)
{
nq = np;
np = np->next;
}
else
{
e = np->r;
if (nq == NULL)
{
H.rcd[p] = np->next;
}
else
{
nq->next = np->next;
}
break;
}
}
H.count--;
free(np);
return 1;
}
else
{
return 0;
}
}
void HashTraverse(HashTable H)
{
if (H.rcd != NULL)
{
Node* np, * nq;
for (int i = 0; i < H.size; i++)
{
printf("%d: ", i);
if (H.rcd [i])
{
printf("%d ",H.rcd [i]->r .key);
Node* curr=H.rcd [i]->next;
while (curr) {
printf("-> %d ", curr->r.key);
curr=curr->next;
}
printf("\n");
}
else
printf("-\n");
}
}
}