数据结构(哈希表(中)纯概念版)
前言
哈希表(Hash Table)是计算机科学中的一个基础而重要的数据结构,它广泛评估各种算法和系统中,尤其是在需要快速查找、插入和删除操作的场景中。由于其O( 1)的平均时间复杂度,存储表在性能要求较高的应用中表现得非常出色。它不仅提供了极快的访问速度,还具备灵活的键值对存储方式,使许多应用程序和系统中司机的核心工具。
从现代的内存管理、数据库的索引系统,到复杂的分布式系统,哈希表都发挥了足轻重的作用。它全面感知存储管理、数据去重、词频统计、集合操作、图算法等多方面这种场景,极大地提高了数据存储和访问的效率。
然而,尽管硬盘表在许多应用中具有不可替代的优势,但它的设计和高效实现也面临着一些挑战。例如,如何设计硬盘函数、如何处理硬盘冲突、如何平衡性能和内存使用等问题,都需要开发者在使用哈希表时注意。
本文文章旨在深入探讨哈希表这一数据结构的基本原理、优势与挑战、常见策略优化、实际应用以及与其他数据结构的对比。通过对这些内容的全面了解,可以更好地选择并使用哈希表,以解决实际开发中的各种问题。
无论您是计算机科学的学生,还是有经验的开发者,了解存储表的核心概念、应用场景及优化方法,都会对您在技术深度和广度上有所提升。在接下来的章节中,我们将详细介绍哈希表的各个方面,并通过实际示例和应用案例,帮助您更好地掌握这一重要的数据结构。
6. 哈希表应用程序场景
哈希表凭借其高效的插入和删除操作,广泛评估流行场景中。
6.1 缓存(Cache)
哈希表常用于快速存储系统中,尤其是像Redis和Memcached这样的内存存储服务。它们通常使用哈希表来查找存储数据。例如:
- Redis:存储键值对数据,提供高效的内存查找。
- Memcached:存储静态网页内容,减少数据库访问压力,提高性能。
应用示例:假设一个数据库查询操作的响应时间可以达到很高,为了提高效率,我们使用存储表存储查询结果。每次查询数据库前,先在存储表中查找存储,若存储中存在对应数据,则直接返回服务器值,从而避免重复的数据库查询。
6.2 去重操作
哈希表常用于去重任务,如数据清洗、日志分析等。例如,利用哈希表判断某个元素是否已经出现过,从而产生重复的元素。常见的应用场景包括:
- 去重文件内容:或许是列表中的重复元素。
- 去重用户输入:比如输入一条用户的唯一性。
应用示例:例如在用户输入时,通过将每个输入的字符串(或其他对象)键存入哈希表,若该键存在作为,则说明该输入已已重复。
6.3 频率统计
稀疏表用于广泛的频率统计问题,能够快速统计各个元素的出现频率。该方法在许多文本处理、数据分析和机器学习任务中都有应用。例如:
- 单词频率统计:在文本处理中,哈希表可以用来统计每个单词出现的频率。
- 字符频率统计:统计一段字符串中各个字符出现的次数。
应用示例:统计一篇文章中各个单词的出现次数,可以将每个单词作为键存入哈希表,频次作为对应的值。遇到相同的单词时,直接增加该单词的值。
6.4 字典实现
哈希表是实现字典(key-value)映射的常用数据结构,如Java的HashMap
和Python的dict
。这种映射类型支持快速查找、插入和删除键值对。
应用示例:在编程语言中,哈希表广泛用于实现变量值的映射,例如,在解释器和编译器中使用哈希表实现符号表。
6.5 快速查找
哈希表常用于需要快速查找的场景。例如,用户验证、商品查找、推荐系统等应用中可以通过哈希表实现快速查找。
- 用户登录验证:通过哈希表存储用户信息,以便快速查找用户是否已注册并验证密码。
- 商品查找:在电商系统中,使用哈希表存储商品信息,快速响应用户的查询请求。
应用示例:在一个网站中,用户的用户名和密码可以存储在哈希表中,查找时根据用户名找到对应的密码并进行验证。
6.6 实现集合操作
哈希表可以快速实现集合的交集、并集、差集等操作。这些操作通常涉及两个集合的元素对比,而哈希表可以快速判断元素是否属于某个集合。
- 交集操作:通过检查两个哈希表中哪些元素是共享的,得到两个集合的交集。
- 并集操作:将两个哈希表的所有元素合并,得到并集。
- 差集操作:从一个哈希表中删除所有在另一个哈希表中的元素,得到差集。
应用示例:在数据库查询中,假设有两个表,其中一列分别存储A、B我们的数据,通过哈希表实现交集、并集、差集等操作,可以很大程度上提高查询效率。
6.7 算法中的邻接表
在图的表示中,哈希表也经常被用于邻接表的实现。对于高效稀疏图,哈希表特别重要,因为它能动态地存储并查找命名的边。
- 稀疏图:在邻接表中,图的每个节点映射到一个包含其邻接节点的哈希表。在稀疏中,大部分节点的邻接节点数分布,稀疏表通过散列存储和查找提高的效率。
应用示例:在社交网络分析中,使用哈希表表示每个用户及其好友关系(即邻接),关系查询某个用户的好友可以快速返回结果。
7 哈希表的优势与挑战
7.1 哈希表的优势
-
快速的插入、插入和删除操作(O(1) 时间复杂度)
- 哈希表最显着的优势是其支持磁盘时间(O(1))的查找、插入和删除操作。通过哈希函数,键被映射到映射的一个索引位置,因此可以直接访问存储的元素。理论上,这使得存储表能够在极短的时间内完成这些基本操作,尤其适合处理大规模数据。
-
空间利用
- 哈希表通过动态扩容和缩容机制,能够在负载因子(即元素数与哈希表容量的比值)达到一定阈值时自动调整表的大小。这种机制有助于哈希表在不同的使用场景下,灵活适应内存的需求,实现高效的空间利用。
- 在负载梯度较低时,缓存表的空间不会被浪费,避免了内存的过度占用。
-
键值对存储
- 哈希表是基于键值对存储数据的。在实际应用中,我们通常需要根据某个唯一标识符(键)来查找或修改对应的值(数据)。哈希表正好满足这一需求,通过键值对的形式,可以方便地存储和快速访问数据。
-
支持快速访问
- 由于哈希表是基于键直接映射到位置的,查找操作通常不需要遍历整个数据结构,极大地提高了访问效率。在很多场景中,哈希表提供比其他数据结构(如备份、链表、树)等)更快的查找速度。
-
插入和删除操作有效
- 与吞吐量或链表相比,哈希表在插入和删除操作上增加了优势。在哈希表中,只需要根据哈希函数计算键对应的槽位并进行相应的插入或删除,而不需要像链表那样遍历元素,或者像吞吐量那样大量移动元素。因此,插入和删除操作的时间复杂度为O(1)(平均情况下)。
-
易于实现
- 哈希表结构简单,易于实现。其基本思想是通过哈希函数将键映射到磁盘中的位置,简单而直接。这使得哈希表成为开发中常用的基础数据结构之一
7.2 哈希表的挑战
-
哈希冲突的问题
- 问题描述:哈希表依赖哈希函数将键映射到磁盘的槽(或桶)中,但是不同的键可能被映射到相同的槽位置,这就是所谓的哈希冲突(Collision)。
- 解决方法:
- 链式法(Chaining):使用链表或其他数据结构存储发生冲突的元素。每个槽会存储一个链表,所有哈希值相同的元素都会被追加到该链表中。
- 开放地址法(Open Addressing):在哈希表中查找下一个空槽来存储发生冲突的要素。常见的探查方法有线性探查、二次探查和双重拓扑。
- 影响:如果哈希冲突处理不当,其中冲突会导致删除、插入和删除操作的性能下降,时间复杂度可能从 O(1) 增加到 O(n),n 是哈希表中的元素数量。
-
内存使用
- 问题描述:哈希表需要额外的内存存储来数据。除了存储元素本身,哈希表还需要额外的空间来存储槽每个(桶)。如果哈希表过度稀疏,内存的使用效率低,浪费空间;如果负载因子过大,间隙间隙,性能下降。
- 影响:内存占用可能成为性能瓶颈,特别是在处理大规模数据时。
- 解决方法:动态扩容和缩容是常见的优化手段,当负载因子达到某个阈值时,缓存表会自动扩展以提高性能,避免冲突。
-
哈希函数设计
- 问题描述:哈希函数的设计至关重要,它决定了哈希表的性能。一个好的好的哈希函数应该能够均匀分配键值,避免集中发生的冲突。如果哈希函数,可能会导致大量的哈希冲突,从而影响哈希表的操作效率。
- 挑战:
- 设计一个哈希函数,使得不同的输入键需要的碰撞概率较低。
- 对于复杂的数据类型(例如复合对象),哈希函数的设计极其困难。
- 影响:不良的哈希函数可能导致哈希冲突频繁发生,从而降低哈希表操作的性能。
-
不保证预期成本
- 问题描述:哈希表中的元素是通过哈希函数直接映射到槽位置的因此,插入元素的顺序和哈希表内部存储的顺序并不一致。哈希表并不能保证元素的顺序,这使得在某些需要遍历元素时,哈希表的表现优于其他数据结构(如链表、吞吐量或树)直接。
- 影响:对于那些需要按插入顺序或按某种顺序遍历元素的场景,哈希表可能不是最常用的选择。
- 解决方法:
- 可以使用社区哈希表(例如Python中的
OrderedDict
)来保存插件顺序,或者在特定场景下使用其他数据结构。
- 可以使用社区哈希表(例如Python中的
-
扩容和缩容的费用开销
- 问题描述:当哈希表的负载因子超过某个阈值时,哈希表会触发扩容操作,通常会初始化哈希表的大小翻倍。扩容时,所有的元素都需要重新计算哈希值并被重新分配到新的槽中,这是一个昂贵的操作。
- 影响:扩容操作的开销可能会影响程序的性能,尤其是在分区表经常扩容的情况下,可能导致时间复杂度不稳定。
- 解决方法:
- 合理地选择分区表的初始大小和负载因子,分区的扩容。
- 在这种情况下,可以采用延期扩容的方式(延迟一些扩容,随后扩展)。
-
固定容量
- 问题描述:哈希表的容量是固定的,当要素数量增长到哈希表容量的某个阈值时,需要扩容。如果扩容策略不当或容量设置过小,可能会导致性能瓶颈。
- 影响:扩容会导致重新分区操作的时间开销,并可能在高并发环境下导致性能下降。
- 解决方法:合理选择初始容量和负载因子,优化扩容策略。
-
线程安全问题
- 问题描述:哈希表在多线程环境中可能会遇到线程安全问题。在多个线程同时进行插入、删除、查找等操作时,如果没有采取合适的同步措施,可能会导致数据不一致或程序崩溃。
- 影响:哈希表的并发访问会带来复杂性,尤其是在多线程环境下。
- 解决方法:可以通过锁(如互斥锁)先进的算数数据结构(如ConcurrentHashMap)来解决线程安全问题。
8 哈希表的优化策略
8.1 传记函数设计
- 均匀分布:哈希函数的设计应尽量保证哈希值的分布,减少哈希冲突。一个好的哈希函数能够将不同的键映射到哈希表的不同槽中,避免将多个键映射到相同的位置。
- 避免集中冲突:例如,对于字符串类型的键,常见的存储函数如DJB2和MurmurHash被认为具有很好的性能表现,它们能够减少冲突。
- 多个字段:对于复合数据类型(混合例如结构体、对象),可以通过混合多个字段的哈希值来生成更好的哈希值。
- 操作优化:一些哈希表函数利用位腐蚀(如分区、异或)来更均匀地分配键值,从而提高哈希表的性能。
8.2 合适的负载因子和容扩策略
- 选择合理的负载因子:负载因子(load Factor)是轴承表中元素个数与轴承表槽数的比值。一个合理的负载因子可以平衡轴承表的空间使用和查询性能。通常,负载因子应设置为0.7到0.75之间,这样可以避免间隔的扩容操作,同时减少冲突。
- 扩容策略:当负载因子超过某个阈值时,哈希表应自动扩容。扩容时,通常会分割表的大小翻倍,重新布局所有元素。合理的扩容可以适时减少扩容次数并带来的性能头顶。
- 动态调整负载因子:在某些场景下,可以动态调整负载因子。例如,在基本时刻使用较小的负载因子来提高空间利用率,而在元素焦点时使用最重要的负载因子来减少内存头顶。
8.3 结构优化
- 链式优化:在链式法(Chaining)中,每个槽位通常存储一个链表。当链表最少时,查找效率会下降。因此,采用以下方法可以优化:
- 使用其他数据结构:在链表中存储元素时,可以使用平衡树(如红黑树)代替链表,当链表长度超过一定阈值时,将链表转化为平衡树,这样可以提高查找效率,从 O(n ) 提升到O(log n)。
- 哈希表桶内部存储:使用更高效的存储结构(例如哈希桶备份或自平衡二叉树),来减少链表长度,提高操作效率。
- 开放地址法优化:在开放地址法中,元素存储在哈希表的槽中,碰撞时会探查下一个空槽。以下是常用的优化方法:
- 线性探查:若哈希槽发生冲突,检查下一个槽,直到找到空槽。可以采用某些变种来减少冲突,如二次探查和双重哈希。
- 使用更高效的探查策略:例如,采用双重哈希技术,通过两个哈希函数生成探查序列,从而减少在某些区域的情况下的冲突集中。
8.4 减少内存
- 初始化合适的容量:在使用缓存表时,应该根据预期的数据量合理初始化缓存表的大小。避免初始化一个过小的表,导致重复容量,或者初始化一个过大的表,浪费内存。
- 动态负载因子调整:通过动态调整负载因子,能够减少内存的浪费。对于不经常修改缓存表大小的场景,可以设置较低的负载因子来优化内存使用。
8.5 并发线程安全优化
- 线程安全哈希表:在多线程环境中使用哈希表时,通常需要考虑高效并发问题。传统的哈希表不是线程安全的,可以使用锁使用多个机制的并发哈希表来保证线程安全。
- 分布式哈希表:像Java的
ConcurrentHashMap
或C++的unordered_map
提供了分布式版本的哈希表,通过分段锁(Segmented Locks)等技术减少线程争用,提升分布式性能。 - 无锁设计:对于极高并发的环境,可以考虑使用无锁哈希表,通过原子操作等技术避免锁带来的性能开销。
8.6 你的扩容与缩容
- 禁止扩容:在一些应用中,可以使用禁止扩容策略,即仅在真正需要扩容时才进行扩容。这样就避免了扩容的操作,也减少了内存的浪费。
- 缩容机制:如果暂停表在间歇期保持较低的负载因子,可以通过缩容来释放不必要的内存一段时间。需要注意的是,缩容操作会涉及重新暂停,因此也需要避免间隙进行。
8.7 内存局部性
- 缓存模式的设计:现代计算机的内存是分层的,优化缓存表的内存布局可以提高缓存命中率,进一步提高缓存表的性能。例如,将缓存表的数据存储在连续的内存块中,避免内存的访问。
- 减少内存碎片:通过避免合理的内存管理策略,缓存表扩容时产生大量碎片,尤其是在需要进行间歇操作的情况下。
8.8 选择合适的数据结构
- 适应具体场景:在一些特定场景下,分区表可能不是最优化选择。例如,在需要维护社区数据的情况下,可以使用平衡二叉树或跳表(如TreeMap或SkipList)。在需要间隙查找最大值或简单的场景,可以考虑使用优先队列(堆)。
9 哈希表与其他数据结构的对比
哈希表(Hash Table)是一种非常的数据结构,特别适用于需要快速快速插入、插入和删除操作的场景。但是,哈希表并非适用于所有场景,其他数据结构(如集群、链表、树、堆等)在不同的应用中也有其优势。以下是哈希表与其他常见数据结构的对比,帮助你理解它们的优点缺点,以及在不同场景下如何选择合适的结构。
1.哈希表 vs 数组
分析:
- 哈希表的插入、插入和删除操作通常是 O(1) 时间复杂度(在哈希冲突突发的情况下),远比磁盘的 O(n) 要高效,尤其是在数据量增大的时候。
- 吞吐量提供顺序访问,哈希表不保证顺序。如果你需要按顺序遍历元素,那么吞吐量可能是更好的选择。
2.哈希表与链表
分析:
- 哈希表的查找性能远胜链表(O(1) vs O(n)),在查找频繁的场景下,哈希表更加高效。
- 链表在插入和删除操作方面通常比哈希表更简单,但它的查找操作遍历链表,因此在需要快速查找的场景下,哈希表比链表更优。
3.哈希表 vs 二叉搜索树(BST)
分析:
- 哈希表在插入、插入和删除操作的平均时间复杂度是 O(1),远高于二叉搜索树的 O(log n)(对于平衡树)。然而,哈希表的元素是无序的的,不支持按顺序遍历。
- 二叉搜索树(特别是平衡二叉树搜索如AVL树、红黑树)具有分组性,支持按顺序查找以及范围查询,但在查找和修改操作上不如哈希表高效。
- 如果需要范围查询和顺序访问,二叉树搜索比哈希表更适合。如果主要注重快速删除、插入和删除操作,哈希表是更好的选择。
4.哈希表与堆(Heap)
分析:
- 哈希表提供了相对时间复杂度的查找、插入和删除操作,非常适合快速查找的应用场景。
- 堆主要用于需要间隙获取顶部或简单的场景,如优先排序、排序等。虽然堆的插入和删除操作在时间复杂度上较优(O(log n)),但查找任意元素的效率较高较低(O(n))。
- 如果需要高效的立即/快速选择访问,堆是更合适的;而如果需要快速查找某个元素,则哈希表更合适。
5.哈希表与栈/边界
分析:
- 哈希表主要用于插入和删除元素,并不是元素的顺序;而栈和队列是按顺序操作的,栈实现关注后进先出(LIFO),队列实现先进先出(FIFO)。
- 栈和队列非常适合那些需要遵循特定顺序的操作(如函数调用栈、任务队列等),而哈希表则更适用于需要快速访问特定元素的场景。
10. 总结
哈希表(Hash Table)是一种数据结构,广泛用于需要快速查找、插入和删除操作的场景。然而,它也存在一些限制和挑战。在实际开发中,根据不同的应用需求,选择合适的数据结构。
10.1 哈希表的优缺点总结
10.1.1哈希表的优势
-
快速的插入、插入和删除操作:
- 平均时间复杂度为O(1),在处理大量数据时,能够提供非常高效的操作。
- 对于字典、存储、索引等场景,哈希表表现出色。
-
我们空间利用:
- 哈希表利用存储和哈希函数来管理数据,具有更高的空间利用率。通过动态扩容和缩容机制,可以自适应数据变化。
-
适用于快速键值对存储与访问:
- 适合在需要通过特定按键快速访问值的场景,例如存储用户信息、商品数据、状态信息等。
10.1.2 哈希表的挑战
-
哈希冲突问题:
- 不同的键可能会映射到相同的哈希槽,这会导致冲突。处理冲突的策略(如链式法、开放地址法)可能会影响性能。
-
内存地址:
- 哈希表通常需要额外的空间来处理哈希冲突,尤其是在负载因子较高的情况下,扩容和存储结构可能会浪费大量内存。
-
无法保证要素的顺序:
- 哈希表内部的元素顺序是不可预测的,这使得在需要顺序遍历时,哈希表不如其他数据结构(如链表、磁盘)适用。
-
哈希函数设计难度:
- 一个好的哈希函数能够极大地提高哈希表的性能。如果哈希函数设计不好,会导致间隙的冲突,进而影响性能。
10.2 选择哈希表的场景
10.2.1 选择哈希表的场景
-
需要快速插入、插入和删除:
- 如果你的应用需要进行磁盘分区、插入和删除操作,那么存储表是一个非常合适的选择。例如,字典、存储、存储集合等。
-
键值对存储和访问:
- 如果应用程序需要基于按键快速访问对应的值,哈希表是理想的选择。它全面评估实现的存储机制、用户会话管理、索引结构等。
-
没有顺序要求:
- 哈希表适合那些不关心元素顺序的场景。如果你不需要按顺序访问元素,那么哈希表可以提供极高的操作效率。
-
内存密钥:
- 如果对内存的使用有一定的忍受度,缓存表可以通过合理的扩容和负载因子管理,提供的查找性能。
10.2.2 什么时候选择其他数据结构
-
需要维护元素的顺序:
- 如果需要按顺序访问数据,可以选择阵列、链表或排序树结构。比如,链表适合需要顺序操作(如队列和栈)的场景,而二叉搜索树适合范围查询或按顺序遍历的场景。
-
内容定位:
- 如果内存使用非常严格,可能需要避免缓存表带来的内存开销。在这种情况下,选择像仓库、链表等结构可能更加高效,尤其是当数据规模较小时。
-
间隙的排序或范围查询操作:
- 哈希表不适合需要排序、范围查询的场景。如果你的应用需要这些操作,二叉搜索树(如红黑树、AVL树)或跳表会更适合。
-
多线程/并发场景:
- 在多线程环境中,如果线程同时考虑访问和修改多个哈希表,可能会面临线程安全问题。此时可以使用线程安全的哈希表(如
ConcurrentHashMap
)或选择其他哈希数据结构。
- 在多线程环境中,如果线程同时考虑访问和修改多个哈希表,可能会面临线程安全问题。此时可以使用线程安全的哈希表(如
10.3 哈希表在实际项目中的应用
哈希表在实际开发中有广泛的应用,特别是在需要快速查找、存储和检索数据的场景。以下是一些常见的应用和实践建议:
10.3.1 储存
哈希表常用于实际存储系统,例如在内存中存储数据库查询结果、API响应、计算结果等,以提高系统性能和响应速度。
-
应用场景:
- LRU(最近最少使用)磁盘:通过哈希表结合哈希表实现,哈希表提供快速的键值访问,哈希表保持元素的顺序,允许在O(1)时间复杂度内插入、删除和更新磁盘项。
- 数据库服务器:数据库查询结果经常被服务器存储到缓存表中,当请求相同的数据时,可以直接从服务器中获取,避免重复计算,提高系统性能。
-
实践建议:
- 选择合适的磁盘删除策略(如LRU、LFU)来管理磁盘的大小和效果。
- 注意内存的管理和清理机制,避免服务器崩溃或服务器雪崩问题。
10.3.2 字典和映射
哈希表是实现字典(Dictionary)、映射(Map)等数据结构的核心。它常用于存储键值对映射,如用户信息、商品属性、配置文件等。
-
应用场景:
- 用户信息存储:在用户登录系统中,可以使用哈希表将用户的ID映射到用户的详细信息(如用户名、权限、历史记录等)。
- 配置文件管理:将配置项的名称映射到具体的配置值,支持快速查询和更新。
- 缓存字典:如CDN(内容分发网络)中,通过缓存表快速查找和缓存网页内容或图片等资源。
-
实践建议:
- 对于海量数据,选择合适的存储函数,保证存储冲突少,从而保持高效的查找性能。
- 在分散系统中,可以考虑分散分布表(如一致性哈希)来处理大规模的数据分布。
10.3.3 计数和统计
哈希表在间隔统计、统计或去重场景中非常有用,例如计算词频、统计用户行为等。
-
应用场景:
- 词频统计:在文本处理中,哈希表可以用来记录每个单词出现的高效次数,特别是在大数据处理中,它比传统的线性查找更。
- 去重操作:通过哈希表存储已经出现的元素,可以有效去除重复数据。适用于去除数据流中的重复项、日志文件中的重复项等。
-
实践建议:
- 使用哈希表的Set结构来重来,这种结构不允许重复元素,可以快速判断元素是否已经存在。
- 处理计数时,可以考虑将哈希表与排序、优先队列结合,来实现按频率排序等复杂需求。
10.3.4 数据去重
哈希表是数据重操作中的理想数据结构。通过将每个元素的哈希值作为键,哈希表可以快速判断元素是否已经去出现,从而高效重复数据。
-
应用场景:
- 去日志重:在日志收集和分析系统中,哈希表可以用于取消重复日志事件,避免多次处理相同的事件。
- 文件去重:在文件存储系统中,使用存储表存储文件的存储值,可以检查文件是否已经存在,避免重复上传或存储相同的文件。
-
实践建议:
- 对于去重场景,可以将缓存表与布隆过滤器结合使用,以减少内存使用量,尤其是在海量数据场景下。
- 注意处理哈希冲突和内存消耗,确保系统稳定运行。
10.3.5 支持快速查找的集合操作
哈希表广泛实现集合数据结构,如HashSet或HashMap,提供快速的元素查找、插入和删除。
-
应用场景:
- 集合侵犯:在处理集合交集、并集、差集等操作时,哈希表可以提供快速的元素查找和合并操作。
- 事件追踪:在事件处理系统中,哈希表可以用来记录已发生的事件,避免事件重复触发。
-
实践建议:
- 在需要高效集合损坏的场景中,优先选择哈希表来存储和操作元素,避免不必要的线性扫描。
- 在实现集合时,合理设置哈希表的骨髓容量和负载因子,避免阻断扩容。
10.3.6 图算法中的邻接表表示
哈希表用于广泛图结构的表示,尤其是在表示邻接表时,哈希表能够有效地将每个节点映射到其邻接节点列表,支持快速访问和更新。
-
应用场景:
- 社交网络分析:在社交网络中,用户与用户之间的关系可以使用哈希表表示,快速查找用户的好友、粉丝或关注对象。
- 网络路由:在网络路由算法中,可以利用哈希表表示每个节点与其他节点的连接,实现关系快速查找和更新路由信息。
-
实践建议:
- 在图算法中,结合哈希表的邻接列表和优先队列(如Dijkstra算法)等数据结构,可以提高图遍历和最短路径计算的效率。
- 注意在图中的稀疏与密集表示中合理选择稀疏表和邻接矩阵的组合,确保性能优化。
10.3.7 任务调度和队列管理
在某些调度系统或任务管理系统中,缓存表用于管理任务的状态、优先级等信息,并支持快速的任务查找和调度。
-
应用场景:
- 任务调度系统:通过哈希表将任务ID映射到任务状态,可以快速搜索和更新任务的状态,支持任务的调度和执行。
- 消息队列:在全球消息队列中,哈希表用于管理消息的索引和处理状态,实现快速的消息查找和处理。
-
实践建议:
- 在设计任务调度和队列系统时,注意哈希表的线程安全性,确保在多线程环境中访问数据时不会出现竞争问题。
- 对于任务优先级排序,可以将哈希表与优先队列结合,优化任务调度的效率。
10.3.8 引擎搜索中的索引管理
哈希表是搜索引擎中用于实现倒排索引的关键技术,通过映射映射到文档集合,支持快速的搜索查询。
-
应用场景:
- 全文搜索:将单词映射到包含该单词的文档列表,支持快速的单词搜索和相关文档搜索。
- 关键词索引:通过哈希表存储关键词与文档的关系,能够高效实现对大规模文档库的索引和查询。
-
实践建议:
- 在建立倒排索引时,采用高效的哈希函数来减少哈希冲突,提升搜索速度。
- 考虑哈希表在内存使用上的影响,可以与磁盘存储结合,处理超大规模数据集。
11. 参考资料与进一步阅读
哈希表是计算机科学中的基础数据结构,广泛覆盖各个领域。以下是一些有价值的参考资料和进一步阅读材料,帮助您深入理解哈希表的理论、实现、优化和应用。
11.1 书籍
-
《算法导论》(算法导论)- Thomas H. Cormen、Charles E. Leiserson、Ronald L. Rivest、Clifford Stein
- 本书是计算机科学领域的经典教材,讲述了哈希表及其相关算法。书中详细介绍了哈希表的实现、哈希函数设计、冲突处理策略等内容。
- 章节推荐:哈希表相关章节(第11章)
-
《数据结构与算法分析:C 语言描述》(C 语言中的数据结构和算法分析)- Mark Allen Weiss
- 本书通过C语言讲解数据结构和算法,其中哈希表的实现与应用部分也非常精彩,适合想要深入理解哈希表的读卡器。
-
《计算机程序设计艺术》(计算机编程的艺术)——Donald E. Knuth
- 这本书是计算机科学经典,全面介绍了算法与数据结构的方面。对于深度学习、哈希表设计和优化的读卡器非常有帮助。
- 推荐章节:第6卷《组合数学和算法》
-
《数据结构与算法:Python语言描述》(Python中的数据结构和算法) - Michael T. Goodrich, Roberto Tamassia, Michael H. Goldwasser
- 本书详细讲解了在Python中实现各种数据结构,包括缓存表的实现和优化,非常适合使用Python进行读卡器的实践。
-
《Python算法与数据结构》(Python算法与数据结构)-Magnus Lie Hetland
- 于Python实现而言,涉及到了哈希表的实现及其应用,适合希望将哈希表实现实际项目的开发者。
11.2 学术论文与文章
-
Richard E. Korf 著《算法设计与分析:哈希技术》
- 这篇文章探讨了缓存表设计中的关键问题,尤其是在缓存冲突处理和缓存函数设计方面。适合对算法分析感兴趣的读者。
-
JFK Ram 撰写的《哈希技术概述》
- 本论文综述了哈希技术的不同类型,包括静态哈希、动态哈希、扩展哈希等,为读者提供哈希表的历史和未来发展方向的深入理解。
11.3 在线资源
-
GeeksforGeeks - 哈希
- GeeksforGeeks的哈希表教程
- 这是一个非常适合初学者的在线学习资源,详细介绍了哈希表的基本概念、实现以及冲突解决方法。文章内容丰富,示例和图标,帮助理解哈希表的工作原理。
-
维基百科 - 哈希表
- 哈希表- Wikipedia
- 维基百科的哈希表页面是一个详细的资源,包含了哈希表的定义、实现、性能分析和应用案例,适合了解哈希表的基本概念和一些高级内容。
-
Python官方文档 - dict 类型
- Python官方文档-dict类型
- 如果您使用Python,Python官方文档提供了关于
dict
(字典)类型的详细说明,Python的字典类型实际上是基于哈希表实现的,文档中解释了字典的实现原理、操作和性能。
-
Visualgo-哈希
- Visualgo -哈希表可视化
- Visualgo是一款互动式的在线可视化工具,支持哈希表的操作演示。通过该平台,您可以深入理解哈希表的插入、删除、查找等操作。
-
LeetCode - 哈希表 题目
- LeetCode -哈希表相关问题
- LeetCode平台上有大量关于哈希表的主题编程,涵盖了不同主题负载的哈希表问题。这些非常适合通过实践深入理解哈希表的实际应用和挑战。
11.4 视频
-
Coursera - 数据结构和算法专业
- Coursera :数据结构和算法专业化
- 由加州大学沙巴分校提供的课程,专门介绍各种数据结构,包括缓存表的实现与优化,适合对算法和数据结构感兴趣的学生。
-
Udemy - 使用 C 和 C++ 掌握数据结构和算法
- Udemy :使用C和C++掌握数据结构和算法
- 本门课程详细介绍了C/C++中常用数据结构的实现和优化,其中包括哈希表的实现。
-
MIT 开放式课程 - 算法导论 (6.006)
- MIT开放式课程:算法导论(6.006)
- 这门课程是麻省理工学院计算机科学与工程系的经典课程,讲解了包括哈希表在内的多种基础数据结构和算法。
11.5 博客 与技术文章
-
计算机科学中的哈希算法 - 迈向数据科学
- 计算机科学中的哈希
- 这篇文章深入浅出地介绍了哈希表的原理、哈希函数的设计以及哈希冲突的处理方式,是学习哈希表的好资源。
-
“如何处理哈希表中的冲突” - Stack Overflow 博客
- 处理哈希表中的冲突
- 这篇文章讨论了哈希表中冲突处理的各种方法,特别是如何设计有效的哈希函数和解决冲突的技术(如开放地址法、链式法等)。
-
哈希技术实践 - Medium
- 哈希技术实践
- Medium上的这篇文章详细讲解了实际开发中缓存技术的应用和挑战,包括缓存表的优化和性能提升技巧。
结语
哈希表作为计算机科学中的基础数据结构之一,凭借其高效的查找、插入和删除操作,在各种应用场景中发挥着至关重要的作用。从存储机制、字典到数据存储重和图算法,存储表在处理大规模数据时的极大性能,使得成为许多高效算法和系统的核心组成部分。
然而,哈希表的使用并非没有挑战。设计一个好的哈希函数、解决哈希冲突、合理控制内存开销、处理线程安全等问题,都需要开发者具备深入的理解和实践经验。在实际开发中其中,了解哈希表的优缺点、使用场景和优化策略,将有助于我们选择最合适的数据结构来满足项目需求。
通过不断的学习和实践,掌握哈希表的应用,能够显着提升我们在处理复杂问题时的能力。在面对大规模数据、性能要求高的场景时,哈希表无疑是一个强大的工具,而在选择哈希表或其他数据结构时,始终要根据具体问题的特点做出明智的决策。
无论是作为编程初学者还是丰富的开发者,持续深入理解存储表的实现、优化和应用,都会在实际项目中带来巨大的帮助。希望通过本篇总结,您能够更好地掌握经验哈希表的使用,并在未来的技术实践中游刃有余。
相关文章:
数据结构(哈希表(中)纯概念版)
前言 哈希表(Hash Table)是计算机科学中的一个基础而重要的数据结构,它广泛评估各种算法和系统中,尤其是在需要快速查找、插入和删除操作的场景中。由于其O( 1)的平均时间复杂度,存储表在性能要求较高的应用中表现得非…...
Node.js 工具:在 Windows 11 中配置 Node.js 的详细步骤
一、概述 记录时间 [2024-12-25] 本文讲述如何在 Windows 11 中进行 Node.js 工具的安装和配置。 以下是详细的步骤和说明。 二、安装 Node.js 1. 官网下载 通过官网,下载 Node.js,上面有好几种下载方式,文中下载的是 zip 压缩包。 如图&…...
工作流并行网关退回思路
问题描述 在设计工作流时遇到并行的流程,会出现并行流程的退回,这里记录下想到的解决思路,后续问题会记录在这里。 流程图 这里是一个简单的流程图: 并行退回思路 若是正常流程退回,流程是: 获取回退…...
C#数学相关开发性能优化方法
本文Github地址:CSharp-MathOptimization.md 华为公司的C语言编程规范在开头就强调了: 一般情况下,代码的可阅读性高于性能,只有确定性能是瓶颈时,才应该主动优化。 本文讲述的方法没有经过大项目和大公司的检验&…...
vulnhub jangow靶机
1.扫描靶机IP arp-scan -l如果扫不到靶机的话根据以下配置 启动时点击第二个 按回车 继续选择第二个 按e进入编辑 删除"recovery nomodeset" 在末尾添加"quiet splash rw init/bin/bash" Ctrlx 启动进入如下界面 passwd修改root密码 重启电脑登录root修…...
配置搜索无人机
升级ubuntu内核 https://www.bilibili.com/video/BV11X4y1h7qN/?spm_id_from333.337.search-card.all.click 进入四个内核文件并安装 sudo dpkg -i *.deb安装ROS,PX4,XTDrone,QGC https://blog.csdn.net/qq_45493236/article/details/13…...
2-6-1-1 QNX编程入门之进程和线程(四)
阅读前言 本文以QNX系统官方的文档英文原版资料“Getting Started with QNX Neutrino: A Guide for Realtime Programmers”为参考,翻译和逐句校对后,对在QNX操作系统下进行应用程序开发及进行资源管理器编写开发等方面,进行了深度整理&…...
Vue开发环境搭建上篇:安装NVM和NPM(cpnm、pnpm)
文章目录 引言I 安装NVM1.1 Windows系统安装NVM,实现Node.js多版本管理1.2 配置下载镜像1.3 NVM常用操作命令II NPM永久使用淘宝源安装 cnpm安装pnpm【推荐】see also: vscode常用插件引言 淘宝镜像:http://npm.taobao.org 和 http://registry.npm.taobao.org 已在 2022.06.3…...
2.微服务灰度发布落地实践(agent实现)
文章目录 前言java agent的介绍基础实现agent端 http服务实现agent端api接口 前言 据上一篇,设计方案的分析,综合考虑,最终决定,客户端采用agent方案实现,具本原因不再赘述, 感觉兴趣的小伙伴可以回头了解一下.该篇主…...
网络安全专业术语
网络安全专有名词详解 1.肉鸡 被黑客操控的终端设备(电脑、服务器、移动设备等等),黑客可以随心所欲的操作这些终端设备而不会被发觉。 2.木马 表面上伪装成正常的程序,但是当这些程序运行时候就会获取整个系统的控制权限&#…...
SpringMVC核心、两种视图解析方法、过滤器拦截器 “ / “ 的意义
SpringMVC的执行流程 1. Spring MVC 的视图解析机制 Spring MVC 的核心职责之一是将数据绑定到视图并呈现给用户。它通过 视图解析器(View Resolver) 来将逻辑视图名称解析为具体的视图文件(如 HTML、JSP)。 核心流程 Controlle…...
ubuntu快速入门
1.进入某个文件夹 cd workspace/2.tab自动补全 3.列出当前文件夹所有文件 ls列出所有文件包括隐藏文件 ls -a 4.创建文件夹 mkdir linuxLearn 5.创建文件 gedit command.sh在commmand.sh键入 echo hello echo hi? echo how are you? PS:touch hello.txt(也可以创建新…...
HarmonyOS NEXT应用开发实战:一分钟写一个网络接口,JsonFormat插件推荐
在开发鸿蒙操作系统应用时,网络接口的实现往往是一个繁琐且重复的过程。为了提高开发效率,坚果派(nutpi.net)特别推出了一个非常实用的插件——JsonFormat。这款插件的主要功能是将JSON格式的数据直接转换为arkts的结构定义,让我们在编写接口…...
光谱相机与普通相机的区别
一、成像目的 普通相机:主要目的是记录物体的外观形态,生成人眼可见的、直观的二维图像,重点在于还原物体的形状、颜色和纹理等视觉特征,以供人们进行观赏、记录场景或人物等用途。例如,拍摄旅游风景照片、人物肖像等…...
贝叶斯神经网络(Bayesian Neural Network)
最近在研究贝叶斯神经网络,一些概念一直搞不清楚,这里整理一下相关内容,方便以后查阅。 贝叶斯神经网络(Bayesian Neural Network) 贝叶斯神经网络(Bayesian Neural Network)1. BNN 的核心思想2. BNN 的优化目标3. BNN 的结构与特点4. BNN 的训练过程5. BNN 的优缺点6. …...
使用FFmpeg进行拉流和推流操作
FFmpeg是一款强大的多媒体处理工具,可以用于视频的录制、转换、推流和拉流等操作。下面将详细介绍如何使用FFmpeg进行拉流和推流操作。 1. FFmpeg推流操作 推流是将本地的音视频流推送到流媒体服务器上,例如主播将本地电脑上的画面推流到直播平台的流媒…...
flutter插件开发-ios
flutter插件开发是一个重要的技能,拓展flutter与原生的通信,将一些公用的东西封装,给不同的项目使用。 阅读前置: flutter基本通道调用 objective-c基础语法 ios项目基础知识 目录 1、创建一个插件项目2、项目结构3、编写原生代码…...
【代码随想录|完全背包问题】
518.零钱兑换|| 题目链接:518. 零钱兑换 II - 力扣(LeetCode) 这里求的是组合数,就是不强调元素排列的顺序,211和121是同一个数那种,要先遍历物品,这样的话我算出来的每个值才是按顺序121&…...
xss csrf怎么预防?
一、XSS(跨站脚本攻击)预防 XSS 是指攻击者向目标网站注入恶意脚本,从而在用户浏览器中执行。 1. 输入过滤 清理用户输入: 拦截或清理HTML特殊字符(如 <, >, , ", &)。使用安全库&#x…...
黑神话悟空游戏鼠标光标使用教程与下载
效果图: 鼠标光标特点 这套鼠标光标的设计灵感来源于《黑神话:悟空》游戏中的角色和元素,具有以下特点: • 主题鲜明:光标设计紧扣游戏主题,采用了游戏中的元素,让玩家在使用电脑时也能感受到…...
<数据集>芝麻作物和杂草识别数据集<目标检测>
数据集下载链接 <数据集>芝麻作物和杂草识别数据集<目标检测>https://download.csdn.net/download/qq_53332949/90181548数据集格式:VOCYOLO格式 图片数量:1300张 标注数量(xml文件个数):130…...
实测数据处理(CS算法处理:可斜视)——SAR成像算法系列(十一)
系列文章目录 《SAR学习笔记-SAR成像算法系列(一)》 《线性调频变标算法(CSA)-SAR成像算法系列(四)》 文章目录 前言 一、算法流程 1.1、回波信号生成 1.2、CS处理 1.3、距离脉压 1.4、方位脉压 1.5…...
【强化学习入门笔记】 2.4 时序差分算法
本系列为学习赵世钰老师的《强化学习的数学原理》所作的学习笔记. 本节我们将介绍强化学习中的蒙特卡洛方法. 2.4.1 Robbins-Monro算法 Robbins-Monro算法是一种随机近似方法,通过迭代的方式求解非线性方程。 假设我们要求解: g ( w ) 0 g(w)0 g(w)0, 但是我们…...
Scrapy数据解析+保存数据
Scrapy数据解析保存数据 目录 1.数据解析 2.基于item存放数据并提交给管道 3.用txt文件来保存数据 今天我们需要爬取B站数据并保存到txt文件里面。 我们先打开B站, 然后点击热门, 进去之后再点击排行榜: 我们打开F12后, 可以看到, 我们想要的请求, 轻而易举的就可以拿到(…...
Redis--缓存穿透、击穿、雪崩以及预热问题(面试高频问题!)
缓存穿透、击穿、雪崩以及预热问题 如何解决缓存穿透?方案一:缓存空对象方案二:布隆过滤器什么是布隆过滤器?优缺点 方案三:接口限流 如何解决缓存击穿问题?方案一:分布式锁方案一改进成双重判定…...
【Python高级353】python实现多线程版本的TCP服务器
前面学了了套接字编程、tcp服务端客户端开发、面向对象版的服务端客户端、带有端口复用的服务端。 这里使用多线程开发多任务版的服务端 多任务版本的TCP服务器 来一个客户,就为其创建一个线程 import socket import threadingclass WebServer:# 3、定义一个__ini…...
【Pandas】pandas Series to_period
Pandas2.2 Series Conversion 方法描述Series.astype用于将Series对象的数据类型转换为指定类型的方法Series.convert_dtypes用于将 Series 对象的数据类型智能地转换为最佳可能的数据类型的方法Series.infer_objects用于尝试推断 Series 中对象(object࿰…...
深度学习领域车辆识别与跟踪
深度学习中车辆识别是一个广泛应用的领域,它涵盖了从车辆检测到车型识别的多个方面。以下是对深度学习中车辆识别与车辆相关内容的详细探讨: 一、车辆检测 车辆检测是车辆识别中的基础任务,其目标是在图像或视频中准确地定位出车辆的位置。…...
数学建模 绘图 图表 可视化(2)
文章目录 前言柱形图条形图克利夫兰点图系列坡度图南丁格尔玫瑰图径向柱图极坐标图词云图总结参考资料 前言 承接上期 数学建模 绘图 图表 可视化(1)的总体描述,这期我们继续跟随《Python 数据可视化之美 专业图表绘制指南》步伐来学习其中l…...
vue源码分析(十)—— 生命周期
文章目录 前言一、关键方法 callHook二、详细的钩子函数说明1.beforeCreate和create2.beforeMount & mounted注意点组件(非根组件)的渲染节点(1)invokeInsertHook函数(2)insert方法(3&#…...
[创业之路-222]:波士顿矩阵与GE矩阵在业务组合选中作用、优缺点比较
目录 一、波士顿矩阵 1、基本原理 2、各象限产品的定义及战略对策 3、应用 4、优点与局限性 二、技术成熟度模型与产品生命周期模型的配对 1、技术成熟度模型 2、产品生命周期模型 3、技术成熟度模型与产品生命周期模型的配对 三、产品生命周期与产品类型的对应关系 …...
# 【超全面了解鸿蒙生命周期】-生命周期补充
【超全面了解鸿蒙生命周期】-生命周期补充 鸿蒙所有的生命周期函数梳理 文章目录 【超全面了解鸿蒙生命周期】-生命周期补充前言一、AbilityStage的生命周期二、ExtensionAbility卡片生命周期三、Web组件常用生命周期 前言 本文是继之前写的生命周期函数梳理的进一步补充&…...
sentinel-请求限流、线程隔离、本地回调、熔断
请求限流:控制QPS来达到限流的目的 线程隔离:控制线程数量来达到限流的目录 本地回调:当线程被限流、隔离、熔断之后、就不会发起远程调用、而是使用本地已经准备好的回调去提醒用户 熔断:熔断也叫断路器,当失败、或者…...
unplugin-vue-router 的基本使用
1. 前言 在Vue3开发过程中,每次创建新的页面都需要注册路由,需要在src/router.ts中新增页面的路径,并将URL路径映射到组件中,如下所示: import { createMemoryHistory, createRouter } from vue-routerimport HomePage…...
[Leetcode] 最大子数组和 [击败99%的解法]
解法1: 暴力解法 遍历每个元素,从它当前位置一直加到最后,然后用一个最大值来记录全局最大值。 代码如下: class Solution {public int maxSubArray(int[] nums) {long sum, max nums[len-1];for (int i0; i<nums.length;…...
SSRF服务端请求Gopher伪协议白盒测试
前言 是什么SSRF? 这个简单点说就是 服务端的请求伪造 就是这个如果是个 请求图片的网站 他的目的是请求外部其他网站的 图片 但是 SSRF指的是让他请求本地的图片 再展示出来 请求的是他的服务器上的图片 SSRF(Server-Side Request Forgery:服务器端请求伪造) …...
[2029].第6-06节:MyISAM引擎中的索引与 InnoDB引擎中的索引对比
所有博客大纲 后端学习大纲 MySQL学习大纲 1.MyISAM索引: 1.1.B树索引适用存储引擎: 1.B树索引适用存储引擎如下表所示: 2.即使多个存储引擎都支持同一种类型的B树索引,但它们的实现原理也是不同的 Innodb和MyISAM默认的索引是B…...
WOFOST作物模型(3):(本地化校准)优化PCSE模型中的参数
目录 一、准备自己的LAI观测数据二、优化参数三、损失函数四、NLOPT优化五、优化结果可视化一、准备自己的LAI观测数据 在进行田间实测后,得到自己的LAI观测数据 在程序这个地方输入自己的LAI采样日期和观测值 二、优化参数 这里主要选择了TDWI(Total Dry Weight at ger…...
如何修改pip全局缓存位置和全局安装包存放路径
使用场景: 在默认情况下,pip 会将安装的包存放在 Python 环境的 site-packages 目录下,会使用到系统盘的内存。 当遇到系统盘的内存很小的时候,需要修改pip的全局缓存位置和全局安装包存放路径,可以极大的节省系统盘内存 详细步骤ÿ…...
ZooKeeper注册中心实现
具体步骤 安装ZooKeeper(启动端口占用,2181:客户端,8080:管理端)引入客户端依赖实现注册中心接口SPI补充ZooKeeper注册中心 引入依赖 <!-- zookeeper --> <dependency><groupId>org.a…...
PyTorch快速入门教程【小土堆】之DataLoader的使用
视频地址DataLoader的使用_哔哩哔哩_bilibili dataset数据集,相当于一副扑克,dataloader数据加载器相当于我们的手,选择摸几张牌,怎么摸牌 import torchvision# 准备的测试数据集 from torch.utils.data import DataLoader from …...
khadas edge2安装ubuntu22.04与ubuntu20.04 docker镜像
khadas edge2安装ubuntu22.04与ubuntu20.04 docker镜像 一、资源准备1.1 镜像文件1.2 刷机工具1.3 ubuntu20.04 docker镜像(具备demon无人机所需各种驱动) 二、开始刷机(安装ubuntu22.04系统)2.1 进入刷机状态2.2 刷机 三、docker…...
大数据面试笔试宝典之Kafka面试
1.Kafka 如何实现高吞吐率 Kafka 如何实现高吞吐率? 参考答案: 1)顺序读写...
新手SEO入门指南如何有效提升网站排名
内容概要 在进行搜索引擎优化(SEO)时,了解基本概念与重要性是首要步骤。SEO不仅仅是提升网站在搜索引擎中排名的手段,它还关乎用户体验和网站内容的质量。随着互联网的发展,越来越多的人意识到优秀的SEO策略能带来持续…...
【Redis】:初识Redis
1.1 盛赞 Redis Redis 是⼀种基于键值对(key-value)的 NoSQL 数据库,与很多键值对数据库不同的是,Redis 中的值可以是由 string(字符串)、hash(哈希)、list(列表…...
C-5 B样条曲线
C-5 B样条曲线 N i , 0 ( u ) { 1 , u i ≤ u < u i 1 0 , o t h e r s N_{i,0}(u)\left\{\begin{matrix} 1 , \quad u_i\le u <u_{i1} \\0 ,\quad others \qquad \quad\end{matrix}\right. Ni,0(u){1,ui≤u<ui10,others N i , p ( u ) u − u i u i p −…...
python安装
python安装 1.下载2.安装3.验证安装成功 1.下载 (1)下载网址:https://www.python.org/downloads/windows/ 进入后稍等一会,比较慢 (2)选择版本 2.安装 (1)双击或者以管理员身份运…...
游戏引擎学习第65天
回顾我们在模拟区域更改方面的进展 目前我们正在进行游戏的架构调整,目标是建立一个引擎架构。我们正在实施的一个关键变化是引入模拟区域的概念,这样我们可以创建非常大的游戏世界,而这些世界的跨度不必受限于单个浮点变量。 通过这种方式…...
代码随想录算法训练营第十六天-二叉树-513.找树左下角的值
左下角不是以为的左下角,而最后一层最左侧的节点也是就是说一个右叶子节点,也可能是最左下角,当然是在其左侧再无其它同级节点看视频讲解使用的递归与回溯方法,自己是完全想不到的,对这道题解法完全是脑袋空空 #inclu…...
力扣第122题:买卖股票的最佳时机 II
力扣第122题:买卖股票的最佳时机 II - C语言解法 题目描述 给定一个数组 prices,其中 prices[i] 是一支股票第 i 天的价格。你可以多次买入和卖出股票,求能够获得的最大利润。 注意: 你不能同时参与多笔交易(即必须…...