数据结构---哈希表/散列表

#include "stdio.h" #include "stdlib.h" #define SUCCESS 1 #define UNSUCCESS 0 #define DUPLICATE -1 #define OK 1 #define ERROR -1 #define EQ(a,b) ((a)==(b)) #define LT(a,b) ((a)< (b)) #define LQ(a,b) ((a)<=(b)) #define BT(a,b) ((a)> (b)) #define NULLKEY -111 int hashsize[]={11,19,29,37}; // 哈希表容量递增表, //一个合适的素数序列 int m=0; // 哈希表表长,全局变量 typedef int KeyType; typedef int info; typedef struct { KeyType key; //info otherinfo; }ElemType; typedef struct { ElemType *elem; int count; int sizeindex; }HashTable; int InitHashTable(HashTable &H) { // 操作结果: 构造一个空的哈希表 int i; H.count=0; // 当前元素个数为0 H.sizeindex=0; // 初始存储容量为hashsize[H.sizeindex] m=hashsize[0]; H.elem=(ElemType*)malloc(m*sizeof(ElemType)); if(!H.elem) exit(0); // 存储分配失败 for(i=0;i<m;i++) H.elem[i].key=NULLKEY; // 未填记录的标志 return OK; } void DestroyHashTable(HashTable &H) { // 初始条件: 哈希表H存在。操作结果: 销毁哈希表H free(H.elem); H.elem=NULL; H.count=0; H.sizeindex=0; }//DestroyHashTable int Hash(KeyType K) { // 一个简单的哈希函数(m为表长,全局变量) //除留余数法 return K%m; }//Hash void collision(int &p,int d) // 线性探测再散列 { // 开放定址法处理冲突 p=(p+d)%m; }//collision int SearchHash(HashTable H,KeyType K,int &p,int &c) { p=Hash(K); //求得哈希地址 while(H.elem[p].key!=NULLKEY && !EQ(K,H.elem[p].key)) //如果该位置填有记录,并且关键字不相等 { collision(p,++c); //探测下一个位置p if(c>=m) break; } if(EQ(K,H.elem[p].key)) //查找成功,p返回待查数据元素位置 return SUCCESS; else //查找不成功(H.elem[p].key==NULLKEY) return UNSUCCESS; //p返回的是插入位置 }//SearchHash int InsertHash(HashTable &H,ElemType e); void RecreateHashTable(HashTable &H) // 重建哈希表 { int i,count=H.count; ElemType *p,*elem=(ElemType*)malloc(count*sizeof(ElemType)); p=elem; printf("重建哈希表\n"); for(i=0;i<m;i++) // 先保存原有的数据到elem中 if((H.elem+i)->key!=NULLKEY) // 该单元有数据 *p++=*(H.elem+i); H.count=0; // H.coun重置为0 H.sizeindex++; // 增大存储容量 m=hashsize[H.sizeindex]; p=(ElemType*)realloc(H.elem,m*sizeof(ElemType)); if(!p) exit(-1); // 存储分配失败 H.elem=p; for(i=0;i<m;i++) H.elem[i].key=NULLKEY; // 未填记录的标志(初始化) for(p=elem;p<elem+count;p++) // 将原有的已经保存的数据按照新的表长插入到重建的哈希表中 InsertHash(H,*p); }//RecreateHashTable int InsertHash(HashTable &H,ElemType e) { // 查找不成功时插入数据元素e到开放定址哈希表H中,并返回OK; // 若冲突次数过大,则重建哈希表 int c,p; c=0; if(SearchHash(H,e.key,p,c)) // 表中已有与e相同的元素 return DUPLICATE; //SUCCESS=1 else if(c<hashsize[H.sizeindex]/2) // 冲突次数c未达到上限,(c的阀值可调) { // 插入e H.elem[p]=e; ++H.count; return OK; } else RecreateHashTable(H); // 冲突次数c达到上限,将原来的哈希表重建,不包括现在正要插入的数据e return ERROR; } int InsertHashD(HashTable &H) { ElemType e; printf("input the data until -1\n"); scanf("%d",&e.key); while(e.key!=-1) { InsertHash(H,e); scanf("%d",&e.key); }//while return 1; }//InsertHashD int SearchHashD(HashTable &H) { KeyType key; int p=0,c=0; printf("input the data you want to search:\n"); scanf("%d",&key); if(SearchHash(H,key,p,c)) printf("the location is %d,%d\n",p,H.elem[p].key); else printf("Search Failed!\n"); return 1; }//SearchHashD void print(int p,ElemType r) { printf("address=%d (%d)\n",p,r.key); }//print void TraverseHash(HashTable H,void(*Vi)(int,ElemType)) { // 按哈希地址的顺序遍历哈希表 printf("哈希地址0~%d\n",m-1); for(int i=0;i<m;i++) if(H.elem[i].key!=NULLKEY) // 有数据 Vi(i,H.elem[i]); }//TraverseHash void TraverseHashD(HashTable &H) { TraverseHash(H,print); }//TraverseHashD int main() { HashTable H; InitHashTable(H); //初始化 InsertHashD(H); //构造哈希表 //SearchHashD(H); //查找 TraverseHashD(H); //遍历 DestroyHashTable(H); //销毁 return 1; }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值