散列查找验证性程序(闭散列)

问题描述

请设计一个整型闭散列表,散列函数为除留余数法,处理冲突时的探查方法为线性探查法,其中散列表的长度、除留余数法的模和关键码的个数由键盘输入,再根据输入由键盘输入所有的关键码。分别对三个待查值在散列表中进行查找,如果找到了输出位置,如果没找到,输出“none”并把该待查值插入到散列表中,如果散列表满输出“full”。
输入描述
各个命令以及相关数据的输入格式如下:
第一行输入闭散列表的长度n
第二行输入除留余数法的模m
第三行输入关键码的个数num
第四行输入num个整型关键码
第五行输入三个待查整型值
输出描述
输出三行,每行格式为:
如果找到待查值,输出找到待查值的位置,如果没找到,输出“none”,并将待查值插入到散列表中,如果散列表满,则输出“full”,每个待查值占一行
输入样例
11 11 9
2 6 8 9 13 17 10 12 20
3 7 11
输出样例
none
none
full

问题分析

首先要清楚什么是散列查找,散列查找所用的储存形式是线性的,同样是用数组储存,但是与折半查找和顺序查找不同的是,散列查找是通过唯一指定的地址进行查找,比如 关键码是8,散列函数是f(x) = x%10,这样的话,这个关键码储存的位置就是数组中小标为8的地址,但是如果还存在除十取余等于8的关键码,那么他的储存位置就是上一个余数是8的关键码逻辑地址加一的地方,当然,如果那个位置已经有关键码存在了,那么就接着向下找下一个没有存关键码的地址。这样的话就减少查找的次数,提高了效率。

代码

#include<iostream>
const int MaxSize = 100;
using namespace std;

class HashTabel
{
public:
	HashTabel(int, int, int, int*);
	void Search(int);									//查找函数 

private:
	int H(int);											//散列函数 
	int ht[MaxSize];									//用来储存关键码 
	int mod;									
	int length;
};

HashTabel::HashTabel(int m, int num, int len, int *a)
{
	int k, j;

	mod = m;
	length = len;

	for (int i = 0; i < length; i++)					//将关键码初始化为0 
	{
		ht[i] = 0;
	}

	for (int i = 0; i < num; i++)
	{
		k = H(a[i]);									//通过散列函数来计算关键码应该储存的位置 
		
		if (!ht[k])										//判断此位置是否已经存在关键码,如果不存在,则将关键码储存在这个位置 
		{
			ht[k] = a[i];
		}
		else											//否则逻辑地址  加一 
		{
			j = (k + 1) % length;
			while (ht[j] && j != k) 
			{
				j = (j + 1) % length;
			}

			if (!ht[j])									//重新找到储存的地址之后,将关键码储存 
			{
				ht[j] = a[i];
			}
		}
	}
}

int HashTabel::H(int k)
{
	return k % mod;										//散列函数 
}

void HashTabel::Search(int k)
{
	int j = H(k);

	if (ht[j] == k)										//如果查找到,直接输出关键码 
	{
		cout << j << endl;
	}
	else if (!ht[j])									//如果关键码应该储存的位置没有此关键码,说明在已有数据中没有此关机那么 
	{
        ht[j] = k;
		cout << "none" << endl;
	}
	else												//如果前面两种情况都不符合,逻辑地址加一,继续查找 
	{
		j = (j + 1) % length;
		while (ht[j] && j != H(k))
		{
			if (ht[j] == k)
			{
				cout << j << endl;
				return ;
			}
			else
			{
				j = (j + 1) % length;
			}
		}
		
		if (!ht[j])
		{
			ht[j] = k;
			cout << "none" << endl;
		}
		else
		{
			cout << "full" << endl;
		}
	}
}

int main()
{
	int n, mod, num, x, *a;

	cin >> n >> mod >> num;

	a = new int[n];

	for (int i = 0; i < num; i++)
	{
		cin >> a[i];
	}

	HashTabel h(mod, num, n, a);
	
	for (int i = 0; i < 3; i++)
	{
		cin >> x;
		h.Search(x);
	}

	delete a;
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值