📄 hash.cpp
字号:
#include <stdio.h>
#include <malloc.h>
#include <process.h>
#include <iostream.h>
#define NULL_KEY 0
#define OVERFLOW -3
#define SUCCESS 1
#define UNSUCCESS 0
#define DUPLICATE -1
#define OK 1
#define ERROR 0
#define N 10
#define EQ(a,b) ((a)==(b))
#define LT(a,b) ((a)<(b))
#define LQ(a,b) ((a)<=(b))
typedef int Status;
int hashsize[]={11,19,29,37};
int m;
typedef struct
{
int *elem;
int count;
int sizeindex;
}HashTable;
void InitHashTable(HashTable *H)
{
H->count=0;
H->sizeindex=0;
m=hashsize[0];
H->elem=(int *)malloc(m*sizeof(int));
if(!H->elem)
exit(OVERFLOW);
for(int i=0;i<m;i++)
H->elem[i]=NULL_KEY;
}
/*void DestroyHashTable(HashTable *H)
{
free(H->elem);//?????
H->elem=NULL;
H->count=0;
H->sizeindex=0;
} */
int Hash(int k)
{
return k%m;
}
void collision(int &p,int collision)
{
p=(p+collision)%m;
}
Status SearchHash(HashTable *H,int key,int &p,int &c)
{
p=Hash(key);
int q=p;
while(H->elem[p]!=NULL_KEY && !EQ(key,H->elem[p]))
{
p=q;
c++;
collision(p,c);
}
if EQ(key,H->elem[p])
return SUCCESS;
else
return UNSUCCESS;
}
void TraverseHash(HashTable *H)
{
for(int i=0;i<m;i++)
if(H->elem[i]!=NULL_KEY)
cout<<"adress"<<"("<<i<<")"<<"="<<H->elem[i]<<endl;
}
//void RecreateHashTable();
Status InsertHash(HashTable *H,int k)
{
int p;
int c=0;
if(SearchHash(H,k,p,c))
return DUPLICATE;
else if(c<hashsize[(*H).sizeindex]/2)
{
(*H).elem[p]=k;
++(*H).count;
return OK;
}
else
//RecreateHashTable(H);
return ERROR;
}
void RecreateHashTable(HashTable *H)
{
int i,num;
num=H->count; //num为原哈希表中的记录数目
int *p=(int*)malloc(num*sizeof(int));
int *t=p;
printf("重建哈希表\n");
for(i=0;i<m;i++) //保存原有的数据到p中
if((H->elem[i])!=NULL_KEY) // 该单元有数据
{
*p=H->elem[i];
p++;
}
H->count=0;
H->sizeindex++; //增大存储容量
m=hashsize[H->sizeindex];
int *elem=(int*)malloc(m*sizeof(int));
if(!elem)
exit(OVERFLOW); //存储分配失败
for(i=0;i<m;i++)
H->elem[i]=NULL_KEY; //未填记录的标志(初始化)
for(i=0;i<num;i++) //将原有的数据按照新的表长插入到重建的哈希表中
{
InsertHash(H,*t);
t++;
}
}
Status Find(HashTable *H,int key,int &p)
{
int c=0;
p=Hash(key);
int q=p;
while(H->elem[p]!=NULL_KEY && !EQ(key,H->elem[p]))
{
c++;
p=q;
collision(p,c);
}
if EQ(key,H->elem[p])
return SUCCESS;
else
return UNSUCCESS;
}
int main()
{
int r[N]={17,60,29,38,60,2,3,4,1,13};//查找表
HashTable h;
int i,p;
Status j;
int k;
InitHashTable(&h);
for(i=0;i<N;i++) //插入前N-1个记录
{
j=InsertHash(&h,r[i]);
if(j==DUPLICATE)
cout<<"表中已有关键字为"<<r[i]<<"的记录,无法再插入记录"<<r[i]<<endl;
if(j==OK)
cout<<r[i]<<"插入成功!"<<endl;
if(j==ERROR)
{
cout<<r[i]<<"在插入过程中,冲突次数过大,所以重建哈希表"<<endl;
RecreateHashTable(&h);
j=InsertHash(&h,r[i]);
}
}
cout<<"按哈希地址的顺序遍历哈希表:"<<endl;
TraverseHash(&h);
cout<<"请输入待查找记录的关键字: "<<endl;
//while(getchar()!='a')
//{
cin>>k;
j=Find(&h,k,p); //查找
if(j==SUCCESS)
cout<<"adress"<<p<<"is"<<h.elem[p]<<endl;
//print(p,h.elem[p]);
else
cout<<"没找到"<<endl;
//}
cout<<"要插入的关键字"<<endl;
cin>>k;
j=InsertHash(&h,k); //插入记录
if(j==ERROR) // 重建哈希表
{
RecreateHashTable(&h);
j=InsertHash(&h,k); // 重建哈希表后重新插入记录
cout<<"按哈希地址的顺序遍历重建后的哈希表:"<<endl;
TraverseHash(&h);
}
if(j==DUPLICATE)
cout<<"表中已有关键字为<<r[i]<<的记录,无法再插入记录r[i]"<<endl;
if(j==OK)
cout<<"插入成功!"<<endl;
TraverseHash(&h);
//cout<<h.elem[1];
// DestroyHashTable(&h);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -