`
- 浏览:
4460 次
- 性别:
-
前段时间因为自己的事情比较多,技术这块有些懈怠了,很多东西学得不扎实,常常产生眼高手低的情况。讲到Hash部分的时候,自认为听过课之后比较容易理解Hash的原理,于是放松了代码的练习,先进行一下自我检讨。
Hash这部分原理其实不难理解,它也是数据结构的一种。数据结构最基础的有四种,分别是树、队列、Map、图,延伸之后产生数组、链表等对基础数据结构的应用。而Hash即是基础的数据结构组合而成的较为复杂的数据结构。
Hash主要用到的数据结构是数组和链表,数组部分主要通过下标来查找,是连续的,而链表是指向性的,可以指向下一个结点,是非连续的。我对链表的掌握还是比较生疏,导致之后的应用出现一些问题。
Hash结构是怎么来的呢?就像门上的珠帘一样,Hash是一个挂链式的结构,最上层是数组的分布,向Hash中添加元素的时候,总是会产生冲突的。我用到的将元素添加到数组方法还是value%size,即根据元素值除以数组大小的余数来将元素添加到与该余数相同下标的数组元素里。而这样就不可避免地会产生冲突,一个数组只能放一个数值,怎么办呢?这时我们就将余数相同的元素像链子一样一个一个地挂在数组元素的下方,这样一串一串地挂下来形成一个珠帘状的结构。
实际写代码的时候,Hash函数里有四个基础的方法,也即函数要实现的效果:增加、删除、查找、修改。为了实现这四个目的,延伸出一些方法和属性,首先来说一下用到的属性:
Size——Hash结构中处在珠帘顶端的数组容量
Length——已存入的元素个数
Local_factory——阀值,这里的阀值是一个临界点,当元素个数与数组容量的比值大于我们设置的阀值时,Hash结构就会进行重新散列。
在主要的MyHash类中用到以下方法:
1 构造方法,创建一个MyHash结构,主要是设置MyHash中数组的初始大小。
2 增加:需要计算出该元素应放入的数组中的下标位置,即value%size,判断数组中该位置是否已经放入元素,如果该位置为空,就直接将要添加的元素放进去;如果该位置已有元素,就进行判断,该位置已存在的元素之后是否有元素,直到判断到nextElement为空的元素的时候,把要添加的元素挂在这个元素的后面,也就是像排队一样依次排下去。最后要进行阀值的判断,就是说将已存入的元素个数与Hash结构的数组容量进行比较,如果大于阀值则调用重散列方法。
3 重散列:在该Hash结构中放入的数据越来越多,就会使得之后的查找、删除越来越麻烦,效率越来越低,因此我们需要把数组的size扩大,将Hash结构进行重新散列,也就是说把这些数据放入一个全新的Hash结构中,而这个新的Hash结构的数组容量将比旧Hash结构的数组容量要大,这样就可以使得查找、删除效率得到提高。当重散列方法被调用的时候,建立一个新数组,容量是原数组容量的两倍,然后找出原Hash结构中的各个元素并将它们添加到新的Hash结构中。
4 删除:在Hash结构中进行循环查找,找到需要删除的元素,将该元素之后的元素挂链上方移动一位,把该元素删除。如果该元素之后未挂其他元素,直接把该元素的位置设置为空。
5 查找:在Hash结构中进行循环,首先查找数组中每一个下标的位置里所储存的元素,如果该下标位置有元素,就在该元素后面继续进行查找,查找该下标的挂链。如果该位置未储存元素,则查找下一位置。直到将所有的元素都查找完毕。
6 修改:在Hash结构中进行循环查找,找到需要修改的元素,并把该元素的值修改成需要修改的数据。
另外,我自己写了Element类,是数组中储存的结点元素的类,该类中主要用到了设置本结点、返回本结点、设置下一结点、返回下一结点、设置结点中数据、返回结点中数据六种方法。
MyHash中难点不在于理解,而在于动手操作。在实际写代码的时候我遇到一些问题,比如说数组越界、空指针等情况,都是思路中没有预料到的,而在删除结点时,也遇到了学习链表结构时候的老问题,即删除时思路被阻塞,总是无法删除到元素本身,而是在查找时用的临时元素,即将Hash结构中的元素赋值到临时元素上以便于循环的元素上进行操作。
学习是一个不能眼高手低的过程,“想”与“做”是有很大不同的,只有真正“做”过了,才是真正的学到了,而眼高手低会导致一知半解,知其然而不知其所以然。所以在以后的学习中还是应该把重心有所转移,尽量在代码上多下功夫,不能掉以轻心!
(我电脑不管怎么发都发不上去代码……总是在缓冲中……望见谅。。。)
分享到:
Global site tag (gtag.js) - Google Analytics
相关推荐
总结来说,MyHash项目是一个集成了多种哈希算法和哈希表实现的工具,它为开发者提供了实践和学习哈希技术的平台。通过研究MyHash的源代码,我们可以深入理解哈希函数的设计原理,提高解决实际问题的能力。无论是进行...
根据提供的文件信息,本文将对Redis的常用命令进行详细的解读与总结。Redis是一种高性能的键值存储系统,常被用于数据库、缓存以及消息中间件等场景。下面将按照文件中提到的不同方面来展开讲解: ### Redis服务...
总结一下,Redis的哈希过期功能允许我们为整个哈希设置一个过期时间,从而实现数据的自动清理。虽然不能为单个字段设置过期时间,但可以通过删除并重新设置整个哈希来达到类似效果。正确地使用这个特性对于构建健壮...
### Redis命令实践基础命令总结 #### 一、Redis简介与启动 Redis是一个开源的内存中的数据结构存储系统,因其高效性和灵活性被广泛应用于多种场景,包括数据库、缓存以及消息中间件等。为了开始使用Redis,首先需要...
总结,Prototype的`Hash`对象提供了一种结构化管理和操作JavaScript对象键值对的方式,通过其丰富的内置方法,使得处理数据变得更加便捷。通过理解并熟练运用这些方法,可以提升代码的可读性和效率,特别是在处理...
#### 四、总结 以上介绍了一些基本的Redis命令,可以帮助开发者快速上手Redis的操作。Redis的强大之处在于其丰富的命令集和灵活的数据结构支持,使得开发者能够轻松应对各种数据管理和操作的需求。为了更深入地学习...
#### 总结 Redis因其高效的数据处理能力和灵活的数据结构支持,在现代软件架构中扮演着越来越重要的角色。掌握上述基础知识可以帮助开发者更好地利用Redis来优化应用性能和实现复杂的功能需求。
#### 六、总结 通过本教程的学习,读者可以掌握Redis的基本命令和常用操作。这些命令不仅包括简单的键值操作,还包括了复杂的列表、散列等高级数据结构的操作。此外,通过学习Redis的持久化和复制机制,用户可以更...
#### 五、总结 本文主要介绍了Redis的一些基础操作命令以及常用数据结构的操作方法。通过这些命令,我们可以高效地管理Redis中的数据。然而,Redis的功能远不止于此,还有许多高级特性等待我们去探索和学习,比如...
总结来说,通过`qredis`库,Qt开发者可以轻松地将Redis数据库集成到他们的应用程序中,实现各种数据操作、发布/订阅、事务处理等功能,从而扩展Qt应用程序的存储和通信能力。这个过程涉及到C++编程、Qt库的使用以及...
总结,Redis 是一款功能强大的键值存储系统,在 Linux 环境下,它的安装、配置和使用都相对简单。无论是作为高速缓存、数据库还是消息队列,Redis 都能为应用程序提供高效的数据服务。通过熟练掌握 Redis 的基本操作...
#### 四、总结 Redis因其强大的功能、高效率和易用性,在现代应用程序开发中扮演着重要的角色。通过了解和掌握以上介绍的各种数据类型和命令,开发者能够有效地利用Redis来提高应用性能、简化复杂逻辑、实现高效的...
**总结** PHP Redis扩展是连接和操作Redis的强大工具,它提供了丰富的API,能够满足各种数据操作需求。正确安装和配置扩展后,开发者可以轻松地将Redis集成到PHP应用中,提升应用的性能和可扩展性。无论是在缓存、...
最后,文章还推荐了读者查阅PHP相关的其他专题,如加密方法总结、编码与转码操作技巧、数学运算技巧、数组操作、字符串处理、数据结构与算法教程、程序设计算法总结和正则表达式用法总结,这些都是深入学习PHP以及...
根据给出的代码示例,可以总结出以下知识点: 1. HTML结构:首先需要有一个包含多个选项卡的HTML结构,每个选项卡通过a标签显示,并且绑定数据。 2. Vue实例:创建一个Vue实例,其中包括选项卡的数据和一个变量...
#### 总结 本文详细介绍了Redis的安装、配置和基础操作,并通过一个简单的消息队列案例项目展示了Redis的实际应用。通过学习本文,读者可以掌握Redis的基本使用方法和应用场景,并了解如何在实际项目中使用Redis进行...
总结,Jedis 2.9.0 API为Java开发者提供了全面且高效的Redis操作手段,涵盖了Redis的所有基本数据类型和高级特性。理解并熟练使用这些API,能有效地提升应用的性能和可靠性。通过不断的实践和优化,开发者可以更好地...
redisTemplate.opsForHash().putAll("myHash", fieldsValues); ``` **总结** Spring Redis集成使得我们在Spring应用中使用Redis变得更加简便,通过`RedisTemplate`我们可以方便地执行各种Redis操作,同时Spring ...
var myHash = $H({key1: 'value1', key2: 'value2'}); ``` 接下来,$R则是创建ObjectRange对象的简便方法。ObjectRange通常用于表示一组连续的对象或数值,它提供了迭代和操作这个范围的函数。在处理数组或需要遍历...
而关联数组(或对象)则是由键值对组成的,键用于标识每个值,可以用花括号包裹,如`var myhash = {key1: "val1", key2: "val2"};`。关联数组与JSON的主要区别在于JSON要求键值对使用双引号,并且是一种数据交换格式...