数据结构(6)哈希表

news2024/10/16 15:39:18

一、哈希表

哈希表的基本概念

  1. 哈希函数

    • 哈希函数是将输入(键)转换为固定大小的输出(哈希值)的函数。这个输出通常是一个整数,表示在哈希表中的索引位置。
    • 理想的哈希函数应该能够均匀分布输入,以减少冲突的发生。
  2. 冲突

    • 当两个不同的键通过哈希函数计算得到相同的索引时,就会发生冲突。哈希表需要一种机制来处理这些冲突。
      • 开放地址法:在发生冲突时,寻找下一个空闲的位置来存储元素。
      • 链地址法:在每个索引位置维护一个链表,所有哈希到同一位置的元素都存储在这个链表中。

哈希表的操作

  • 插入:使用哈希函数计算键的索引,将值存储在该索引位置。
  • 查找:使用哈希函数计算键的索引,直接访问该索引位置以获取值。
  • 删除:使用哈希函数计算键的索引,找到对应的值并将其删除

哈希表的优缺点

优点

  • 平均情况下,插入、查找和删除操作的时间复杂度为 𝑂(1)O(1),非常高效。
  • 可以快速访问数据,适合需要频繁查找的场景。

缺点

  • 在最坏情况下(例如,所有键都发生冲突),时间复杂度可能退化为 𝑂(𝑛)O(n)。
  • 需要额外的内存来存储链表或处理冲突。
  • 哈希函数的设计和负载因子的管理是实现哈希表的关键。

二、算法

算法是为解决特定问题而设计的一系列明确的、有限的步骤和规则。

1. 算法设计原则
  • 正确性:确保语法正确,合法输入有合理输出,非法输入有明确处理,能够通过各种测试(尤其是边界条件测试)。
  • 可读性:算法设计应清晰易读,具备高内聚、低耦合的特性,便于维护与交流。
  • 健壮性:应对非法数据,算法能处理异常而不会崩溃,可通过异常处理机制(如 try-catchif-else)。
  • 高效率:在时间复杂度上尽量优化,确保随着输入规模增长,运行时间不成倍增加。
  • 低存储:空间复杂度要尽量优化,减少对内存的占用。
2. 时间复杂度的计算规则
  • 用常数 1 取代运行时间中的所有加法常数。
  • 保留运行时间函数中的最高阶项。
  • 去除最高阶项中的常数系数。
3. 常见时间复杂度类型
  • O(1): 常数时间,执行时间不受输入规模影响。
  • O(log n): 对数时间,典型于二分查找等算法。
  • O(n): 线性时间,执行时间随输入规模线性增长。
  • O(n log n): 常见于归并排序和快速排序的平均时间复杂度。
  • O(n^2): 二次时间,常见于双重嵌套循环。
  • O(2^n): 指数时间,通常用于组合问题。
  • O(n!): 阶乘时间,常见于全排列问题。
4. 时间复杂度增长顺序

O(1) < O(log n) < O(n) < O(n log n) < O(n^2) < O(n^3) < O(2^n) < O(n!) < O(n^n)

5. 空间复杂度
  • 与时间复杂度类似,空间复杂度衡量算法在内存中的占用情况,应尽量减少占用空间。

三、排序思想及时间复杂度

1. 冒泡排序(Bubble Sort)

排序思想: 冒泡排序通过多次比较相邻的元素,并交换位置,将最大(或最小)的元素“冒泡”到数组的一端。每一轮都会将剩余的最大(或最小)元素逐渐放到正确位置。不断重复这个过程,直到整个数组有序。

步骤

  1. 从数组的开头开始,比较相邻的两个元素。
  2. 如果前一个元素比后一个元素大,就交换它们。
  3. 完成一轮后,数组末端的元素是当前最大的。
  4. 继续对剩下的元素重复上述过程,直到没有元素需要交换。

时间复杂度

  • 最好情况:O(n)O(n)O(n)(如果数组已经有序,只需要一次遍历)
  • 平均情况:O(n2)O(n^2)O(n2)
  • 最坏情况:O(n2)O(n^2)O(n2)

2. 选择排序(Selection Sort)

排序思想: 选择排序通过反复选择剩余元素中的最小(或最大)元素,将它放在排序的正确位置。每次选择后,将该元素与当前排序范围中的第一个未排序元素交换位置。

步骤

  1. 找到数组中最小的元素,和第一个元素交换位置。
  2. 再从剩下的未排序部分中找到最小元素,和第二个元素交换位置。
  3. 不断重复这个过程,直到整个数组有序。

