【数据结构】_复杂度
目录
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. 算法效率 一般情况下,衡量一个算法的好坏是…...
pytorch实现循环神经网络
人工智能例子汇总:AI常见的算法和例子-CSDN博客 PyTorch 提供三种主要的 RNN 变体: nn.RNN:最基本的循环神经网络,适用于短时依赖任务。nn.LSTM:长短时记忆网络,适用于长序列数据,能有效解决…...
Java 16进制 10进制 2进制数 相互的转换
在 Java 中,进行进制之间的转换时,除了功能的正确性外,效率和安全性也很重要。为了确保高效和相对安全的转换,我们通常需要考虑: 性能:使用内置的转换方法,如 Integer.toHexString()、Integer.…...

力扣动态规划-14【算法学习day.108】
前言 ###我做这类文章一个重要的目的还是给正在学习的大家提供方向(例如想要掌握基础用法,该刷哪些题?建议灵神的题单和代码随想录)和记录自己的学习过程,我的解析也不会做的非常详细,只会提供思路和一些关…...

数据结构day02
1 线性表的定义和基本操作 1.1 线性表的定义 分析: 1.1.1 问题一:我们为什么探讨线性表的定义和基本操作 在研究数据结构时,需要重点关注三个方面:逻辑结构、物理结构以及数据的运算。在本节内容里,我们首先来介绍线…...
随笔 | 写在一月的最后一天
. 前言 这个月比预想中过的要快更多。突然回看这一个月,还有点不知从何提笔。 整个一月可以总结为以下几个关键词: 期许,保持期许出现休息 . 期许 关于期许,没有什么时候比一年伊始更适合设立目标和计划的了。但令人惭愧的…...

JVM方法区
一、栈、堆、方法区的交互关系 二、方法区的理解: 尽管所有的方法区在逻辑上属于堆的一部分,但是一些简单的实现可能不会去进行垃圾收集或者进行压缩,方法区可以看作是一块独立于Java堆的内存空间。 方法区(Method Area)与Java堆一样,是各个…...
一文读懂fgc之cms
一文读懂 fgc之cms-实战篇 1. 前言 线上应用运行过程中可能会出现内存使用率较高,甚至达到95仍然不触发fgc的情况,存在内存打满风险,持续触发fgc回收;或者内存占用率较低时触发了fgc,导致某些接口tp99,tp…...

MYSQL 商城系统设计 商品数据表的设计 商品 商品类别 商品选项卡 多表查询
介绍 在开发商品模块时,通常使用分表的方式进行查询以及关联。在通过表连接的方式进行查询。每个商品都有不同的分类,每个不同分类下面都有商品规格可以选择,每个商品分类对应商品规格都有自己的价格和库存。在实际的开发中应该给这些表进行…...

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

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

FBX SDK的使用:基础知识
Windows环境配置 FBX SDK安装后,目录下有三个文件夹: include 头文件lib 编译的二进制库,根据你项目的配置去包含相应的库samples 官方使用案列 动态链接 libfbxsdk.dll, libfbxsdk.lib是动态库,需要在配置属性->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?免责声明 一、关于 h2oGPT 使用文档、图像、视频等与本地GPT进行私人聊天。100%私人,Apache 2.0。支持oLLaMa、Mixtral、llama. cpp…...

Win10安装MySQL、Pycharm连接MySQL,Pycharm中运行Django
一、Windows系统mysql相关操作 1、 检查系统是否安装mysql 按住win r (调出运行窗口) 输入service.msc,点击【确定】 image.png 打开服务列表-检查是否有mysql服务 (compmgmt.msc) image.png 2、 Windows安装MySQL …...

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

【Block总结】ODConv动态卷积,适用于CV任务|即插即用
一、论文信息 论文标题:Omni-Dimensional Dynamic Convolution作者:Chao Li, Aojun Zhou, Anbang Yao发表会议:ICLR 2022论文链接:https://arxiv.org/pdf/2209.07947GitHub链接: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如何解决拓扑排序问题
✨感谢您阅读本篇文章,文章内容是个人学习笔记的整理,如果哪里有误的话还请您指正噢✨ ✨ 个人主页:余辉zmh–CSDN博客 ✨ 文章所属专栏:搜索回溯算法篇–CSDN博客 文章目录 一.广度优先搜索(BFS)解决拓扑排…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...

springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...

Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...

相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...

DBLP数据库是什么?
DBLP(Digital Bibliography & Library Project)Computer Science Bibliography是全球著名的计算机科学出版物的开放书目数据库。DBLP所收录的期刊和会议论文质量较高,数据库文献更新速度很快,很好地反映了国际计算机科学学术研…...