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

【数据结构】_复杂度

目录

1. 算法效率

2. 时间复杂度

2.1 时间复杂度概念

2.2 准确的时间复杂度函数式

2.3 大O渐进表示法

2.4 时间复杂度的常见量级

2.5 时间复杂度示例

3. 空间复杂度

3.1 空间复杂度概念

3.2 空间复杂度示例


1. 算法效率

一般情况下,衡量一个算法的好坏是从时间和空间两个维度来衡量的。

时间复杂度主要衡量一个算法的运行快慢,空间复杂度主要衡量一个算法运行需要的额外空间。

2. 时间复杂度

2.1 时间复杂度概念

在计算机科学中算法的时间复杂度是一个函数,一个算法所花费的时间与其中语句的执行次数成比例,算法中的基本操作的执行次数,为算法的时间复杂度

即:找到某条基本语句与问题规模N之间的数学表达式,就是算出了该算法的时间复杂度。

注:不能直接用运行时间来定义一个算法的时间复杂度,一个算法的运行时间与硬件的配置存在联系,同样一个算法无法算出准确时间。而时间复杂度与具体机器无关。

2.2 准确的时间复杂度函数式

对于以下代码:

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

F(N)=N*N+2*N+10,这是准确的时间复杂度函数式,计算的结果是算法运行的准确次数。

但其意义并不大,计算时间复杂度时,并不一定要计算出准确的执行次数,只需要大概执行次数表示算法效率所在量级即可,故而引进大O的渐进表示法。

2.3 大O渐进表示法

当不方便在算法之间比较准确时间复杂度函数式时,使用大O的渐进表示法对其进行简化。

简单而言,大O渐进表示法是估算一个算法的数量级而非准确数值。

具体而言,推导大O阶方法:

(1)用常数1取代运行时间中的所有加法常数;(O(1)代表常数次,而非1次)

(2)在修改后的运行次数函数中,只保留最高阶项

(3)如果最高阶项存在且不是1,则去除与这个项目相乘的常数

得到的结果就是大O阶。

2.4 时间复杂度的常见量级

按数量级递增排列,常见的时间复杂度有:

O(1)<=O(log N)<=O(N)<=O(Nlog N)<=O(n^2)<=O(n^3)<=...<=n^k<=O(2^n)

随着问题规模N的不断增大,上述时间复杂度不断增大,算法的执行效率越低,若复杂度超过O(N^3)则该算法效率已经非常低,没有运行的必要。

2.5 时间复杂度示例

示例1:

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

时间复杂度为O(N)=N;(时间复杂度准确函数式:F(N)=2*N+10)

示例2:

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

当N、M大小未知时,时间复杂度表示为O(N+M);

当N远大于M时,时间复杂度表示为O(N);

当M远大于N时,时间复杂度表示为O(M);

当N、M属于一个量级时,时间复杂度表示为O(M)或O(N)均可;

示例3:

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

时间复杂度表示为O(1);

示例4:

const char * strchr ( const char * str, int character );

该算法的时间复杂度最好1次,最坏N次,时间复杂度一般看最坏情况,为O(N);

注:(1)strstr为字符串查找函数,详细内容见下文:

【C语言】_字符串查找函数strstr_c语言查找字符-CSDN博客文章浏览阅读147次,点赞9次,收藏5次。注:关于上文strstr函数的模拟实现,还有很大优化空间,包括但不限于KMP算法,本篇仅实现简单的匹配功能,暂不考虑效率。(2)待匹配字符串str2需逐字符在str1中进行对应查找匹配,将用于遍历str2的指针变量记为s2,类型为char*;(3)str2需与str1中的字符逐字符进行匹配,需设遍历str1的指针变量,记为s1,类型为char*;(1)返回值为第一次匹配的str2在str1中的位置,记为cur,类型为char*;strstr函数功能:在str1中查找str2;若未找到,则返回空指针;_c语言查找字符https://blog.csdn.net/m0_63299495/article/details/145165702https://blog.csdn.net/m0_63299495/article/details/145165702https://blog.csdn.net/m0_63299495/article/details/145165702(2)在算法时间复杂度计算时,一般会采取保守估计,将最坏情况作为时间复杂度。

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

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

示例5:(冒泡排序)

void BubbleSort(int* a, int n)
{assert(a);for (size_t end = n; end > 0; --end){int exchange = 0;for (size_t i = 1; i < end; ++i){if (a[i - 1] > a[i]){Swap(&a[i - 1], &a[i]);exchange = 1;}}if (exchange == 0)break;}
}

时间复杂度准确函数式式F(N) = N-1+N-2+...+2+1=((N-1+1)*(N-1))/2=(N*(N-1))/2;

故时间复杂度为O(N^2);

示例6:(二分查找)

int BinarySearch(int* a, int n, int x)
{assert(a);int begin = 0;int end = n - 1;while (begin < end){int mid = begin + ((end - begin) >> 1);if (a[mid] < x)begin = mid + 1;else if (a[mid] > x)end = mid;elsereturn mid;}return -1;
}

二分查找用于有序数组的查找,查找区间变化为N -> N/2 -> N/2/2 -> N/2/2/2 -> ...  -> N/2/2/.../2

① 查找的最好情况为查找一次即找到,即O(1);

② 查找的最坏情况为查找区间只剩一个数或没找到,即 N/2/2/.../2=1,假设查找了x次,即2^x=N,求得最坏情况为O(log N)   ,故时间复杂度为O(log N) ;

注:在时间复杂度的表示中,log₂N 可简写为 log N,不准确表达也有lg N。

在时间复杂度表示中,默认 log N 的底数为2。

示例7:(阶乘)

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

Fac(N)调用Fac(N-1), Fac(N-1)调用Fac(N-2)...Fac(2)调用Fac(1),Fac(1)调用Fac(0),共调用N+1次,且单次调用复杂度为O(1),递归的时间复杂度是所有递归调用次数的累加:

故时间复杂度为O(N);

示例8:

long long Fib(size_t N)
{if (N < 3)return 1;return Fib(N - 1) + Fib(N - 2);
}

 复杂度具体函数可以近似为Fib(N)=2^0 + 2^1 + 2^2 + ...... + 2^(N-2) = 2^(N-1) - 1:

时间复杂度为O(2^N);(仅有理论意义,实际几乎不用)

注:当N不是非常大时,通常使用循环代替递归计算斐波那契数列,可降低时间复杂度为O(N):

long long Fib(size_t N) {long long f1 = 1;long long f2 = 2;long long f3 = 0;for (size_t i = 3; i <= N; i++) {f3 = f1 + f2;f1 = f2;f2 = f3;}return f3;
}

3. 空间复杂度

3.1 空间复杂度概念

空间复杂度也是一个数学表达式,是对一个算法在运行过程中临时占用存储空间大小的量度。

同时间复杂度一样,具体占用了多少字节的空间大小没有意义,也采用大O渐进表示法,空间复杂度计算的是变量个数

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

3.2 空间复杂度示例

示例1:

void BubbleSort(int* a, int n)
{assert(a);for (size_t end = n; end > 0; --end){int exchange = 0;for (size_t i = 1; i < end; ++i){if (a[i - 1] > a[i]){Swap(&a[i - 1], &a[i]);exchange = 1;}}if (exchange == 0)break;}
}

该程序开辟了常数个额外空间,空间复杂度是O(1);

示例2:

long long* Fibonacci(size_t n)
{if (n == 0)return NULL;long long* fibArray = (long long*)malloc((n + 1) * sizeof(long long));fibArray[0] = 0;fibArray[1] = 1;for (int i = 2; i <= n; ++i){fibArray[i] = fibArray[i - 1] + fibArray[i - 2];}return fibArray;
}

空间复杂度是O(N);

示例3:

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

递归调用了N+1次,量级为N,开辟了N个栈帧,每个栈帧使用了常数个空间,空间复杂度为O(N);

示例4:

long long Fib(size_t N)
{if (N < 3)return 1;return Fib(N - 1) + Fib(N - 2);
}

(时间是累积的;空间不累积,可以重复利用)空间复杂度是O(N); 

相较于时间复杂度,空间复杂度更为简单,通常情况下最常见的空间复杂度有O(1)、O(N)(一维数组)、O(N^2)(二维数组);

相关文章:

【数据结构】_复杂度

目录 1. 算法效率 2. 时间复杂度 2.1 时间复杂度概念 2.2 准确的时间复杂度函数式 2.3 大O渐进表示法 2.4 时间复杂度的常见量级 2.5 时间复杂度示例 3. 空间复杂度 3.1 空间复杂度概念 3.2 空间复杂度示例 1. 算法效率 一般情况下&#xff0c;衡量一个算法的好坏是…...

pytorch实现循环神经网络

人工智能例子汇总&#xff1a;AI常见的算法和例子-CSDN博客 PyTorch 提供三种主要的 RNN 变体&#xff1a; nn.RNN&#xff1a;最基本的循环神经网络&#xff0c;适用于短时依赖任务。nn.LSTM&#xff1a;长短时记忆网络&#xff0c;适用于长序列数据&#xff0c;能有效解决…...

Java 16进制 10进制 2进制数 相互的转换

