代码如下:
#include "stdafx.h"
#include<iostream>
using namespace std;
const int INF=65535;
struct HashTable
{
int *elem;
int count;//存储HashTable中元素的个数
}H;
void InitHashTable(HashTable &H)//要动态数组存储元素
{
cout<<"请输入元素个数,以enter结束"<<endl;
cin>>H.count;
cout<<'\n';
H.elem=new int[H.count];
for(int i=0;i<H.count;i++)
H.elem[i]=INF;
}
void InsertHash(HashTable &H,int key)
{
int addr=key % H.count;//获取地址
while(H.elem[addr]!=INF)//判断是否冲突,即里面看有没有值
addr=(addr+1) % H.count;
H.elem[addr]=key;//找到空的就插入
}
void SearchHash(const HashTable &H,int key)
{
int addr=key % H.count;
int temp=addr;
while(H.elem[addr]!=key)
{
addr=(addr+1) % H.count;
if(addr==temp)//说明回到原点
{
cout<<"找不到这个关键字"<<endl;
return;
}
}
cout<<"关键字的位置是"<<addr<<endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
InitHashTable(H);
int key;
cout<<"请输入"<<H.count<<"个Hash元素"<<endl;
for(int i=0;i<H.count;i++)
{
cin>>key;
InsertHash(H,key);
}
while(getchar()!='a')
{
cout<<"请输入要查找的Hash元素值"<<endl;
cin>>key;
SearchHash(H,key);
}
return 0;
}
输出结果是:
请输入元素个数,以enter结束
5
请输入5个Hash元素
1 2 4 20 84
请输入要查找的Hash元素值
1
关键字的位置是1
请输入要查找的Hash元素值
2
关键字的位置是2
请输入要查找的Hash元素值
4
关键字的位置是4
请输入要查找的Hash元素值
20
关键字的位置是0
请输入要查找的Hash元素值
84
关键字的位置是3
请输入要查找的Hash元素值
插入思想:
(1)相当于要将几个信息存在几块内存中,信息包括(学号,姓名)等。比如说这里有5个,那么有一个数组,或者说一个类型数组,利用Hash函数
求的地址。将其存储在这个数组类型中。
(2)当有冲突时,就用开放定址进行探测,获得其不冲突的地址,然后进行储存。
查找思想:
(1)当插入完毕之后,就可以根据学号,利用Hash函数进行查找了,同时,还可以找出对应的姓名。
(2)所以说还是有一定的实用价值的。
注,冲突的解决方法还有:
(1)二次探测法,其中d=1^2, -1^2 , 2^2 ,-2 ^2 ... ...q^2 (q<m/2) 。
(2)随机探测法,d为随机数。
(3)再散列函数法 ,取另外一个函数
(4)链地址法,将冲突以链表形式存储起来,散列表只存储头指针
(5)公共溢出区法,将冲突的放到溢出表中,查找时可以在里面进行顺序查找。
hash函数的构造方法:
直接定址法
数字分析法
随机数法
除留余数法
平方取中法
折叠法
总结:散列表对于那种查找性能要求高,记录之间无要求的数据有非常好的适用性。