哈希表的实现

来源:互联网 发布:微信编辑器php源代码 编辑:程序博客网 时间:2024/05/16 18:20
转自:http://blog.csdn.net/htyurencaotang/article/details/7881399

相关定义
:根据散列函数H(key)和处理冲突的方法将一组关键字映象到一个有限的连续的地址集(区间)上,并以关键字在地址集中的“象” 作为记录在表中的存储位置,这种表便称为散列表(或称哈希表),这一映象过程称为散列造表或散列,所得的存储位置称散列地址

构造哈希函数的方法: 

1. 直接寻址法;2. 数字分析法;3. 平方取中法; 

4. 折叠法;5. 随机数法;6. 除留余数法

处理冲突的方法

1. 开放寻址法:Hi=(H(key) + di) MOD m,i=1,2,…,k(k<=m-1),其中H(key)为散列函数,m为散列表长,di为

    增量序列,可有下列三种取法:  

     1.1. di=1,2,3,…,m-1,称线性探测再散列; 

     1.2. di=1^2,-1^2,2^2,-2^2,⑶^2,…,±(k)^2,(k<=m/2)称二次探测再散列; 

     1.3. di=伪随机数序列,称伪随机探测再散列。  

2. 再散列法:Hi=RHi(key),i=1,2,…,k RHi均是不同的散列函数,即在同义词产生地址冲突时计算另一个散列函数地址,直到冲突不再发生,这种方法不易产生“聚集”,但增加了计算时间。  

3. 链地址法  

4. 建立一个公共溢出区


代码:

[cpp] view plaincopy
  1. // HashTable.cpp : 定义控制台应用程序的入口点。  
  2. //哈希表的实现  
  3. //哈希函数采用除留余数法构造  
  4. //使用链地址法解决冲突  
  5.   
  6. #include "stdafx.h"  
  7. #include <iostream>  
  8. using namespace std;  
  9.   
  10. const int MAXSIZE = 100;   
  11. int a[MAXSIZE];  
  12.   
  13. //哈希表的结点类型  
  14. class HashNode  
  15. {  
  16. public:  
  17.     HashNode():next(NULL){};//默认构造函数  
  18.     HashNode(int item):data(item), next(NULL){};//一般构造函数  
  19.   
  20. private:  
  21.     int data;  
  22.     HashNode *next;  
  23.     friend class HashTable;  
  24. };  
  25.   
  26. //哈希表类型  
  27. class HashTable  
  28. {  
  29. public:  
  30.     HashTable();  
  31.     void Create(int *a, int n);//创建哈希表  
  32.     bool Find(int data);//查找  
  33.     void Insert(int data);//插入  
  34.     void Delete(int data);//删除  
  35.   
  36. private:      
  37.     HashNode *value[10];//哈希表长度为10  
  38. };  
  39.   
  40. HashTable::HashTable()//默认构造函数  
  41. {     
  42.     memset(value, NULL, 10*sizeof(HashNode*));  
  43. }  
  44.   
  45. void HashTable::Create(int *a, int n)  
  46. {  
  47.     cout << "请输入n个元素:" << endl;  
  48.     for (int i=0; i<n; i++)  
  49.     {  
  50.         cin >> a[i];  
  51.         Insert(a[i]);  
  52.     }  
  53. }  
  54.   
  55. bool HashTable::Find(int data)  
  56. {  
  57.     HashNode *pNode = NULL;  
  58.   
  59.     if (value[data%10] == NULL)//该结点不存在,则返回false  
  60.     {         
  61.         return false;  
  62.     }  
  63.   
  64.     pNode = value[data%10];//获取所在位置对应的链表的第一个结点  
  65.     while(pNode ->next != NULL && pNode->data != data)  
  66.     {  
  67.         pNode = pNode->next;  
  68.     }  
  69.   
  70.     if (pNode != NULL)  
  71.     {         
  72.         return true;  
  73.     }  
  74.     else   
  75.     {          
  76.         return false;  
  77.     }  
  78. }  
  79.   
  80. void HashTable::Insert(int data)  
  81. {  
  82.     HashNode *pNode = NULL;  
  83.   
  84.     if (value[data%10] == NULL)//获取所在位置对应的链表为空,则插入  
  85.     {  
  86.         pNode = new HashNode;  
  87.         pNode->data = data;  
  88.         value[data%10] = pNode;  
  89.     }  
  90.     else//所在位置对应的链表不空  
  91.     {  
  92.         if (Find(data))//检查该数值是否已经存在,若存在则返回  
  93.         {  
  94.             return;  
  95.         }  
  96.         else//否则插入链表尾端  
  97.         {  
  98.             pNode = value[data%10];  
  99.             while(pNode->next != NULL)  
  100.             {  
  101.                 pNode = pNode->next;  
  102.             }  
  103.   
  104.             HashNode *newNode = new HashNode(data);               
  105.             pNode->next = newNode;  
  106.         }         
  107.     }  
  108. }  
  109.   
  110. void HashTable::Delete(int data)  
  111. {  
  112.     HashNode *pNode = NULL;//定位到待删除的结点  
  113.     HashNode *pPre = NULL;//定位到待删除结点的前一个结点    
  114.   
  115.     if (!Find(data))  
  116.     {  
  117.         cout << "该数值的结点不存在!" << endl;  
  118.     }  
  119.     else  
  120.     {  
  121.         pNode = value[data%10];//初始值为所在位置对应的链表的第一个结点          
  122.         if(pNode->data == data)//头结点即为待删除的结点  
  123.         {  
  124.             value[data%10] = pNode->next;  
  125.             cout << data << "删除成功!" << endl;  
  126.         }  
  127.         else//否则指针后移,找到待删除的结点  
  128.         {     
  129.             pPre = pNode;  
  130.             while(pNode->next != NULL && pNode->next->data != data)  
  131.             {  
  132.                 pPre = pNode;  
  133.                 pNode = pNode->next;               
  134.             }  
  135.             pPre->next = pNode->next;  
  136.             delete pNode;  
  137.             pNode = NULL;  
  138.             cout << data << "删除成功!" << endl;  
  139.         }     
  140.     }     
  141. }  
  142.   
  143. int _tmain(int argc, _TCHAR* argv[])  
  144. {     
  145.     int n = 0;  
  146.     cout << "请输入哈希表元素的个数:";  
  147.     cin >> n;  
  148.       
  149.     HashTable *ht = new HashTable;  
  150.     ht->Create(a, n);      
  151.   
  152.     cout << ht->Find(9) << endl;  
  153.     cout << ht->Find(3) << endl;  
  154.   
  155.     ht->Delete(10);  
  156.     ht->Delete(8);  
  157.   
  158.     cout << ht->Find(8) << endl;  
  159.   
  160.     system("pause");  
  161.     return 0;  
  162. }  

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 支付宝登录失败请稍后再试怎么办 万王之王3d限制注册了怎么办 绑定手机号无法登陆以前微信怎么办 手机号注册了淘宝如果不用了怎么办 淘宝网登陆要手机验证码怎么办 手机清理了微信图片打不开了怎么办 到淘宝网买东西卖家拒绝退货怎么办 淘宝店铺检测出他人认证图片怎么办 文件过大无法复制到u盘怎么办 淘宝账号上不去总说网络不好怎么办 手机上登录微信一直闪退怎么办 京东账号手机号换了登陆不了怎么办 对方账号停止收款我们汇了款怎么办 淘宝店铺严重违规被扣12分怎么办 中国网银登陆不会自动弹出怎么办 高考报考的时候页面无法显示怎么办 如果卖家收到货不退款怎么办 淘宝退货卖家收到货不退款怎么办 手机号码淘宝被注册跟换绑定怎么办 微信发送ppt显示文件太大怎么办 微信手机号丢了微信登不了钱怎么办 新买的号码注册过支付宝怎么办 新买的号码被注册过支付宝怎么办 支付宝同号码注册了新的帐号怎么办 新卖的号码有人注册过支付宝怎么办 我的号码被别人注册了支付宝怎么办 别人用我的号码注册了支付宝怎么办 打开支付宝进入到淘宝的界面怎么办 我的手机号注销了支付宝账号怎么办 微博绑定的支付宝账号注销了怎么办 闲鱼买家申请退款卖家不同意怎么办 微信与手机旧版本不一致怎么办 在应用宝里下载微信老是失败怎么办 使用u盘储存视频显示不兼容怎么办 支付宝下载显示与存在不兼容怎么办 cpu与64位系统不兼容怎么办 微信版本低登录不了怎么办苹果手机 手机版本低登录不了微信怎么办? 进入微信公众号显示登录失败怎么办 安卓系统手机亮度调到最低怎么办 阿里妈妈买家号虚假交易违规怎么办