时间复杂度

  • 最好情况:O(n2)O(n^2)O(n2)
  • 平均情况:O(n2)O(n^2)O(n2)
  • 最坏情况:O(n2)O(n^2)O(n2)

(选择排序的比较次数与输入无关,始终是 O(n2)O(n^2)O(n2),即使数组已排序。)


3. 插入排序(Insertion Sort)

排序思想: 插入排序通过逐步构建有序序列,每次将未排序的元素插入到已排序部分的正确位置。适合数据量小或部分有序的场景。

步骤

  1. 从第二个元素开始,将它与前面的元素进行比较,找到合适的位置插入。
  2. 每插入一个元素后,已排序部分的长度增加一。
  3. 不断重复这个过程,直到所有元素都被插入正确位置。

时间复杂度

  • 最好情况:O(n)O(n)O(n)(如果数组已经有序,每次只需一次比较)
  • 平均情况:O(n2)O(n^2)O(n2)
  • 最坏情况:O(n2)O(n^2)O(n2)

(插入排序在数组基本有序时效率较高。)


4. 快速排序(Quick Sort)

排序思想: 快速排序通过分治法实现。它选择一个基准元素(通常是数组的第一个或最后一个元素),然后将数组划分为两个子数组:小于基准的元素放在左边,大于基准的放在右边。递归对左右子数组进行排序。

步骤

  1. 选择一个基准元素(pivot)。
  2. 将数组划分为两部分:小于基准的在左边,大于基准的在右边。
  3. 对左右子数组递归执行快速排序。
  4. 最终,左右子数组有序时,整个数组也有序。

时间复杂度

  • 最好情况:O(nlog⁡n)O(n \log n)O(nlogn)(每次划分时基准能均匀地将数组分成两半)
  • 平均情况:O(nlog⁡n)O(n \log n)O(nlogn)
  • 最坏情况:O(n2)O(n^2)O(n2)(当基准总是最小或最大元素,导致划分极不均匀)
总结时间复杂度对比:
  • 冒泡排序: 最好 O(n)O(n)O(n), 平均 O(n2)O(n^2)O(n2), 最坏 O(n2)O(n^2)O(n2)
  • 选择排序: 最好、平均、最坏均为 O(n2)O(n^2)O(n2)
  • 插入排序: 最好 O(n)O(n)O(n), 平均 O(n2)O(n^2)O(n2), 最坏 O(n2)O(n^2)O(n2)
  • 快速排序: 最好 O(nlog⁡n)O(n \log n)O(nlogn), 平均 O(nlog⁡n)O(n \log n)O(nlogn), 最坏 O(n2)O(n^2)O(n2)

四、查找方法的思想及时间复杂度

1. 顺序查找(线性查找)

查找思想: 顺序查找是最简单的查找方法,逐个检查数组中的每个元素,直到找到目标元素或检查完整个数组。适用于无序数组。

步骤

  1. 从数组的第一个元素开始,依次比较每个元素与目标元素是否相等。
  2. 如果找到相等的元素,返回该元素的下标;如果遍历到最后也没找到,返回失败或空值。

时间复杂度

  • 最好情况:O(1)O(1)O(1)(目标元素在数组的第一个位置)
  • 平均情况:O(n)O(n)O(n)(需要检查一半的元素)
  • 最坏情况:O(n)O(n)O(n)(目标元素在最后或不存在)

2. 二分查找(Binary Search)

查找思想: 二分查找只适用于有序数组。它通过每次将查找范围减半来寻找目标元素。该算法基于“分而治之”的思想,将查找问题递归地缩小至更小的子问题。

步骤

  1. 先将数组中间元素与目标元素比较。
  2. 如果相等,查找成功;如果目标元素小于中间元素,则在左半部分继续查找;如果目标元素大于中间元素,则在右半部分查找。
  3. 重复上述过程,直到找到目标元素或查找范围为空。

时间复杂度

  • 最好情况:O(1)O(1)O(1)(目标元素正好位于中间位置)
  • 平均情况:O(log⁡n)O(\log n)O(logn)
  • 最坏情况:O(log⁡n)O(\log n)O(logn)

(二分查找的高效性来源于每次都将问题规模缩小一半,因此具有对数时间复杂度。)


3. 哈希查找(Hash Search)

