当前位置: 首页 > news >正文

【数据结构】算法的复杂度分析:让你拥有未卜先知的能力

在这里插入图片描述

  • 👑专栏内容:数据结构
  • ⛪个人主页:子夜的星的主页
  • 💕座右铭:日拱一卒,功不唐捐

文章目录

  • 一、前言
  • 二、时间复杂度
    • 1、定义
    • 2、大O的渐进表示法
    • 3、常见的时间复杂度
  • 三、空间复杂度
    • 1、定义
    • 2、常见的空间复杂度


一、前言

一个程序能用很多不同的算法来实现,那么到底那种算法是效率最高的呢?
对此我们有两种方法:

第一种是事后统计法,既在编写之后,通过计时,比较不同算法编写的程序的运行时间,以此确定算法效率的高低。但是该方法的缺陷很大,会受到测试环境、数据规模的影响。

第二种是事前分析法,即在编写之前,依据一些统计方法对算法进行粗略估算,大致的估算出该算法的时间复杂度和空间复杂度,通过对比复杂度来评判那种算法的效率更高。

在这里插入图片描述
可以说,学会了如何分析一个算法的复杂度,就拥有了未卜先知的能力,即在这个算法被写出来之前,就能大致评判出这个算法的好坏。

二、时间复杂度

1、定义

维基百科:在计算机科学中,算法的时间复杂度(time complexity)是一个函数,它定性描述该算法的运行时间。这是一个代表算法输入值的字符串的长度的函数。时间复杂度常用大O符号表述,不包括这个函数的低阶项和首项系数。使用这种方式时,时间复杂度可被称为是渐近的,亦即考察输入值大小趋近无穷时的情况。

在这里插入图片描述

额…具体来举个例子吧。

void Func1(int N)
{
int count = 0;
// n*n次
for (int i = 0; i < N ; ++ i)
{for (int j = 0; j < N ; ++ j){++count;}
}
// 2*n次
for (int k = 0; k < 2 * N ; ++ k)
{++count;
}
// 10次
int M = 10;
while (M--)
{++count;
}
printf("%d\n", count);
}

这个函数一共执行的基本操作次数为:F(n)=n2+2∗n+10F(n)=n^2+2*n+10F(n)=n2+2n+10
但是,我们计算复杂度的时候,不一定需要计算这么精确的执行次数,我们只需要计算出大概的执行次数就行了,所以这里我们应该使用大O的渐进表示法。那么什么是大O表示法呢?

2、大O的渐进表示法

大O符号(Big O notation):是用于描述函数渐进行为(趋向于特定值或无穷大)的数学符号。

上面函数一共执行的操作次数为:F(n)=n2+2∗n+10F(n)=n^2+2*n+10F(n)=n2+2n+10
学过极限的都知道,当nnn趋向于无穷的时候,n2+2∗n+10n^2+2*n+10n2+2n+10 中的2∗n2*n2n和10可以忽略不记。
所以用大O的渐进表示法,上面函数的时间复杂度应该为:O(n2)O(n^2)O(n2)
这里我们可以简单的总结一下方法:
1、用常数1取代运行时间中的所有加法常数。
2、在修改后的运行次数函数中,只保留最高阶项。
3、嵌套代码的复杂度等于嵌套内外代码复杂度的乘积。
4、如果最高阶项存在且不是1,则去除与这个项目相乘的常数。

3、常见的时间复杂度

  • O(1)O(1)O(1)

一般情况下,要算法的执行时间不随问题规模 n 的增加而增大,那么就是O(1)O(1)O(1)的时间复杂度

void Func(int n)
{int count = 0;for (int k = 0; k < 100; ++ k){++count;}printf("%d\n", count);
}

以上代码看似存在循环,但是仔细看,当循环到第十次的时候,这个循环就停止了。
所以上面的时间复杂度为 O(1)O(1)O(1)

  • O(logn)O(logn)O(logn)

类似于二分查找、幂运算都是O(logn)O(logn)O(logn)的时间复杂度

void Func(int n)
{int i=1;while (i <= n)  {i = i * 2;}
}

以上代码,变量 i 从 1 开始,每循环一次就乘以 2。当大于n时,循环结束。所以,假设一共循环了xxx次,那么我们就可以得到:2x=n2^x=n2x=nx=log2nx=log_2nx=log2n ,忽略掉底数2,则该时间复杂度为:O(logn)O(logn)O(logn)

在这里插入图片描述

为什么可以忽略掉底数?
高中学过的换底公式:logbn=logba∗loganlog_bn=log_ba*log_anlogbn=logbalogan
现在假设底数不是2是3,我们可以把log3nlog_3nlog3n写成log32∗log2nlog_32*log_2nlog32log2n,根据前面的规矩:如果最高阶项存在且不是1,则去除与这个项目相乘的常数。 而这里的log32log_32log32是个常数,可以直接去除。所以兜兜转转,最后的时间复杂度还是O(logn)O(logn)O(logn)

  • O(nlogn)O(nlogn)O(nlogn)
void Func(int n)
{for (int i = 1; i <= n; i++){int j = 1;while (j <= n){j = j * 2;}}
}

根据上面可以知道,这个循环里面的循环的复杂度是O(logn)O(logn)O(logn),而这个循环又要执行n次,所以算下来,它的时间复杂度是O(nlogn)O(nlogn)O(nlogn)

  • O(n)O(n)O(n)
void Func(int n)
{for (int i = 1; i <= n; i++){printf("我一共执行了n次哦!");}
}
  • O(n2)O(n^2)O(n2)

循环套循环,每个循环都是n次

void Func(int n)
{for (int i = 1; i <= n; i++){for (int j = 1; j <= n; j++){printf("我一共执行了n*n次哦!");}}
}
  • O(m∗n)O(m*n)O(mn)
void Func(int n,int m)
{for (int i = 1; i <= n; i++){for (int j = 1; j <= m; j++){printf("看的出来我有那些不一样吗?");}}
}

在这里插入图片描述
确实还有其他很多不同的时间复杂度,比如,O(2n)、O(n!)O(2^n)、O(n!)O(2n)O(n!)…但是这些时间复杂度都太高了,以至于高到很多计算机都承受不了,所以比较少见。

在这里插入图片描述
在这里插入图片描述

三、空间复杂度

1、定义

维基百科:在计算机科学中,一个算法或程序的空间复杂度定性地描述该算法或程序运行所需要的存储空间大小。空间复杂度是相应计算问题的输入值的长度的函数,它表示一个算法完全执行所需要的存储空间大小。和时间复杂度类似,空间复杂度通常也使用大O记号来渐进地表示例如O(n)、O(nlogn)O(n)、O(nlogn)O(n)O(nlogn)其中n用来表示输入的长度,该值可以影响算法的空间复杂度。

就像时间复杂度的计算不考虑算法所使用的空间大小一样,空间复杂度也不考虑算法运行需要的时间长短。

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

2、常见的空间复杂度

  • O(1)型O(1)型O(1)

无论 n 的值如何变化,代码在执行过程中开辟的内存空间是固定的

void Func(int n)
{int i = 0; int sum = 0;for (i = 1; i < n; i++){sum = sum + i;}
}

这段代码之开辟了sum和i两个int类型的空间,大小是固定的。
所以这段代码的空间复杂度为O(1)O(1)O(1)

  • O(n)型O(n)型O(n)

随着n的值的增大,开辟的空间也逐渐增大

long long Fac(size_t N)
{if(N == 0)return 1;return Fac(N-1)*N;
}

这段代码递归调用了N次,开辟了N个栈帧,每个栈帧使用了常数个空间。
所以这段代码的空间复杂度为O(N)O(N)O(N)

  • O(n2)型O(n^2)型O(n2)
  int** fun(int n) {int ** s = (int **)malloc(n * sizeof(int *));while(n--)s[n] = (int *)malloc(n * sizeof(int));return s;}

