哈希表的查找及分析

查找

哈希表的查找过程和造表过程基本一致:根据给定的关键字key,用该表对应的哈希函数求得哈希地址,判断该地址的记录与key是否相同。若不相同,则用此哈希表处理冲突的方法来找到下一个哈希地址,直到哈希地的记录为空或者找到与key值相同的记录为止。

在这里插入图片描述

以开放定址等方法处理冲突的哈希表的查找算法

//开放定址哈希表的存储结构
int  hashsize[]={997,...};      //哈希表容量递增表,素数序列 
typedef struct Elemtype         //数据元素类型定义 
{
	KeyType key;  //关键字 
	int a;        //其他数据 
	int b;
};

typedef struct    
{
	Elemtype *elem;             //数据元素存储基址,动态分配数组 
	int  count;                 //当前数据元素个数 
	int  sizeindex;             //hashsize[sizeindex]为当前表的容量 
 }HashTable;
 
#define SUCCESS 1;
#define UNSUCCESS 0;
#define DUPLICATE -1;
#define NULLKEY 0;  //定义key为0时为空
 
void collision(int &p,int &c)  
//开放定址法求下一个哈希地址,以线性探测再散列为例 
{
	p=(++p) % 13;       //处理冲突方法 
}

int EQ(KeyType k1,KeyType k2)   //判等函数 
{
	if(k1==k2)
	 return 1;
	else return 0;
}

Status SearchHash(HashTable h,KeyType k,int &p,int &c){
	/*在开放定址哈希表h中查找关键字为k的元素,若查找成功,,以p指示待查数据在表中的位置,
	并返回success;否则,以p指示插入位置,并返回unsuccess;c用来记录冲突次数,供建表时参考
	*/
	p=Hash(k);        //求k的哈希地址
	
	while(h.elem[p].key!=NULLKEY && !EQ(k,h.elem[p].key)) 
	//哈希地址p有记录且k与该地址的key不相等
	  collision(p,++c);                 //求下一个哈希地址,比如此处用开放定址法
	
	if(EQ(k,h.elem[p].key))           //k与哈希地址p的key相等,查找成功
	  return SUCCESS;
	else return UNSUCCESS;            //查找不成功,此时地址p的记录为空,作为插入位置 
	
}//Searchhash

开放定址哈希表的插入操作

Status InsertHash(HashTable &h,Elemtype e)
//查找不成功时插入元素e到哈希表h中,并返回;若冲突次数过多,则重新建表 
{
	if(SearchHash( h, e.key, p, c) )    //哈希表中已有该元素,无需插入 
	  return DUPLICATE;
	else if(c < hashsize[h.sizeindex]/2)   //冲突次数c未达到上限,c的阈值可调 
	{
		h.elem[p]=e;    //插入元素e 
		++h.count;      //元素个数增加 
        return;
	}
	
	else {
		RecreateHashTable(h);    //重新建表 
		return SUCCESS;
	} 
 } 

分析

虽然哈希表在关键字和记录位置之间建立了直接映像,但由于冲突的产生,使得哈希表查找过程仍是一个给定制和关键字进行比较的过程。因此,仍需要以 平均查找长度 作为衡量哈希表查找效率的量度。

一般来说,线性探测再散列在处理冲突过程中易产生记录的二次聚集,使得哈希函数不相同的记录产生新的冲突;而链地址法处理冲突不会发生类似的情况,因为哈希地址记录在不同的链表中。而在处理冲突方法相同的哈希表中,其平均查找长度依赖于哈希表的 装填因子 ,其定义为

  装填因子 = 表中填入的记录数 / 哈希表长度

装填因子表示哈希表的装满程度。可以直观看出,装填因子越小,发生冲突的可能性越小。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

晚风也很浪漫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值