查找思想: 哈希查找通过使用哈希函数将关键字直接映射到数组的一个位置。理想情况下,哈希查找的时间复杂度为常数时间。哈希查找需要使用哈希表结构,并通过哈希函数进行查找和插入。哈希查找能非常快速地找到元素,但前提是哈希函数设计得当,冲突较少。

步骤

  1. 使用哈希函数计算出目标元素的哈希值。
  2. 在哈希表中查看该哈希值对应的位置是否存有目标元素。
  3. 如果有冲突(多个元素映射到同一位置),根据冲突解决方法继续查找(如链地址法、开放地址法等)。

时间复杂度

  • 最好情况:O(1)O(1)O(1)(没有冲突的情况下)
  • 平均情况:O(1)O(1)O(1)
  • 最坏情况:O(n)O(n)O(n)(当发生大量哈希冲突时,查找退化为线性查找)
查找方法总结与时间复杂度对比:
  • 顺序查找: 最好 O(1)O(1)O(1), 平均 O(n)O(n)O(n), 最坏 O(n)O(n)O(n)
  • 二分查找: 最好 O(1)O(1)O(1), 平均 O(log⁡n)O(\log n)O(logn), 最坏 O(log⁡n)O(\log n)O(logn)
  • 哈希查找: 最好 O(1)O(1)O(1), 平均 O(1)O(1)O(1), 最坏 O(n)O(n)O(n)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2119623.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大数据决策分析平台建设方案(可编辑的56页PPT)

引言&#xff1a;在当今信息爆炸的时代&#xff0c;大数据已成为企业决策制定、业务优化与市场洞察的重要驱动力。为了充分挖掘大数据的潜在价值&#xff0c;提升决策效率与精准度&#xff0c;构建一套高效、灵活、可扩展的大数据决策分析平台显得尤为重要。通过大数据分析平台…

佰朔资本:沪指跌0.23%,金融板块集体上扬,半导体等板块下挫

6日早盘&#xff0c;沪指盘中轰动回落&#xff0c;深证成指、创业板指弱势下探&#xff0c;上证50指数逆市上扬&#xff0c;场内超4400股飘绿。 到午间收盘&#xff0c;沪指跌0.23%报2782点&#xff0c;深证成指跌1.01%&#xff0c;创业板指跌1.29%&#xff0c;上证50指数微涨…

不小心删除丢失了所有短信?如何在 iPhone 上查找和恢复误删除的短信

不小心删除了一条短信&#xff0c;或者丢失了所有短信&#xff1f;希望还未破灭&#xff0c;下面介绍如何在 iPhone 上查找和恢复已删除的短信。 短信通常都是非正式和无关紧要的&#xff0c;但短信中可能包含非常重要的信息。因此&#xff0c;如果您删除了一些短信以清理 iPh…

LeetCode第414场周赛(第一题)

目录 一&#xff1a;题目&#xff1a;3280. 将日期转换为二进制表示 一&#xff1a;题目&#xff1a;3280. 将日期转换为二进制表示 给你一个字符串 date&#xff0c;它的格式为 yyyy-mm-dd&#xff0c;表示一个公历日期。 date 可以重写为二进制表示&#xff0c;只需要将年…

idea创建一个spring项目,并编写一个初级spring项目实战(全网最详细)

1.创建spring项目 创建后界面显示 2.再pom.xml文件中添加Spring框架依赖 <dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>6.0.10</version> </dependency> 注意&…

Spring中FactoryBean的高级用法实战

❃博主首页 &#xff1a; 「码到三十五」 &#xff0c;同名公众号 :「码到三十五」&#xff0c;wx号 : 「liwu0213」 ☠博主专栏 &#xff1a; <mysql高手> <elasticsearch高手> <源码解读> <java核心> <面试攻关> ♝博主的话 &#xff1a…

AT3340-6T杭州中科微BDS定位授时板卡性能指标

AT3340-6T是一款高性能多系统卫星定位安全授时板卡&#xff0c;可通过配置支持各个单系统的定位授时。 外观尺寸&#xff1a; 电气参数 应用领域&#xff1a; 通信基站授时 电力授时 广播电视授时 轨道系统授时 金融系统授时 其他授时应用 注意事项&#xff1a; 为了充分发挥…

nvidia-smi命令视图含义

第一部分&#xff1a;NVIDIA-SMI 标题 ---------------------------------------------------------------------------------------- | NVIDIA-SMI 555.42.06 Driver Version: 555.42.06 CUDA Version: 12.5 | ------------------------------------------------------------…

ML 系列:机器学习和深度学习的深层次总结(01)