此处开辟的是一个二维数组,数组有n行,每行分别有1,2,3,…n列,所以是n(n+1)/2n(n + 1)/2n(n+1)/2个元素空间,空间复杂度为n2n^2n2

在这里插入图片描述

相关文章:

【数据结构】算法的复杂度分析:让你拥有未卜先知的能力

&#x1f451;专栏内容&#xff1a;数据结构⛪个人主页&#xff1a;子夜的星的主页&#x1f495;座右铭&#xff1a;日拱一卒&#xff0c;功不唐捐 文章目录一、前言二、时间复杂度1、定义2、大O的渐进表示法3、常见的时间复杂度三、空间复杂度1、定义2、常见的空间复杂度一、前…...

Linux根文件系统移植

目录 一、根文件系统 1.1根文件系统 1.2根文件系统内容 二、根文件系统移植 2.1BusyBox 2.2BusyBox的获取 2.3BusyBox的使用 2.4make menuconfig 2.5编译和安装 2.6修改根文件系统 一、根文件系统 1.1根文件系统 根文件系统是内核启动后挂载的第一个文件系统系统引…...

Three.js 无限平面快速教程【Plane】

Three.js 提供了 Plane 概念来表示在 3d 空间中无限延伸的二维表面。 这对于光标交互很有用&#xff0c;因此你可能需要了解如何设置此平面、将其可视化并根据需要进行调整。 推荐&#xff1a;使用 NSDT场景设计器 快速搭建 3D场景。 Three.js 的 Plane 文档很好而且准确&…...

在线预览PDF文件、图片,并且预览地址不显示文件或图片的真实路径。

实现在线预览PDF文件、图片&#xff0c;并且预览地址不显示文件或图片的真实路径。1、vue使用blob流在线预览PDF、图片&#xff08;包括jpg、png等格式&#xff09;。1、按钮的方法&#xff1a;2、方法详细&#xff1a;&#xff08;此方法可以在发起请求时携带token&#xff0c…...

Allegro如何设置导入Subdrawing可自由选择目录操作指导

Allegro如何设置导入Subdrawing可自由选择目录操作指导 用Allgro做PCB设计的时候,导入Subdrawing是非常常用的功能,在导入Subdrawing的时候,通常需要把Subdrawing文件放在需要导入PCB的相同目录下,不能自由选择,如下图 但是Allegro是支持自由选择目录的,只需按照下方的步…...

SpirngMVC执行原理--自学版

DispatcherServlet表示前置控制器&#xff0c;是整个SpringMVC的控制中心&#xff0c;用户发出请求&#xff0c;DispatcherServlet接收请求并拦截请求HandlerMapper为处理器映射。DispatcherServlet调用。HandlerMapping根据请求url查找HandlerHandlerExecution表示具体的Handl…...

获取savemodel的输入输出节点

saved_model_cli show --dir savemodels --all 结果&#xff1a; MetaGraphDef with tag-set: ‘serve’ contains the following SignatureDefs: signature_def[‘translation_signature’]: The given SavedModel SignatureDef contains the following input(s): inputs[‘i…...

《Learning to Reconstruct Botanical Trees from Single Images》学习从单幅图像重建植物树

读书报告下载https://download.csdn.net/download/weixin_43042683/87448211论文原文https://dl.acm.org/doi/10.1145/3478513.3480525论文视频https://www.bilibili.com/video/BV1cb4y127Vp/?fromseopage&vd_source5212838c127b01db69dcc8b2d27ca5171引言植物存在在室外与…...

vant 4 正式发布,支持暗黑主题,那么是如何实现的呢

2022年10月25日首发于掘金&#xff0c;现在同步到公众号。11. 前言大家好&#xff0c;我是若川。我倾力持续组织了一年多源码共读&#xff0c;感兴趣的可以加我微信 lxchuan12 参与。另外&#xff0c;想学源码&#xff0c;极力推荐关注我写的专栏《学习源码整体架构系列》&…...