在 Java 中&#xff0c;进行进制之间的转换时&#xff0c;除了功能的正确性外&#xff0c;效率和安全性也很重要。为了确保高效和相对安全的转换&#xff0c;我们通常需要考虑&#xff1a; 性能&#xff1a;使用内置的转换方法&#xff0c;如 Integer.toHexString()、Integer.…...

力扣动态规划-14【算法学习day.108】

前言 ###我做这类文章一个重要的目的还是给正在学习的大家提供方向&#xff08;例如想要掌握基础用法&#xff0c;该刷哪些题&#xff1f;建议灵神的题单和代码随想录&#xff09;和记录自己的学习过程&#xff0c;我的解析也不会做的非常详细&#xff0c;只会提供思路和一些关…...

数据结构day02

1 线性表的定义和基本操作 1.1 线性表的定义 分析&#xff1a; 1.1.1 问题一&#xff1a;我们为什么探讨线性表的定义和基本操作 在研究数据结构时&#xff0c;需要重点关注三个方面&#xff1a;逻辑结构、物理结构以及数据的运算。在本节内容里&#xff0c;我们首先来介绍线…...

随笔 | 写在一月的最后一天

. 前言 这个月比预想中过的要快更多。突然回看这一个月&#xff0c;还有点不知从何提笔。 整个一月可以总结为以下几个关键词&#xff1a; 期许&#xff0c;保持期许出现休息 . 期许 关于期许&#xff0c;没有什么时候比一年伊始更适合设立目标和计划的了。但令人惭愧的…...

JVM方法区

一、栈、堆、方法区的交互关系 二、方法区的理解: 尽管所有的方法区在逻辑上属于堆的一部分&#xff0c;但是一些简单的实现可能不会去进行垃圾收集或者进行压缩&#xff0c;方法区可以看作是一块独立于Java堆的内存空间。 方法区(Method Area)与Java堆一样&#xff0c;是各个…...

一文读懂fgc之cms

一文读懂 fgc之cms-实战篇 1. 前言 线上应用运行过程中可能会出现内存使用率较高&#xff0c;甚至达到95仍然不触发fgc的情况&#xff0c;存在内存打满风险&#xff0c;持续触发fgc回收&#xff1b;或者内存占用率较低时触发了fgc&#xff0c;导致某些接口tp99&#xff0c;tp…...

MYSQL 商城系统设计 商品数据表的设计 商品 商品类别 商品选项卡 多表查询

介绍 在开发商品模块时&#xff0c;通常使用分表的方式进行查询以及关联。在通过表连接的方式进行查询。每个商品都有不同的分类&#xff0c;每个不同分类下面都有商品规格可以选择&#xff0c;每个商品分类对应商品规格都有自己的价格和库存。在实际的开发中应该给这些表进行…...

HTB:Administrator[WriteUP]

目录 连接至HTB服务器并启动靶机 信息收集 使用rustscan对靶机TCP端口进行开放扫描 将靶机TCP开放端口号提取并保存 使用nmap对靶机TCP开放端口进行脚本、服务扫描 使用nmap对靶机TCP开放端口进行漏洞、系统扫描 使用nmap对靶机常用UDP端口进行开放扫描 使用nmap对靶机…...

开源项目Umami网站统计MySQL8.0版本Docker+Linux安装部署教程

Umami是什么&#xff1f; Umami是一个开源项目&#xff0c;简单、快速、专注用户隐私的网站统计项目。 下面来介绍如何本地安装部署Umami项目&#xff0c;进行你的网站统计接入。特别对于首次使用docker的萌新有非常好的指导、参考和帮助作用。 Umami的github和docker镜像地…...

FBX SDK的使用:基础知识

Windows环境配置 FBX SDK安装后&#xff0c;目录下有三个文件夹&#xff1a; include 头文件lib 编译的二进制库&#xff0c;根据你项目的配置去包含相应的库samples 官方使用案列 动态链接 libfbxsdk.dll, libfbxsdk.lib是动态库&#xff0c;需要在配置属性->C/C->预…...

VisionMamba安装

1.安装python环境 conda create -n mamba python3.10.13 -y conda activate mamba2.安装torch环境 conda install cudatoolkit11.8 -c nvidia pip install torch2.1.1 torchvision0.16.1 torchaudio2.1.1 --index-url https://download.pytorch.org/whl/cu1183.安装其他包 c…...

h2oGPT

文章目录 一、关于 h2oGPT二、现场演示特点 三、开始行动安装h2oGPT拼贴画演示资源文档指南开发致谢为什么选择 H2O.ai&#xff1f;免责声明 一、关于 h2oGPT 使用文档、图像、视频等与本地GPT进行私人聊天。100%私人&#xff0c;Apache 2.0。支持oLLaMa、Mixtral、llama. cpp…...

