【图解数据结构】深入剖析时间复杂度与空间复杂度的奥秘

在这里插入图片描述
🌈个人主页:聆风吟
🔥系列专栏:图解数据结构、算法模板
🔖少年有梦不应止于心动,更要付诸行动。


文章目录

  • 一. ⛳️算法的定义
  • 二. ⛳️算法的特性
    • 2.1 🔔输入输出
    • 2.2 🔔输入输出
    • 2.3 🔔有穷性
    • 2.4 🔔确定性
    • 2.5 🔔可行性
  • 三. ⛳️算法设计要求
    • 3.1 🔔正确性
    • 3.2 🔔可读性
    • 3.2 🔔健壮性
    • 3.3 🔔时间效率高和存储量低
  • 四. ⛳️算法效率的度量方法
    • 4.1 🔔事后统计方法
    • 4.2 🔔事前分析估算方法
  • 五. ⛳️算法的复杂度
    • 5.1 🔔算法的复杂度的简单介绍
    • 5.2 🔔算法复杂度在面试中考察
  • 六. ⛳️算法的时间复杂度(重点)
    • 6.1 🔔算法的时间复杂度定义
    • 6.2 🔔大O的渐进表示法
    • 6.3 🔔常见的时间复杂度
    • 6.4 🔔最好情况、最坏情况与平均情况
  • 七. ⛳️算法的空间复杂度
  • 📝全文总结

一. ⛳️算法的定义

    算法是解决特定问题求解步骤的描述,在计算机中表现为指令的有限序列,并且每条指令表示一个或多个操作



二. ⛳️算法的特性

    算法具有五个基本特性:输入、输出、有穷性、确定性和可行性。

2.1 🔔输入输出

    算法具有零个或多个输入,尽管对于大多数算法来说,输入参数都是有必要的,但对于个别情况,如打印"hello world!"这样的代码,不需要任何输入参数,因此算法的输入可以是零个。

2.2 🔔输入输出

    算法至少有一个或多个输出,算法是一定需要输出的,不需要输出,你用这个算法干嘛呢?输出的形式可以打印输出,也可以是返回一个或多个值等。

2.3 🔔有穷性

    有穷性:是指算法在执行有限的步骤之后,自动结束而不会出现无限循环,并且每一个步骤都在可接受的时间内完成

2.4 🔔确定性

    确定性:算法的每一步骤都具有确定的含义,不会出现二义性。算法在一定条件下,只有一条执行的路径,相同的输入只能有唯一的输出结果。算法的每一步骤都被精确定义而无歧义。

2.5 🔔可行性

    可行性:算法的每一步都必须是可行的,也就是说,每一步都能够通过执行有限次数完成



三. ⛳️算法设计要求

    算法不是唯一的。也就是说,解决同一个问题,可以有多种解决问题的算法。通常为了设计一个 “好” 的算法应考虑达到一下目标:
在这里插入图片描述

3.1 🔔正确性

    正确性:算法的正确性是指算法至少应该具有输入、输出和加工处理无歧义性,能够得到问题的正确答案。但是算法的 “ 正确 ” 一词在用法上通常有很大差别,大体分为一下四个层次:

  1. 算法程序没有语法错误;
  2. 算法程序对于合法的输入数据能够产生满足要求的输入结果;
  3. 算法程序对于非法的输入数据能够得出满足规格说明的结果;
  4. 算法程序对于精心选择的,甚至刁难的测试数据都有满足要求的输出结果。

对于这四层含义,层次 1的要求最低,但仅仅没有语法错误实在谈不上是好算法。这就是如同仅仅解决温饱,不算是生活幸福一样。而层次 4是最难实现的,我们几乎不可能逐一验证所有的输入都得到正确的结果。所以一般情况下,我们通常把层次 3作为衡量一个算法算法是否合格的标准。

3.2 🔔可读性

    可读性:算法的另一个目的是为了便于阅读,来理解和交流。可读性高有助于人们理解算法,晦涩难懂的算法往往隐含错误,不易被发现,并且难以调试和修改。

3.2 🔔健壮性

    健壮性:当输入数据不合法时,算法也能做出相关处理而不是产生异常或莫名其妙的结果

3.3 🔔时间效率高和存储量低

    时间效率指的是算法的执行时间。对于同一个问题,如果有多个算法能够解决,执行时间短的算法效率高,执行时间长的效率低。存储量需求指的是算法在执行过程中需要的最大空间,主要指算法程序运行时所占用的内存或外部硬盘存储空间。因此,设计算法时应尽量满足时间效率高和存储量低的需求。