MySQL的复制 二

复制是MySQL的一项功能&#xff0c;使服务器能够将更改从一个实例恢复到另一个实例 主服务器&#xff08;master&#xff09;将所有数据和结构更改记录到二进制日志中。二进制日志格式是基于语句的、基于行的和混合的。 从属服务器&#xff08;slave&#xff09;从主服务器请求…...

秒杀项目之秒杀商品展示及商品秒杀

目录前言一、登录方式调整二、生成秒杀订单2.1 绑定秒杀商品2.2 查看秒杀商品2.3 订单秒杀2.3.1 移除seata相关&#xff08;方便测压&#xff09;2.3.2 生成秒杀订单2.3.3 前端页面秒杀测试注意前言 博主博客用到的资源都会同步分享到资源包中 一、登录方式调整 第1步&#xf…...

教育行业需要什么样的数字产品?

数字化转型的浪潮已经席卷了各行各业&#xff0c;不仅出现在互联网、电商、建筑等行业&#xff0c;还应用在了教育行业。数字化的教育ERP软件能够在满足学校需求的基础上&#xff0c;帮助学校完善各类工作流程&#xff0c;提高工作效率。 对于一个拥有多个校区&#xff0c;上万…...

Spring MVC

一、Spring MVC介绍 a. Spring MVC是一个Web框架 b. Spring MVC是基于Servlet API构成的 MVC 是 Model View Controller 的缩写。 MVC 是⼀种思想&#xff0c;⽽ Spring MVC 是对 MVC 思想的具体实现。 学习Spring MVC目标&#xff1a; a.连接功能&#xff1a;将用户&#xff…...

类与对象(上)

类与对象(上) 1.面向过程和面向对象初步认识 C语言是面向过程的&#xff0c;关注的是过程&#xff0c;分析出求解问题的步骤&#xff0c;通过函数调用逐步解决问题。 C是基于面向对象的&#xff0c;关注的是对象&#xff0c;将一件事情拆分成不同的对象&#xff0c;靠对象之间…...

正确安装 torch_geometric库

step1&#xff1a; 查看pytorchcuda 版本 torch-scatter torch-sparse torch-cluster torch-spline-conv 这些关联包要与torch版本匹配。 import torch print(torch.__version__) print(torch.cuda.is_available()) torch.version.cuda或者 pip list查看版本 step2&#xff…...

【Unity VR开发】结合VRTK4.0:自身移动(滑动)

语录&#xff1a; 依山傍水房树间&#xff0c;行也安然&#xff0c;住也安然&#xff1b; 一条耕牛半顷田&#xff0c;收也凭天&#xff0c;荒也凭天&#xff1b; 雨过天晴驾小船&#xff0c;鱼在一边&#xff0c;酒在一边&#xff1b; 夜晚妻子话灯前&#xff0c;今也谈谈…...

G1垃圾回收器详解

文章目录前言一、思考问题二、官方文档三、基本介绍四、G1的内存模型五、G1的标记过程六、G1的垃圾回收1、G1过程梳理2、Young GC3、Mixed GC4、Full GC七、参数介绍八、典型问题1、疏散失败&#xff08;Evacuation Failure&#xff09;2、大对象分配&#xff08;Humongous All…...

tws耳机哪个牌子音质好?tws耳机音质排行榜

随着蓝牙耳机市场的不断发展&#xff0c;使用蓝牙耳机的人也逐渐增多&#xff0c;近年来更是超越有线耳机成为最火爆的数码产品之一。那么&#xff0c;tws耳机哪个牌子音质好&#xff1f;下面&#xff0c;我来给大家推荐几款音质好的tws耳机&#xff0c;可以当个参考。 一、南…...

TIA博途中DB数据块清零的具体方法示例

TIA博途中DB数据块清零的具体方法示例 TIA中数据块如何实现清零? 在TIA指令集内有多个移动指令可对DB块内数据进行清零处理。对于S7-1500 CPU或ET200SP CPU来说,可使用BLKMOV、FILL以及SCL的POKE_BLK指令。但是这些指令对DB块清零时,要求DB块必需为非优化DB。 对于优化的DB…...

