【数据结构】顺序哈希表与链式哈希表
顺序哈希表
头文件
1 //@ author 成鹏致远 2 //@ net http://infodown.tap.cn 3 //@ qq 552158509 4 //@ blog lcw.cnblogs.com 5 6 #ifndef __HASHSQ_H 7 #define __HASHSQ_H 8 9 #include <stdio.h> 10 #include <stdlib.h> 11 #include <stdbool.h> 12 #include <math.h> 13 14 typedef struct hash_tbl 15 { 16 int len;//哈希表长度 17 int *parray;//指向表的首地址 18 }*p_hash_tbl; 19 20 extern void hash_init(p_hash_tbl *p_hash, int len);//初始化哈希表 21 extern int hash(p_hash_tbl phash, int key);//哈希函数,返回哈希地址 22 extern void hash_insert(p_hash_tbl phash, int key);//插入key值 23 extern void hash_show(p_hash_tbl phash, int hash_val, int key); 24 25 26 27 #endif
顺序哈希表
1 //@ author 成鹏致远 2 //@ net http://infodown.tap.cn 3 //@ qq 552158509 4 //@ blog lcw.cnblogs.com 5 6 //哈希函数:保留余数法 7 //处理冲突:开放地址法 8 9 #include "hash_sq.h" 10 11 void hash_init(p_hash_tbl *p_hash, int len)//初始化哈希表 12 { 13 int i; 14 15 *p_hash = (p_hash_tbl)malloc(sizeof(struct hash_tbl)); 16 if(NULL == *p_hash) 17 { 18 perror("hash_init(malloc)"); 19 exit(1); 20 } 21 (*p_hash)->len = len;//哈希表长度 22 (*p_hash)->parray = (int *)malloc(sizeof(int)*((*p_hash)->len));//申请哈希表指向的数组空间 23 24 //数组初始化 25 for(i=0; i<(*p_hash)->len; i++) 26 { 27 (*p_hash)->parray[i] = -1;//初始经为-1 28 } 29 } 30 31 int hash(p_hash_tbl phash, int key)//哈希函数,返回哈希地址 32 { 33 int hash_val; 34 35 //用除留余数构造hash函数 36 hash_val = key % 13;//13是哈希表长度的最大质数,可通过函数获得,这里略过 37 38 //用开放地址法处理冲突 39 while(-1 != phash->parray[hash_val])//冲突 40 { 41 hash_show(phash,hash_val,key);//如果有冲突,则显示哈希表冲突位置 42 hash_val = (hash_val+1) % phash->len; 43 sleep(1);//观察插入过程 44 } 45 sleep(1); 46 47 return hash_val; 48 } 49 50 void hash_insert(p_hash_tbl phash, int key)//插入key值 51 { 52 int hash_val; 53 54 hash_val = hash(phash, key);//求得哈希地址 55 hash_show(phash, hash_val, key);//显示哈希表 56 57 phash->parray[hash_val] = key;//插入键值 58 } 59 60 void hash_show(p_hash_tbl phash, int hash_val, int key) 61 { 62 int i; 63 64 for(i=0; i<phash->len; i++) 65 { 66 if(i == hash_val && -1 != phash->parray[hash_val])//冲突位置,在冲突处理中打印 67 { 68 printf("phash->parray%02d[%02d](Conflict)\t<---%d\n",i,phash->parray[i],key); 69 } 70 else if(i == hash_val)//可以在hash_val处插入 71 { 72 printf("phash->parray%02d[%02d](Insert)\t<---%d\n",i,phash->parray[i],key); 73 } 74 else//只需要else便可打印出哈希表的存储情况,加上以上两句只是为了观察构建哈希表的过程 75 { 76 printf("phash->parray%2d[%2d]\n",i,phash->parray[i]);//循环打印除了hash_val外的数组存储情况 77 } 78 } 79 printf("****************************************************\n"); 80 }
主文件
1 //@ author 成鹏致远 2 //@ net http://infodown.tap.cn 3 //@ qq 552158509 4 //@ blog lcw.cnblogs.com 5 6 //哈希函数:保留余数法 7 //处理冲突:开放地址法 8 9 #include "hash_sq.h" 10 11 int main() 12 { 13 int array[] = {23,34,14,38,46,16,68,15,07,31,26};//数组长11 14 p_hash_tbl p_hash;//指向哈希表 15 int len;//哈希表长度 16 int i; 17 18 len = ceil(11/0.75);//数组长度 / 装填因子 19 20 hash_init(&p_hash,len);//初始化哈希表 21 22 for(i=0; i<11; i++) 23 { 24 hash_insert(p_hash,array[i]);//依次插入哈希表中 25 } 26 27 return 0; 28 }
链式哈希表
头文件
1 //@ author 成鹏致远 2 //@ net http://infodown.tap.cn 3 //@ qq 552158509 4 //@ blog lcw.cnblogs.com 5 6 #ifndef __HASHLINK_H 7 #define __HASHLINK_H 8 9 #include <stdio.h> 10 #include <stdlib.h> 11 #include <stdbool.h> 12 13 typedef int datatype; 14 15 typedef struct node 16 { 17 datatype key; 18 struct node *next;//指向表的下一个元素 19 }list_node,*list_pnode; 20 21 typedef struct hash_tbl 22 { 23 int len;//哈希表长度 24 list_pnode *pnode;//指向链表 25 }*p_hash_tbl; 26 27 extern void hash_init(p_hash_tbl *p_hash, int len);//初始化哈希表 28 extern void hash_insert(p_hash_tbl phash, int key);//插入key值 29 extern void hash_show(p_hash_tbl phash, int hash_val, int key); 30 31 32 33 #endif
链式哈希表
1 //@ author 成鹏致远 2 //@ net http://infodown.tap.cn 3 //@ qq 552158509 4 //@ blog lcw.cnblogs.com 5 6 #include "hash_link.h" 7 8 void hash_init(p_hash_tbl *phash,int len)//初始化 9 { 10 int i; 11 12 *phash = (p_hash_tbl)malloc(sizeof(struct hash_tbl)); 13 if(NULL == *phash) 14 { 15 perror("hash_init(malloc)"); 16 exit(1); 17 } 18 (*phash)->len = len;//哈希链表长度 19 (*phash)->pnode = (list_pnode*)malloc(sizeof(list_pnode)*((*phash)->len)); 20 21 for(i = 0; i < (*phash)->len;i++) 22 ((*phash)->pnode)[i] = NULL;//先全部置空 23 } 24 25 void hash_insert(p_hash_tbl phash,int key)//哈希表插入 26 { 27 int hash_val; 28 list_pnode new; 29 30 /*用除留余数构造hash函数*/ 31 hash_val = key % 11;//11,哈希表长度 32 33 hash_show(phash,hash_val,key);//插入之前先看看哈希链表存储情况 34 35 sleep(1); 36 new = (list_pnode)malloc(sizeof(list_node));//新建节点 37 if(NULL == new) 38 { 39 perror("hash_insert(malloc)"); 40 exit(1); 41 } 42 new->key = key; 43 //把新节点插入到前一个节点后面 44 new->next = phash->pnode[hash_val]; 45 phash->pnode[hash_val] = new; 46 } 47 48 void hash_show(p_hash_tbl phash,int hash_val,int key)//显示哈希链表 49 { 50 int i; 51 list_pnode p; 52 53 for(i = 0; i< phash->len; i++) 54 { 55 #if 1//这个开关只是为了使结果更好看 56 if(i == hash_val && phash->pnode[hash_val] != NULL)//有冲突,插入前显示 57 { 58 p = phash->pnode[i]; 59 printf("phash->pnode[%02d]",i);//显示哈希地址 60 while(p != NULL)//显示该地址后的所有链表 61 { 62 printf(" -->[%02d]",p->key); 63 p = p->next; 64 } 65 printf("(Conflict)<---%d\n",key);//显示将要插入的节点 66 } 67 else if(i == hash_val)//该地址可以插入 68 printf("phash->pnode[%02d](Insert)\t<---%d\n",i,key);//显示地址和值 69 else//依次遍历哈希表所有的地址,显示指向的节点值 70 #endif 71 { 72 p = phash->pnode[i]; 73 printf("phash->pnode[%02d]",i); 74 while(p != NULL) 75 { 76 printf(" -->[%02d]",p->key); 77 p = p->next; 78 } 79 printf("\n"); 80 } 81 } 82 printf("********************************************************\n"); 83 }
主文件
1 //@ author 成鹏致远 2 //@ net http://infodown.tap.cn 3 //@ qq 552158509 4 //@ blog lcw.cnblogs.com 5 6 #include "hash_link.h" 7 8 int main(void) 9 { 10 int array[11] = {23,34,14,38,46,16,68,15,07,31,26}; 11 int len;//哈希表长度 12 int i; 13 p_hash_tbl phash; 14 15 len = 11; 16 17 hash_init(&phash,len); 18 19 for(i = 0; i < 11; i++) 20 { 21 hash_insert(phash,array[i]); 22 } 23 24 return 0; 25 }