Win10安装MySQL、Pycharm连接MySQL,Pycharm中运行Django

一、Windows系统mysql相关操作 1、 检查系统是否安装mysql 按住win r &#xff08;调出运行窗口&#xff09; 输入service.msc&#xff0c;点击【确定】 image.png 打开服务列表-检查是否有mysql服务 &#xff08;compmgmt.msc&#xff09; image.png 2、 Windows安装MySQL …...

使用Pygame制作“俄罗斯方块”游戏

1. 前言 俄罗斯方块&#xff08;Tetris&#xff09; 是一款由方块下落、行消除等核心规则构成的经典益智游戏&#xff1a; 每次从屏幕顶部出现一个随机的方块&#xff08;由若干小方格组成&#xff09;&#xff0c;玩家可以左右移动或旋转该方块&#xff0c;让它合适地堆叠在…...

【Block总结】ODConv动态卷积,适用于CV任务|即插即用

一、论文信息 论文标题&#xff1a;Omni-Dimensional Dynamic Convolution作者&#xff1a;Chao Li, Aojun Zhou, Anbang Yao发表会议&#xff1a;ICLR 2022论文链接&#xff1a;https://arxiv.org/pdf/2209.07947GitHub链接&#xff1a;https://github.com/OSVAI/ODConv 二…...

RK3568 opencv播放视频

文章目录 一、opencv相关视频播放类1. `cv::VideoCapture` 类主要构造方法:主要方法:2. 视频播放基本流程代码示例:3. 获取和设置视频属性4. 结合 FFmpeg 使用5. OpenCV 视频播放的局限性6. 结合 Qt 实现更高级的视频播放总结二、QT中的代码实现一、opencv相关视频播放类 在…...

《LLM大语言模型+RAG实战+Langchain+ChatGLM-4+Transformer》

文章目录 Langchain的定义Langchain的组成三个核心组件实现整个核心组成部分 为什么要使用LangchainLangchain的底层原理Langchain实战操作LangSmithLangChain调用LLM安装openAI库-国内镜像源代码运行结果小结 使用Langchain的提示模板部署Langchain程序安装langserve代码请求格…...

【搜索回溯算法篇】:拓宽算法视野--BFS如何解决拓扑排序问题

✨感谢您阅读本篇文章&#xff0c;文章内容是个人学习笔记的整理&#xff0c;如果哪里有误的话还请您指正噢✨ ✨ 个人主页&#xff1a;余辉zmh–CSDN博客 ✨ 文章所属专栏&#xff1a;搜索回溯算法篇–CSDN博客 文章目录 一.广度优先搜索&#xff08;BFS&#xff09;解决拓扑排…...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

ssc377d修改flash分区大小

1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户&#xff0c;但你不希望用 root 权限运行 ns-3&#xff08;这是对的&#xff0c;ns3 工具会拒绝 root&#xff09;&#xff0c;你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案&#xff1a;创建非 roo…...

IT供电系统绝缘监测及故障定位解决方案

随着新能源的快速发展&#xff0c;光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域&#xff0c;IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选&#xff0c;但在长期运行中&#xff0c;例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...

【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计&#xff0c;提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合&#xff1a;各模块职责清晰&#xff0c;便于独立开发…...

精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南

精益数据分析&#xff08;97/126&#xff09;&#xff1a;邮件营销与用户参与度的关键指标优化指南 在数字化营销时代&#xff0c;邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天&#xff0c;我们将深入解析邮件打开率、网站可用性、页面参与时…...

django blank 与 null的区别

1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是&#xff0c;要注意以下几点&#xff1a; Django的表单验证与null无关&#xff1a;null参数控制的是数据库层面字段是否可以为NULL&#xff0c;而blank参数控制的是Django表单验证时字…...

Unity中的transform.up

2025年6月8日&#xff0c;周日下午 在Unity中&#xff0c;transform.up是Transform组件的一个属性&#xff0c;表示游戏对象在世界空间中的“上”方向&#xff08;Y轴正方向&#xff09;&#xff0c;且会随对象旋转动态变化。以下是关键点解析&#xff1a; 基本定义 transfor…...

客户案例 | 短视频点播企业海外视频加速与成本优化:MediaPackage+Cloudfront 技术重构实践

01技术背景与业务挑战 某短视频点播企业深耕国内用户市场&#xff0c;但其后台应用系统部署于东南亚印尼 IDC 机房。 随着业务规模扩大&#xff0c;传统架构已较难满足当前企业发展的需求&#xff0c;企业面临着三重挑战&#xff1a; ① 业务&#xff1a;国内用户访问海外服…...