​ 文章目录 一、说明二、人工智能和机器学习三、机器学习的类型四、结论 一、说明 欢迎学习机器学习系列。这门综合课程目前包括40个部分&#xff0c;指导您了解机器学习、统计和数据分析的基本概念和技术。以下是到目前为止涵盖的关键主题的简要概述&#xff1a; 1 机器学习…

C与汇编之间的相互调用(29)

1 先来看一下 基本的调用规则。 注意&#xff1a; 程序通过 r1 -r4 来保存 传递的参数&#xff0c;如果 超过了 4个参数怎么办&#xff0c; 那就 放到栈里面。 注意&#xff1a; 堆栈是满递减&#xff0c; FD。 子程序的返回结果 会放到R0 里面。 2 然后是 c 语言调用 汇编语言…

如何最好地制定自动化测试策略

尽管不能否认手动测试的价值&#xff0c;自动化测试的需求却在不断增长。自动化测试可以为公司和团队带来许多好处&#xff1a;时间效率高、覆盖面广。 如何最好地制定自动化测试策略呢&#xff1f; 在本文中&#xff0c;我将展示测试自动化策略的所有7个阶段中的一些最佳实践…

gpt4最新保姆级教程

如何使用 WildCard 服务注册 Claude3 随着 Claude3 的震撼发布&#xff0c;最强 AI 模型的桂冠已不再由 GPT-4 独揽。Claude3 推出了三个备受瞩目的模型&#xff1a;Claude 3 Haiku、Claude 3 Sonnet 以及 Claude 3 Opus&#xff0c;每个模型都展现了卓越的性能与特色。其中&a…

LLM - 理解 多模态大语言模型 (MLLM) 的发展与相关技术 (一)

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/142063880 免责声明&#xff1a;本文来源于个人知识与公开资料&#xff0c;仅用于学术交流&#xff0c;欢迎讨论&#xff0c;不支持转载。 多模态…

揭秘世界上那些同时横跨两大洲的国家

我们在《世界人口过亿的一级行政区分布》盘点全球是那些人口过亿的一级行政区。 现在我们介绍五个横跨两州的国家&#xff0c;并整理七大洲和这些国家的KML矢量数据分析分享给大家&#xff0c;如果你需要这些数据&#xff0c;请在文末查看领取方式。 世界上横跨两大洲的国家 …

【Python报错已解决】SyntaxError: positional argument follows keyword argument

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 前言一、问题描述1.1 报错示例1.2 报错分析1.3 解决思路 二、解决方法2.1 方法一&#xff1a;调整参数顺序2.2 步骤二…

excel分列

Excel中有这么几列&#xff0c;希望将每一列内容再分出3列&#xff1a; 可以通过以下步骤在 Excel 表格中将 B 到 F 列的内容拆分为每列的 3 列&#xff0c;分别为 pred_label、pred_score 和 pred_class&#xff1a; 确定数据结构&#xff1a;假设 B 列到 F 列中的内容都是按类…

洛谷 P10798 「CZOI-R1」消除威胁

题目来源于&#xff1a;洛谷 题目本质&#xff1a;贪心&#xff0c;st表&#xff0c;单调栈 解题思路&#xff1a;由于昨天联练习了平衡树&#xff0c;我就用平衡树STL打了个暴力&#xff0c;超时得了30分 这是暴力代码&#xff1a; #include<bits/stdc.h> using name…

小琳AI课堂:多模态模型的训练与应用

引言 大家好&#xff0c;这里是小琳AI课堂。今天我们将探讨一个热门且前沿的话题——多模态模型的训练与应用。让我们一起走进这个复杂而精致的艺术创作过程&#xff01; 训练关键步骤 1. 数据收集与预处理 准备工作&#xff1a;从多种来源和模态收集数据&#xff0c;如文…

苍穹外卖()

day1 软件开发整体介绍 软件开发流程&#xff1a;需求分析&#xff08;需求规格说明书、产品原型&#xff09;->设计&#xff08;UI设计、数据库设计、接口设计&#xff09;->编码&#xff08;项目代码&#xff0c;单元测试&#xff09;->测试&#xff08;测试用例、…

C++:入门篇(补充C语言中的不足)

前言 这篇文章是C的第一篇文章&#xff0c;主要是补充C语言中存在的不足而扩展的一些新的语法&#xff0c;有了这篇文章作为杂序&#xff0c;后面再介绍其他内容就要清晰地多 C&#xff1a;入门篇 一、namespace 命名空间&#xff08;一&#xff09;域的概念&#xff08;二&…