转自:http://blog.csdn.net/htyurencaotang/article/details/7881399
相关定义:根据散列函数H(key)和处理冲突的方法将一组关键字映象到一个有限的连续的地址集(区间)上,并以关键字在地址集中的“象” 作为记录在表中的存储位置,这种表便称为散列表(或称哈希表),这一映象过程称为散列造表或散列,所得的存储位置称散列地址。
相关定义:根据散列函数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. 建立一个公共溢出区
代码:
- // HashTable.cpp : 定义控制台应用程序的入口点。
- //哈希表的实现
- //哈希函数采用除留余数法构造
- //使用链地址法解决冲突
- #include "stdafx.h"
- #include <iostream>
- using namespace std;
- const int MAXSIZE = 100;
- int a[MAXSIZE];
- //哈希表的结点类型
- class HashNode
- {
- public:
- HashNode():next(NULL){};//默认构造函数
- HashNode(int item):data(item), next(NULL){};//一般构造函数
- private:
- int data;
- HashNode *next;
- friend class HashTable;
- };
- //哈希表类型
- class HashTable
- {
- public:
- HashTable();
- void Create(int *a, int n);//创建哈希表
- bool Find(int data);//查找
- void Insert(int data);//插入
- void Delete(int data);//删除
- private:
- HashNode *value[10];//哈希表长度为10
- };
- HashTable::HashTable()//默认构造函数
- {
- memset(value, NULL, 10*sizeof(HashNode*));
- }
- void HashTable::Create(int *a, int n)
- {
- cout << "请输入n个元素:" << endl;
- for (int i=0; i<n; i++)
- {
- cin >> a[i];
- Insert(a[i]);
- }
- }
- bool HashTable::Find(int data)
- {
- HashNode *pNode = NULL;
- if (value[data%10] == NULL)//该结点不存在,则返回false
- {
- return false;
- }
- pNode = value[data%10];//获取所在位置对应的链表的第一个结点
- while(pNode ->next != NULL && pNode->data != data)
- {
- pNode = pNode->next;
- }
- if (pNode != NULL)
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- void HashTable::Insert(int data)
- {
- HashNode *pNode = NULL;
- if (value[data%10] == NULL)//获取所在位置对应的链表为空,则插入
- {
- pNode = new HashNode;
- pNode->data = data;
- value[data%10] = pNode;
- }
- else//所在位置对应的链表不空
- {
- if (Find(data))//检查该数值是否已经存在,若存在则返回
- {
- return;
- }
- else//否则插入链表尾端
- {
- pNode = value[data%10];
- while(pNode->next != NULL)
- {
- pNode = pNode->next;
- }
- HashNode *newNode = new HashNode(data);
- pNode->next = newNode;
- }
- }
- }
- void HashTable::Delete(int data)
- {
- HashNode *pNode = NULL;//定位到待删除的结点
- HashNode *pPre = NULL;//定位到待删除结点的前一个结点
- if (!Find(data))
- {
- cout << "该数值的结点不存在!" << endl;
- }
- else
- {
- pNode = value[data%10];//初始值为所在位置对应的链表的第一个结点
- if(pNode->data == data)//头结点即为待删除的结点
- {
- value[data%10] = pNode->next;
- cout << data << "删除成功!" << endl;
- }
- else//否则指针后移,找到待删除的结点
- {
- pPre = pNode;
- while(pNode->next != NULL && pNode->next->data != data)
- {
- pPre = pNode;
- pNode = pNode->next;
- }
- pPre->next = pNode->next;
- delete pNode;
- pNode = NULL;
- cout << data << "删除成功!" << endl;
- }
- }
- }
- int _tmain(int argc, _TCHAR* argv[])
- {
- int n = 0;
- cout << "请输入哈希表元素的个数:";
- cin >> n;
- HashTable *ht = new HashTable;
- ht->Create(a, n);
- cout << ht->Find(9) << endl;
- cout << ht->Find(3) << endl;
- ht->Delete(10);
- ht->Delete(8);
- cout << ht->Find(8) << endl;
- system("pause");
- return 0;
- }