四. ⛳️算法效率的度量方法

    刚才我们提到了设计算法要提高效率。这里的效率大都指算法的执行时间。算法的执行时间需要依据该算法编制的程序在计算机上运行时所消耗的时间来度量的。而度量一个程序的执行时间通常有有两种方法 —— 事后统计方法和事前分析估算方法。

4.1 🔔事后统计方法

    事后统计方法:这种方法主要是通过设计好的测试程序和数据,利用计算机计时器对不同的算法编制的程序的运行时间进行比较,从而确定算法效率的高低。但是这种方法明显是有很大的缺陷:

  • 必须要依据算法事先编制好程序,这通常要需要花费大量时间和精力。如果编制出来发现它根本就是一团很糟糕的算法,那不就是竹篮打水一场空了吗?
  • 时间的比较依赖计算机硬件和软件等环境因素的影响,有时会掩盖算法本身的优劣。
  • 算法的测试数据设计困难,并且程序的运行时间往往还与测试数据的规模有很大关系,效率高的算法在小的测试数据面前往往得不到体现。

基于事后统计方法有这样那样的缺陷,我们一般不予以采纳,而是采用另一种事前分析估算方法。

4.2 🔔事前分析估算方法

    事前分析估算方法:在计算机程序编制前,依据统计方法对算法进行估算。经过分析我们可以发现,一个用高级语言程序语言编写的程序在计算机上运行时所消耗的时间取决于一下因素:
在这里插入图片描述解析
    第(1)条是一个好算法的根本,第(2)条要有软件来支持,第(4)条要看硬件性能。因此,抛开这些与计算机硬件、软件有关的因素,一个程序的运行时间,依赖于算法的好坏和问题的输入规模。所谓问题输入规模是指输入量的多少。



五. ⛳️算法的复杂度

5.1 🔔算法的复杂度的简单介绍

    算法在编写成可执行程序后,运行时需要耗费时间资源和空间(内存)资源 。因此衡量一个算法的好坏,一般是从时间和空间两个维度来衡量的,即时间复杂度和空间复杂度

    时间复杂度主要衡量一个算法的运行快慢,而空间复杂度主要衡量一个算法运行所需要的额外空间。在计算机发展的早期,计算机的存储容量很小。所以对空间复杂度很是在乎。但是经过计算机行业的迅速发展,计算机的存储容量已经达到了很高的程度。所以我们如今已经不需要再特别关注一个算法的空间复杂度。


5.2 🔔算法复杂度在面试中考察

在这里插入图片描述

由此可以看出算法复杂度的重要性,所以说同学们下面的内容一定要好好学哦。言归正传接下来让我们开始具体讲解时间复杂度和空间复杂度。



六. ⛳️算法的时间复杂度(重点)

6.1 🔔算法的时间复杂度定义

    在计算机科学中,算法的时间复杂度是一个函数,它定量描述了该算法的运行时间。一个算法执行所耗费的时间,从理论上说,是不能算出来的,只有你把你的程序放在机器上跑起来,才能知道。但是我们需要每个算法都上机测试吗?是可以都上机测试,但是这很麻烦,所以才有了时间复杂度这个分析方式。一个算法所花费的时间与其中语句的执行次数成正比例,算法中的基本操作的执行次数,为算法的时间复杂度
即:找到某条基本语句与问题规模N之间的数学表达式,就是算出了该算法的时间复杂度

  • 示例:请计算一下Func1中++count语句总共执行了多少次?
