【西南交大数据结构实验】链地址法哈希表的建立与基本操作

//水平有限,酌情参考

#include<iostream>
using namespace std;
#define M 5 //哈希表长度
typedef struct linklist { //链表
	int e;   //值域
	struct linklist* next;  //指针域
}link;

//把哈希表和其容量标识设置为全局变量
link* Hash[M-1];
int space = 2*M;//链地址法,要求哈希表允许的关键字最大数目为2m

int FindLoc(int key) //求地址
{
	return key % M;//取余
}
void InsertNode(int loc,int data) //向链表插入新结点
{
	if(space==0){
		cout << "----插入失败,哈希表容量已满" << endl;
		return;
	}
	link* p = Hash[loc];     
	if (Hash[loc] == NULL) { //如果该地址还没有元素存储
		Hash[loc] = new link;
		Hash[loc]->e = data;
		Hash[loc]->next = NULL;
		space--;  //容量减少
	}
	else{  
		while (p != NULL) {  //此时该地址已有元素存储。先遍历链表查找是否有相同元素存在
			if (p->e == data) {
				cout << "----插入失败,该地址存在相同元素" << endl;
				return;
			}
			p = p->next;
		}//若没有相同元素存在,则用头插法插入新结点
		link* ph = Hash[loc];		
		Hash[loc] = new link;
		Hash[loc]->e = data;
		Hash[loc]->next = ph;
		space--;
	}
	cout << "----插入后,该地址储存的元素:" ;
	p = Hash[loc];
	while (p != NULL) {
		cout << p->e<<" ";
		p = p->next;
	}
	cout << endl;
}
void insert() {
	cout << "Insert" << endl;
	cout << "----请输入元素,输入-1停止输入" << endl;
	int e, loc;
	while (cin >> e && e != -1) {
		loc = FindLoc(e);
		InsertNode(loc, e); //把元素和得到的地址传入插入结点函数
	}
}
void DelNode(int loc, int data) {
	link* p1= Hash[loc];
	link* p2 = p1;  //主从指针
	if (p1 == NULL) { cout << "----删除失败,该地址未存储元素"<<endl; return; }
	while (p1!= NULL&&(p1->e!=data)) {    //遍历寻找该元素
		p2 = p1;   //让p2指向p1的前驱结点
		p1 = p1->next;
	}
	if(p1==NULL){ cout << "----删除失败,未找到该元素"<<endl; return; }
	//此时p1已指向元素的结点,但先要判断该元素是否位于头结点
	if (p1 == p2)  //位于头结点
		Hash[loc] = p1->next;   //直接让头指针指向next
	else           //不位于头结点
		p2->next = p1->next;
	//free(p1);
	space++;    
	cout << "----删除后,该地址储存的元素:";
	p1 = Hash[loc];
	while (p1 != NULL) {
		cout << p1->e << " ";
		p1 = p1->next;
	}
	cout << endl;
}
void del() {
	cout << "Del" << endl;
	cout << "----请输入元素,输入-1停止输入" << endl;
	int e, loc;
	while (cin >> e && e != -1) {
		loc = FindLoc(e);
		DelNode(loc, e);
	}
}
void SearchNode(int loc, int data) {
	link* p = Hash[loc];
	if (p == NULL) {
		cout << "----不存在该元素" << endl;
		return;
	}
	while (p != NULL ) {
		if (p->e == data) {
			cout << "----查找成功,该元素处于地址" << loc << endl;
			return;
		}
		p = p->next;
	}
		cout << "----不存在该元素" << endl;
		return;
}
void search() {
	cout << "Search" << endl;
	cout << "请输入元素,输入-1停止输入" << endl;
	int e, loc;
	while (cin >> e && e != -1) {
		loc = FindLoc(e);
		SearchNode(loc, e);
	}
}

void menu()
{
	cout << "---------------------" << endl;
	cout << "   1.插入关键字" << endl;
	cout << "   2.删除关键字" << endl;
	cout << "   3.查找关键字" << endl;
	cout << "   4.结束程序" << endl;
	cout << "---------------------" << endl;
	int i;
	while (cin>>i)
	{
		switch (i)
		{
		case 1:
			insert();
			menu();
			break;
		case 2:
			del();
			menu();
			break;
		case 3:
			search();
			menu();
			break;
		case 4:
			exit(0);
			menu();
			break;
		default:
			cout << "错误的输入" << endl;
			menu();
			break;
		}
	}
}
int main()
{
	memset(Hash, NULL, sizeof(Hash));//将头指针全初始化为NULL
	menu();
}

编写控制台应用程序,提供以下菜单项:

1.插入关键字

2.删除关键字

3.查找关键字

4.结束程序

其中,“插入关键字”是指从键盘输入一个关键字,将关键字插入哈希表中,若插入的关键字已存储于哈希表中,则插入失败,显示提示信息;若插入关键字数目已超过哈希表设计容量,则插入失败,显示提示信息;其它情况则插入成功,显示提示信息。程序初始运行时,哈希表为空,通过插入多个关键字建立哈希表。

“删除关键字”是指从键盘输入一个关键字,若在哈希表中查找成功,则将关键字从哈希表中删除;若查找失败,显示提示信息。

“查找关键字”是指从键盘输入一个关键字,在哈希表中查找,显示查找成功与失败的提示信息。

已知哈希函数H(K)=K mod m,其中m为哈希表长度(程序中m应不小于10)。可选择用二次探测再散列或链地址法解决冲突。若选用二次探测再散列,装填因子设为0.8;若选用链地址法,要求哈希表允许的关键字最大数目为2m。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值