iptables防火墙屏蔽指定ip的端口

因为需要测试客户端程序与hadoop服务器之间正常通信需要开通的端口, 所以在hadoop各服务器上使用iptables防火墙屏蔽了测试客户端程序的ip和所有端口。然后&#xff0c;根据报错信息提示的端口号来逐步放开直到能正常通信下载文件。 在服务器端屏蔽指定ip访问所有端口 #查看…...

脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)

一、数据处理与分析实战 &#xff08;一&#xff09;实时滤波与参数调整 基础滤波操作 60Hz 工频滤波&#xff1a;勾选界面右侧 “60Hz” 复选框&#xff0c;可有效抑制电网干扰&#xff08;适用于北美地区&#xff0c;欧洲用户可调整为 50Hz&#xff09;。 平滑处理&…...

【大模型RAG】Docker 一键部署 Milvus 完整攻略

本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装&#xff1b;只需暴露 19530&#xff08;gRPC&#xff09;与 9091&#xff08;HTTP/WebUI&#xff09;两个端口&#xff0c;即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...

【Go语言基础【13】】函数、闭包、方法

文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数&#xff08;函数作为参数、返回值&#xff09; 三、匿名函数与闭包1. 匿名函数&#xff08;Lambda函…...

基于Java+MySQL实现(GUI)客户管理系统

客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息&#xff0c;对客户进行统一管理&#xff0c;可以把所有客户信息录入系统&#xff0c;进行维护和统计功能。可通过文件的方式保存相关录入数据&#xff0c;对…...

20个超级好用的 CSS 动画库

分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码&#xff0c;而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库&#xff0c;可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画&#xff0c;可以包含在你的网页或应用项目中。 3.An…...

针对药品仓库的效期管理问题,如何利用WMS系统“破局”

案例&#xff1a; 某医药分销企业&#xff0c;主要经营各类药品的批发与零售。由于药品的特殊性&#xff0c;效期管理至关重要&#xff0c;但该企业一直面临效期问题的困扰。在未使用WMS系统之前&#xff0c;其药品入库、存储、出库等环节的效期管理主要依赖人工记录与检查。库…...

深入浅出WebGL:在浏览器中解锁3D世界的魔法钥匙

WebGL&#xff1a;在浏览器中解锁3D世界的魔法钥匙 引言&#xff1a;网页的边界正在消失 在数字化浪潮的推动下&#xff0c;网页早已不再是静态信息的展示窗口。如今&#xff0c;我们可以在浏览器中体验逼真的3D游戏、交互式数据可视化、虚拟实验室&#xff0c;甚至沉浸式的V…...

Windows 下端口占用排查与释放全攻略

Windows 下端口占用排查与释放全攻略​ 在开发和运维过程中&#xff0c;经常会遇到端口被占用的问题&#xff08;如 8080、3306 等常用端口&#xff09;。本文将详细介绍如何通过命令行和图形化界面快速定位并释放被占用的端口&#xff0c;帮助你高效解决此类问题。​ 一、准…...

GeoServer发布PostgreSQL图层后WFS查询无主键字段

在使用 GeoServer&#xff08;版本 2.22.2&#xff09; 发布 PostgreSQL&#xff08;PostGIS&#xff09;中的表为地图服务时&#xff0c;常常会遇到一个小问题&#xff1a; WFS 查询中&#xff0c;主键字段&#xff08;如 id&#xff09;莫名其妙地消失了&#xff01; 即使你在…...

RLHF vs RLVR:对齐学习中的两种强化方式详解

在语言模型对齐&#xff08;alignment&#xff09;中&#xff0c;强化学习&#xff08;RL&#xff09;是一种重要的策略。而其中两种典型形式——RLHF&#xff08;Reinforcement Learning with Human Feedback&#xff09; 与 RLVR&#xff08;Reinforcement Learning with Ver…...