void Func1(int N)
{int count = 0;for (int i = 0; i < N; ++i){for (int j = 0; j < N; ++j){++count;//执行 N*N 次}}for (int k = 0; k < 2 * N; ++k){++count;//执行 2*N 次}int M = 10;while (M--){++count;//执行 10次}printf("%d\n", count);
}

在这里插入图片描述

     实际中我们计算时间复杂度时,我们其实并不一定要计算精确的执行次数,而只需要大概执行次数,那么我们就可以使用大O的渐进表示法。看到这估计有同学该问了大O的渐进表示法是什么,它又是如何推导的呢?且听我慢慢道来,让我们继续接着向下面学习。


6.2 🔔大O的渐进表示法

大O符号(big O notation):是用于于描述函数渐进行为的数学符号

推导大O阶方法:

(1)用常数1取代运行时间中的所有加法常数。
(2) 在修改后的运行次数函数中,只保留最高阶项。
(3)如果最高阶项存在且其系数不是1,则去除与这个项相乘的系数。得到的结果就是大O阶。

结合上面示例: 使用大O的渐进表示法以后,Func1的时间复杂度为:
在这里插入图片描述

通过上面我们会发现大O的渐进表示法去掉了那些对结果影响不大的项,简洁明了的表示出了执行次数


6.3 🔔常见的时间复杂度

  常见的时间复杂度如下表所示:
在这里插入图片描述注:对数在文本中不好表示,以 2 为底的对数通常简写为(logn)

  常用的时间复杂度所耗费的时间从小到大依次是:

O(1) < O(logn) < O(n) < O(nlogn) < O(2n) < O(n3) < O(2n) < O(n!)

在这里插入图片描述


6.4 🔔最好情况、最坏情况与平均情况

另外有些算法的时间复杂度存在最好、平均和最坏情况:

  • 最坏情况:任意输入规模的最大运行次数(上界)
  • 平均情况:任意输入规模的期望运行次数
  • 最好情况:任意输入规模的最小运行次数(下界)

例如:在一个长度为N数组中搜索一个数据x
      最好情况:1次找到
      最坏情况:N次找到
      平均情况:N/2次找到
在实际中 一般在没有特殊说明的情况下,关注的都是算法的最坏运行情况,所以数组中搜索数据时间复杂度为O(N)。



七. ⛳️算法的空间复杂度

算法空间复杂度的定义:

  • 空间复杂度也是一个数学表达式,是对一个算法在运行过程中额外临时占用存储空间大小的量度
  • 空间复杂度不是程序占用了多少bytes的空间,因为这个也没太大意义,所以 空间复杂度算的是变量的个数
  • 空间复杂度计算规则基本跟时间复杂度类似,也使用大O渐进表示法。

注意: 函数运行时所需要的栈空间(存储参数、局部变量、一些寄存器信息等)在编译期间已经确定好了,因此空间复杂度主要通过函数在运行时候显式申请的额外空间来确定。



📝全文总结

本文主要讲解:

  1. 算法的定义:算法是解决特定问题求解步骤的描述,在计算机中表现为指令的有限序列,并且每条指令表示一个或多个操作。
  2. 算法的特性:有穷性、确定性、可行性、输入、输出。
  3. 算法的设计要求:正确性、可读性、健壮性、高效率和低存储量需求。
  4. 算法的度量方法:事后统计方法、事前分析估算方法。
  5. 推导大O阶
  6. 时间复杂度
  7. 空间复杂度

     今天的干货分享到这里就结束啦!如果觉得文章还可以的话,希望能给个三连支持一下,聆风吟的主页还有很多有趣的文章,欢迎小伙伴们前去点评,您的支持就是作者前进的最大动力!
在这里插入图片描述

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

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

相关文章

MySQL面试题2

文章目录 面试题 (9-15) 面试题 (9-15) 09&#xff09;查询学过「张三」老师授课的同学的信息 SELECT s.*,c.cname,t.tname FROM t_mysql_teacher t,t_mysql_student s,t_mysql_course c,t_mysql_score sc WHERE t.tidc.tid and c.cidsc.cid and sc.sids.sid and tname ‘张…

网站建设网络设计营销类网站eyouCMS模板(PC+WAP)

模板介绍&#xff1a; 本模板自带eyoucms内核&#xff0c;无需再下载eyou系统&#xff0c;原创设计、手工书写DIVCSS&#xff0c;完美兼容IE7、Firefox、Chrome、360浏览器等&#xff1b;主流浏览器&#xff1b;结构容易优化&#xff1b;多终端均可正常预览。

【面试合集】说说微信小程序的登录流程?

面试官&#xff1a;说说微信小程序的登录流程&#xff1f; 一、背景 传统的web开发实现登陆功能&#xff0c;一般的做法是输入账号密码、或者输入手机号及短信验证码进行登录 服务端校验用户信息通过之后&#xff0c;下发一个代表登录态的 token 给客户端&#xff0c;以便进行…

线程安全2

文章目录 锁的可重入性死锁内存可见性引起的线程安全 锁的可重入性 直观来看这个代码不能运行 为啥没有出现阻塞&#xff1f; 当前由于是同一个线程&#xff0c;此时的锁对象&#xff0c;就知道了第二次加锁的线程&#xff0c;就是持有锁的线程&#xff0c;第二次操作&#xff…

前端开发必备:掌握正则表达式,轻松应对复杂的表单验证

前言 在前端开发中&#xff0c;经常需要处理 URL 地址、校验手机号合法性、提取域名等。正则表达式是一种常用的工具。通过使用正则表达式&#xff0c;我们可以对用户输入进行有效的验证&#xff0c;确保数据的合法性和完整性。本文将介绍一些常见的正则表达式&#xff0c;帮助…

使用JDK自带的jvisualvm工具查看堆dump文件【回顾】

JDK自带的jvisualvm的使用 打开方式&#xff1a; 直接命令行输入&#xff1a;jvisualvm ,然后回车​​​​​​​ ​​ 或者去jdk的bin目录下找到打开 安装visual GC插件 检测死锁 再点击“死锁 dump”就可以看到死锁的线程信息了&#xff1b;

Vulnhub靶机:driftingblues 4

一、介绍 运行环境&#xff1a;Virtualbox 攻击机&#xff1a;kali&#xff08;10.0.2.15&#xff09; 靶机&#xff1a;driftingblues4&#xff08;10.0.2.20&#xff09; 目标&#xff1a;获取靶机root权限和flag 靶机下载地址&#xff1a;https://www.vulnhub.com/entr…

【Python数据分析系列】实现txt文件与列表(list)相互读写转换(源码+案例)

这是Python数据分析系列原创文章&#xff0c;我的第199篇原创文章。 一、问题 平时在做数据分析或者程序开发的时候&#xff0c;需要将中间的一些结果或最后的处理结果保存下来&#xff0c;比如保存为txt格式的文本文件&#xff0c;这就涉及列表与txt之间的一种读取和写入操作…

spring cloud feign demo

1. 工程结构 2. 父工程pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.…

JVM实战(17)——模拟对象晋升

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 学习必须往深处挖&…

将PDF发票转换为excel、xml结构化数据的完美解决方案

随着电子发票的普及&#xff0c;越来越多的企业和个人开始使用PDF格式的电子发票。然而&#xff0c;有时我们需要将电子发票转换为XML格式以便于处理和分析。本文将介绍如何将收到的PDF发票下载为excel、xml文件。首先&#xff0c;我们需要明确一点&#xff0c;PDF是一种基于图…

C#编程-属性和反射

属性和反射 属性是将元数据信息和行为添加到应用程序代码中的简单技术。属性是允许您将声明信息添加到程序的元素。此声明信息在运行时用途广泛,可使用应用程序开发工具在设计时使用。 介绍属性 对象是由其属性值描述的。例如,汽车可以使用它的构造、型号或颜色来描述。类似…

ART-Adversarial Robustness Toolbox检测AI模型及对抗攻击的工具

一、工具简介 Adversarial Robustness Toolbox 是 IBM 研究团队开源的用于检测模型及对抗攻击的工具箱&#xff0c;为开发人员加强 AI模型被误导的防御性&#xff0c;让 AI 系统变得更加安全&#xff0c;ART支持所有流行的机器学习框架 &#xff08;TensorFlow&#xff0c;Ker…

SpringMVC RESTful案例

文章目录 1、准备工作2、功能清单3、具体功能&#xff1a;访问首页a>配置view-controllerb>创建页面 4、具体功能&#xff1a;查询所有员工数据a>控制器方法b>创建employee_list.html 5、具体功能&#xff1a;删除a>创建处理delete请求方式的表单b>删除超链接…

Web3社交治理:用户参与决策的新模式

Web3时代的到来不仅仅带来了区块链技术的创新&#xff0c;还为社交治理带来了全新的模式。传统社交平台上的决策权通常集中在平台的运营方&#xff0c;而Web3社交治理的兴起意味着用户能够更直接地参与到社交平台的决策过程中。本文将深入探讨Web3社交治理的背景、工作原理以及…

帆软笔记-决策表报对象使用(两表格联动)

效果描述如下&#xff1a; 数据库中有个聚合商表&#xff0c;和一个储能表&#xff0c;储能属于聚合商&#xff0c;桩表中有个字段是所属聚合商。 要求帆软有2个表格&#xff0c;点击某个聚合商&#xff0c;展示指定的储能数据。 操作&#xff1a; 帆软选中表格单元&#xf…

SpringBoot 入门教程

1.复习SSM项目中&#xff0c;用spring&#xff0c;mybatis,springmvc这三个框架整合的项目。 SSM项目的所有类&#xff0c;这是用SSM整合一个搜索书籍种类和呈现的前端和后端的ssm的小项目。 2.springboot如何去开发这个页面&#xff1a; 新建springboot项目&#xff0c;勾选对…

MeshLab生成分形地形

文章目录 分型地形脊状多重分形其他地形 分型地形 分形地形是一种较为复杂的几何对象&#xff0c;MeshLab提供了下列五种地形生成算法&#xff0c;并且贴心地给出了每种算法相对较好的参数。 算法SeedOctaves缺项性分形增量偏移增益fBM(fractal Brownian Motion)11021.2--Sta…

【WPF.NET开发】WPF中的版式

本文内容 改进的文本质量和性能丰富的版式增强的国际文本支持增强的字体支持新的文本应用程序编程接口 (API) 本主题介绍 WPF 的主要版式功能。 这些功能包括改进的文本呈现质量和性能、OpenType 版式支持、增强的国际文本、增强的字体支持和新的文本应用程序编程接口 (API)。…