查找算法06-哈希查找


知识分享: 热门博客

6、哈希查找

(1)概述

在哈希表中,若出现key1≠key2,而f(key1)=f(key2),则这种现象称为地址冲突key1和key2对哈希函数f来说是同义词。根据设定的哈希函数f=H(key)和处理冲突的方法,将一组关键字映射到一个有限的连续的地址集上,并以关键字在地址集中的“象作为记录中的存储位置,这一映射过程为构造哈希表(散列表)。
  好的哈希函数应该使一组关键字的哈希地址均匀分布在整个哈希表中,从而减少冲突,常用的构造哈希函数的方法有

  • 直接地址法(直接寻址法):
    ① 公式:f(key)=a*key+b (a,b都是常数)。
    ②适合查找表较小且连续的情况。
    ③优点:简单、均匀,不会产生冲突。
    ④缺点:需要知道关键字的分布,现实中不常用。

  • 数字分析法:
    ①方法:抽取关键字中的一部分来计算存储位置。
    ②适用于关键词较长的情况。

  • 平方取中法:
    ① 方法:将关键字先平方,然后截取中间x位作为存储位置。
    ②适合用于不知道关键词分布,且位数不长的情况。

  • 除留余数法:
    ① 方法:f(key)=key mod p (p<=m),m是散列表表长。
    ②p取小于等于m的最小质数或者不包含小于20质因子的合数,以减少冲突的情况。

  • 折叠法:
    ① 方法:将关键字拆分成若干部分后累加起来,根据散列表表长取总和的后若干位作为存储位置。
    ②适用于不知道关键字分布,且位数较长的情况。

  • 随机数法:
    ① 方法:f(key)=random(key)。
    ②注意random的随机种子需要是固定的,以便查询的时候能够根据key重新找到存储位置。
    ③适用于关键字长度不等的情况。

(2)常用冲突处理方法

采用均匀的哈希函数可以减少地址冲突,但是不能避免冲突,因此,必须有良好的法来处理冲突,通常,处理地址冲突的方法有以下两种:

  • 开放地址法
  • 拉链法(链地址法)
  • 再散列函数法
  • 公共溢出区法

6-1实现代码

  • Java实现方式一:
	public static int searchHash(int[] hash,int hashLength,int key) {
		int index=key%hashLength;
		while(hash[index]!=0&&hash[index]!=key) {
			index=(++index)%hashLength;
		}
		if(hash[index]==0)
			return -1;
		return index;
	}
	public static void insertHash(int[] hash,int data) { 
		int index=data%hash.length;
		while(hash[index]!=0) {
			index+=(++index)%hash.length;
		}
		hash[index]=data;
	}

6-2测试

		int[] array= {1,2,3,4,5,6,7,8,9,10};
		int hashLength=20;  //设置的值应该大于数组中元素的个数
		int[] hash=new int[hashLength];
		for(int i=0;i<array.length;i++) {
			insertHash(hash,array[i]);
		}
		for(int i=0;i<50;i++) {
			int index=searchHash(hash,hashLength,i);
			if(index!=-1) {
				System.out.println("数组中有"+i+"元素");
			}
		}

输出结果:
在这里插入图片描述

6-3方法解析

  • 方法中的hashLength的长度不能小于原数组的长度,否则会出现死循环。其中searchHash函数返回的是数据在hash数组中存放的下标,不是原数组的下标。
  • 当然上面代码也有缺点,就是原数组中不能包含0,因为hash数组没赋初值,默认值也是0,所以解决方式就是给hash数组中每一个元素都赋一个原数组中不可能出现的初值。

上篇博文:查找算法05-分块查找

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
哈希查找算法是一种高效的查找算法,它通过将关键字映射到哈希表中的位置来实现查找。下面是一个简单的Python实现: ```python # 定义哈希表类 class HashTable: def __init__(self): self.size = 11 self.slots = [None] * self.size self.data = [None] * self.size # 哈希函数 def hashfunction(self, key, size): return key % size # 插入数据 def put(self, key, data): hashvalue = self.hashfunction(key, len(self.slots)) if self.slots[hashvalue] == None: self.slots[hashvalue] = key self.data[hashvalue] = data else: if self.slots[hashvalue] == key: self.data[hashvalue] = data # 更新数据 else: nextslot = self.rehash(hashvalue, len(self.slots)) while self.slots[nextslot] != None and self.slots[nextslot] != key: nextslot = self.rehash(nextslot, len(self.slots)) if self.slots[nextslot] == None: self.slots[nextslot] = key self.data[nextslot] = data else: self.data[nextslot] = data # 更新数据 # 查找数据 def get(self, key): startslot = self.hashfunction(key, len(self.slots)) data = None stop = False found = False position = startslot while self.slots[position] != None and not found and not stop: if self.slots[position] == key: found = True data = self.data[position] else: position = self.rehash(position, len(self.slots)) if position == startslot: stop = True return data # 重新哈希 def rehash(self, oldhash, size): return (oldhash + 1) % size ``` 上述代码中,我们定义了一个哈希表类`HashTable`,并实现了哈希函数`hashfunction`、插入数据方法`put`、查找数据方法`get`和重新哈希方法`rehash`。我们可以通过以下代码来测试这个哈希表类: ```python H = HashTable() H.put(54, "cat") H.put(26, "dog") H.put(93, "lion") H.put(17, "tiger") H.put(77, "bird") H.put(31, "cow") H.put(44, "goat") H.put(55, "pig") H.put(20, "chicken") print(H.slots) print(H.data) print(H.get(20)) ``` 输出结果为: ``` [77, 44, 55, 20, 26, 93, None, None, 17, None, 31] ['bird', 'goat', 'pig', 'chicken', 'dog', 'lion', None, None, 'tiger', None, 'cow'] chicken ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值