首先制作一个hash表是有很多种方式 只要是根据关键码值(Key value)而直接进行访问的数据结构。也就是说通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
映射函数的几种类型
1. 直接寻址法:
2. 数字分析法:
3. 平方取中法:
4. 折叠法:
5. 随机数法:
6. 除留余数法:
这里要说明的是映射函数不是唯一的,你完全可以折叠法之后再除留取余,关键是要使每个value最后计算得到的数组下标
能够减少冲突 使得元素的位置尽量分布均匀的那种即可
当然每一种映射都会存在冲突 对于冲突 处理冲突的办法有
1是线性探测的开型寻址
2是再散列的开型寻址
3是链式散列
最后通过不同装载因子的情况下计算成功查找时平均检验的表元素的个数 得出链式散列的个数在不同的装载因子下都是最少的如附件图:
所以我们在这里选取链式散列来解决冲突
采用HashMap中已经定义好的映射函数经由hashcode()得到hashcode值 再调用hash()函数得到hash值最后与数组长度-1取&得到数组下标
然后还要确定的元素有初始数组大小 装载因子 (HashMap中已经定义好的分别为16的0.75)
而要明确的是α越大,填入表中的元素较多,产生冲突的可能性就越大;α越小,填入表中的元素较少,产生冲突的可能性就越小
而容量必须是2的幂 可以保证length-1的二进制位上全是1 最后取&之后得到的数 比较均衡 减少冲突 节约数组空间
然后针对我们要完成的这个myhash表的功能进行分析
我们所要完成的这个myhash是对两个数据进行操作分别为key/value 这里的key是比较关键的一个参数 我们所有的操作都要根据它来完成 而
value值只负责存放到myhash中。
这里要完成的主要功能有
插入以key和value的值-------------------------put<object key,object vlaue>
用key为关键字来查询value的值-----------------public object get(object key)
删除key和value的值--------------------------public object remove(object key)
是否包含关键字key和value---------------public boolean containkey(object key)/(object value)
然后为完成功能必须要涉及的重要类有:
第一在put进去的时候数组的可能超过最大存储量(loadfactor*capcity) 这时需要resize(2*table.length)
第二仅仅扩容是不可以的,因为数组长度改变后,由hash值和length-1得到index会改变 所以放进去和取得的数组地址计算出来就有差异
所以在这里需要更新数组元素 updata(chatinTable[] newTable)
最后提一点完成hash表最主要的代码
第一部分重要代码
int hash = (key == null) ? 0 : hash(key.hashCode());
int index = (hash == 0) ? 0 : indexFor(hash, table.length);
for (chainTable<K, V> c = table[index]; c != null; c = c.next) {
if (c.hash == hash || (key != null && key.equals(c.key))) {
····
}
}
不管是在插入 查询还是 删除中这段代码都是必须的 因为你必须要查到key所在的数组中的位置,put要考虑这个位置是否存在有key这个关键字 再考虑是替换 还是直接插入 查询是不仅要找到再数组中的位置 还要找到它再链表中的位置 删除亦是。
第二部分重要代码
for (int i = 0; i <oldTable.length; i++) {
chainTable<K, V> c = oldTable[i];
if (c != null) {
oldTable[i] = null;
do {
int index = indexFor(c.hash, newCapacity);
chainTable<K, V> next = c.next;// 将c后面的节点保存
c.next = newTable[index];// 将数组整条链挂在c的后面
newTable[index] = c;// 将以c节点为头得链放在数组中
c = next;// 将c后面的节点赋给c
} while (c != null);
}
}
这部分代码是将旧表中的节点移到新表中 涉及到数据结构的内容
思考:数组下标相同的链表节点 的hash值肯定是一致的 所以在新数组中肯定也是在同一位置 所以是否可以降整条链直接作为数组元素插入而不
需要一个节点一个节点的链上去
有待验证
最后测试
结果:进行5次测试 前两次和系统的HashMap速度一致 后两次我的略快2秒 最后一次系统快1秒
原因有待考察
- 大小: 9.6 KB
分享到:
相关推荐
《MyHash工具详解——深入理解哈希算法与其实现》 在信息技术领域,哈希算法是一种重要的数据处理手段,广泛应用于信息安全、数据存储、身份验证等多个方面。MyHash-master.zip是一个包含MyHash项目的压缩包,它为...
### 哈希表在C++中的实现 #### 概述 本文介绍了一个使用C++实现的哈希表类,该类使用了模板技术来增强其通用性,并且使用了除留余数法作为散列函数的基础算法。该类不仅支持基本的操作如插入、删除、查找,还提供了...
在给定的描述中,我们看到一个简单的哈希表类`MyHash`的实现,该类允许用户通过字符串键来存取对象。下面我们将详细讨论这个实现方法。 首先,哈希表的核心在于它能够将任意键映射到一个数组的索引,使得查找和插入...
"redis 对hash设置expires"这个主题涉及到Redis中的一个关键特性,即如何为哈希(Hash)数据类型设置过期时间(expires),这使得存储在Redis中的数据能够自动删除,从而实现内存管理。现在我们将深入探讨这个知识点...
本文将详细讲解如何使用C#语言来实现对Redis数据库的访问,以便充分利用其高效特性来提升应用性能。 首先,要实现C#访问Redis,我们需要一个客户端库。StackExchange.Redis是.NET开发者广泛使用的官方推荐库,它...
接下来,实现MyHash的基本操作,包括创建一个固定大小的数组,将数组中的每个元素作为头节点存储键值对,存储键值对时计算哈希码,将哈希码与数组做某种运算,得到该数在数组中的哪一个位置下的链表中。取数时计算该...
哈希表是一种数据结构,它使用哈希函数来存储数据,能够实现平均时间复杂度为O(1)的查找和插入操作。 首先,`hash.h`文件很可能是包含哈希类定义的头文件。在C++中,类定义通常会声明类的成员变量、构造函数、析构...
Hash散列是一种在计算机科学中广泛使用的数据结构和算法,...在给定的文件"MyHash"中,可能包含了这两种方法的具体实现代码,可供学习和参考。通过分析和比较这两种方法,我们可以更好地理解Hash散列的原理和优化策略。
3. 动态类绑定:使用Vue的v-bind指令实现动态绑定class,当某个选项卡的href属性匹配当前的myhash变量时,相应的a标签会被赋予一个类名为“active”的样式类。 4. CSS样式:定义相应的CSS样式,通常“active”类...
在程序中我们对关键字key应用散列函数H(key)来判断关键字key是否在散列表中,...程序的具体实现如下:本程序是用模板类myhash来实现,包括protected和public属性成员。其中protected成员有*ht(自定义散列表指针)、*e
Jedis是Java语言实现的Redis客户端库,它提供了一系列方法,方便Java开发者能够操作Redis数据库,执行各种数据库操作。Redis是一种开源的高性能键值存储数据库,广泛应用于缓存、会话管理、消息队列等场景。本文将...
g.drawString("取出的内容:" + myHash.get(m_int1) + "," + myHash.get(m_int2), 100, 120); g.drawString("取出的内容:" + myStack.pop() + "," + myStack.pop(), 100, 140); } catch (Exception e) { g....
**题目1:** 哈希表`MyHash`定义如下: ```java Hashtable MyHash = new Hashtable(); ``` 查看下列语句: ```java MyHash.put("ten", new Integer(10)); MyHash.put("ten", "Hello"); System.out.print(MyHash.size...
在分布式系统设计中,哈希算法是实现数据分布的关键技术之一。在本篇文章中,我们探讨如何使用PHP语言实现一个普通的哈希分布式算法,并通过具体的实例来解释算法的定义与使用技巧。 首先,哈希分布式算法的概念是...
- 哈希操作:可以使用`hset`和`hget`来操作哈希表,例如`jedis.hset("myHash", "field", "value")`和`String fieldValue = jedis.hget("myHash", "field")`。 - 列表操作:`lpush`用于在列表前端添加元素,`rpop`...
在实际应用中,你可能还需要了解如何持久化Redis中的数据,如RDB和AOF两种持久化策略,以及主从复制和哨兵系统以实现高可用性。此外,Redis还提供了事务(Transactions)、发布订阅(Publish/Subscribe)和Lua脚本等...
连接 Redis 服务器可以通过 `redis-cli` 命令实现,默认情况下,它会尝试连接到本地主机上的 Redis 服务器(localhost,端口 6379): ```bash redis-cli ``` 一旦成功连接,你将看到一个类似于这样的提示符: ``` ...
`MyHash.cs` 和 `myvars.cs` 可能包含了自定义的哈希计算和全局变量的实现。 综上所述,"fileman" 是一个利用 C# 的强大功能实现的文件管理工具,它利用正则表达式提供了灵活的文件操作,如批量改名、搜索、计算...
- **主从复制**:支持主从复制,实现数据备份及读写分离。 - **发布/订阅功能**:可用于构建消息队列系统。 #### 二、连接Redis服务器 要开始使用Redis,首先需要连接到Redis服务器。通常可以通过`redis-cli`工具...