#include <iostream>
using namespace std;
#define HashTable_Size 100
//用除留余数法求关键字的哈希地址
int Hash(int k,int m)
{
	return k%m;
}
//**********************************************************
//开放地址法——闭哈希表
//**********************************************************
//闭哈希表的类型定义
#define MIN -100000000
typedef struct 
{
	int r[HashTable_Size];
	int length;
}HashTable;
//闭哈希表的初始化
void InitHashTable(HashTable &HT)
{
	int i;
	for(i=0;i<HT.length;i++)
		HT.r[i]=MIN;
}
//闭哈希表的插入——采用线性探测法处理冲突
void InsertHashTable_Close(HashTable &HT,int x)
{
	int i,j,m;
	m=HT.length;
	i=Hash(x,m);
	if(HT.r[i]==MIN)
		HT.r[i]=x;
	else
	{
		j=(i+1)%m;
		while(HT.r[j]!=MIN && j!=i)//当查找到的哈希地址为非空,即产生冲突,并且j还没有循环一圈时,执行循环
			j=(j+1)%m;
		if(HT.r[j]==MIN)//如果找到了空的位置,则执行插入
			HT.r[j]=x;
		else//如果j循环一圈还没找到空的位置插入,则表示哈希表已经满了
			cout<<"OVER FLOW!";
	}
}
//闭哈希表的建立
void CreateHashTable_Close(HashTable &HT)
{
	int i;
	int n;//表中元素的个数
	int h[100];
	cin>>n>>HT.length;//n是元素个数,和表长不是一个概念
	InitHashTable(HT);
	for(i=0;i<n;i++)
		cin>>h[i];//先把要输入的元素存储到一个数组中
	for(i=0;i<n;i++)
		InsertHashTable_Close(HT,h[i]);//用插入操作建立哈希表	
}
//闭哈希表的查找
int HashSearch_Close(HashTable &HT,int x)
{
	int i,j,m;
	m=HT.length;
	i=Hash(x,m);
	if(HT.r[i]==x)
		return i;//一次比较成功,找到了该记录,返回记录地址,查找结束
	j=(i+1)%m;//若第一次查找有冲突,向后查找
	while(HT.r[j]!=MIN && j!=i)
	{//当查找到的哈希地址为非空,并且j还没有循环一圈时,执行循环
		if(HT.r[j]==x)
			return j;
		j=(j+1)%m;
	}
	return -1;//没有查找到记录
}
//*****************************************************************************
//链地址法(拉链法)——开哈希表
/*基本思想是将所有哈希地址相同的记录存储到一个单链表中,在哈希表中存储的是所有
哈希地址相同的记录的头指针*/
//*****************************************************************************
//开哈希表的类型定义
typedef struct HTNode
{
	int key;
	struct HTNode *next;
}HTNode;
typedef struct HashList
{
	HTNode *List[HashTable_Size];//该数组存放的是指针,即为哈希表
	int length;
}HashList;
//开哈希表的初始化
void InitHashList(HashList &HL)
{
	int i;
	for(i=0;i<HL.length;i++)
		HL.List[i]=NULL;
}
//开哈希表的插入
void InsertHashList_Open(HashList &HL,int x)
{
	int i,m;
	HTNode *p,*q;
	m=HL.length;
	i=Hash(x,m);
	p=HL.List[i];//找到x在哈希表中所在的单链表,即和x相对应的头指针
	if(p==NULL)
	{//即和该记录对应的哈希地址为空,即目前还没有还该记录冲突的记录,则插入该元素
		q=new HTNode;
		q->key=x;
		q->next=HL.List[i];
		HL.List[i]=q;//这里不能用尾插法,得用头插法
	}
	else
	{//即已有相同的哈希地址的记录
		while(p!=NULL)
			p=p->next;
		q=new HTNode;
		q->key=x;
		q->next=HL.List[i];
		HL.List[i]=q;
	}
}
//开哈希表的建立
void CreateHashList_Open(HashList &HL)
{
	int i;
	int n;//表中元素的个数
	int h[100];
	cin>>n>>HL.length;
	InitHashList(HL);
	for(i=0;i<n;i++)
		cin>>h[i];
	for(i=0;i<n;i++)
		InsertHashList_Open(HL,h[i]);
}
//开哈希表的查找
HTNode *HashSearch_Open(HashList &HL,int x)
{
	int i,m;
	HTNode *p;
	m=HL.length;
	i=Hash(x,m);
	p=HL.List[i];//找到x在哈希表中所在的单链表,即和x相对应的头指针
	if(p==NULL)
		return NULL;
	else
	{//即已有相同的哈希地址的记录
		while(p!=NULL && p->key!=x)
			p=p->next;//当P为非空并且和x不相等
		if(p->key==x)
			return p;
		return NULL;
	}
}
void main()
{
	//freopen("in.txt","r",stdin);
	
	int i;
	HashTable HT;
	CreateHashTable_Close(HT);
	i=HashSearch_Close(HT,47);
	if(i!=-1)
		cout<<HT.r[i]<<endl;
	else
		cout<<"Not Found!"<<endl;
	
	/*HTNode *p;
	HashList HL;
	CreateHashList_Open(HL);
	p=HashSearch_Open(HL,3);
	if(p==NULL)
		cout<<"Not Found!"<<endl;
	else
		cout<<p->key<<endl;*/
}

我写的和书上的不一样,因为我不知道这个哈希表具体是怎么用的,我根据我自己理解的哈希表的用法,去设计写这个哈希表的,虽然和书上的不一样,但是根本的思想还是一样的,现在我又掌握了哈希表的写法,嘿嘿,下一步应该是排序了,数据结构已经结课了,我要抓紧时间写把代码写一下!

现在我感觉轻松了好多,下午把线性代数考了,我感觉轻松极了,因为我心中的一块大石头落地了,接下来到就都小菜了,还有就是我可以有更多的精力来写程序了,而不是整天钻在抽象、枯燥的数学里面了,哈哈,努力啊!