一篇文章理解时间复杂度和空间复杂度

今天也是很开心的学到了数据结构,也是打算把我自己对知识的理解给写出来了。第一篇数据结构开始咯。开始之前我们先理解一个概念。

什么是算法效率?

算法效率是指算法执行的速度或完成任务所需的资源(如时间和空间)的度量。它通常用于评估算法的性能和比较不同算法的优劣。
 
算法效率的主要考量因素包括:
 
1. 时间复杂度:描述算法执行所需的时间与问题规模(如输入数据的大小)之间的关系。常见的时间复杂度度量方法有 O(n)、O(log n)、O(n log n) 等。较低的时间复杂度表示算法在处理大规模问题时效率更高。
2. 空间复杂度:描述算法所需的额外存储空间与问题规模之间的关系。较低的空间复杂度表示算法在内存使用上更高效。
3. 稳定性:某些算法可能对输入数据的顺序或其他特征有特殊要求,稳定性指的是算法在这些情况下的表现。
4. 可扩展性:算法是否容易适应更大规模或更复杂的问题。
5. 实际性能:除了理论分析,实际测试和基准测试也可以用来衡量算法在具体硬件和环境中的效率。

 
评估算法效率的目的是选择在特定场景下最适合的算法,以达到最优的性能和资源利用。在设计算法时,通常会追求高效率的算法,以减少计算时间和资源消耗。同时,还需要考虑算法的实现复杂度、可读性和可维护性等因素。对于一些复杂问题,可能需要在效率和其他因素之间进行权衡。
 

但是现在我们不了解那么多,我们就来理解一下简单的时间复杂度和空间复杂度!!!

目录

时间复杂度

空间复杂度


时间复杂度

时间复杂度是一种对算法运行时间的度量,用于描述算法在处理特定规模问题时所需的计算操作数量。它反映了算法的效率和性能。
 

时间复杂度通常使用大 O 表示法来表示,其中 O(n) 表示算法的运行时间与问题规模 n 成正比。例如,如果一个算法的时间复杂度为 O(n),意味着随着问题规模的增大,算法的运行时间也会线性增加。
 
常见的时间复杂度级别包括:
 
1. O(1):表示常量时间复杂度,算法的运行时间与问题规模无关,无论输入规模如何变化,算法的执行时间都是固定的。
2. O(log n):对数时间复杂度,算法的运行时间与对数函数相关,对于大规模问题,算法的效率较高。
3. O(n):线性时间复杂度,算法的运行时间与问题规模成线性关系。
4. O(n log n):线性对数时间复杂度,算法的运行时间与 n 和 log n 相关。
5. O(n^2):平方时间复杂度,算法的运行时间与 n 的平方成正比,对于大规模问题,效率可能较低。
6. O(n^c):其中 c 是常数,这种复杂度表示算法的运行时间与 n 的 c 次幂成正比。
 
这里需要注意的是:时间复杂度的评估是基于算法的最坏情况运行时间,即在最不利的输入情况下的时间复杂度。它提供了一种对算法效率的粗略估计,帮助我们在不同算法之间进行比较和选择。
 
时间复杂度只是一种理论上的度量,实际的运行时间还受到其他因素的影响,如硬件性能、数据结构的选择、算法的实现细节等。因此,在实际应用中,除了考虑时间复杂度外,还需要综合考虑其他因素来评估算法的性能。

 
通过分析算法的时间复杂度,我们可以在设计和选择算法时做出更明智的决策,以满足特定场景下对效率的要求。较低的时间复杂度通常意味着算法在处理大规模问题时具有更好的性能。但在实际情况中,还需要结合具体问题和需求来选择合适的算法。

下面我们就开始用例子来说说如何计算时间复杂度。

例一:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>int Func(int n)
{int i = 0;int j = 0;int count = 0;for (i = 0; i < n; i++){for (j = 0; j < n; j++){++count;}}int k = 0;for (k = 0; k < 2 * n; k++){++count;}int a = 20;while (a){++count;--a;}return count;
}int main()
{int n = 0;scanf("%d", &n);int count = Func(n);printf("%d\n", count);return 0;
}

 在上面代码中大家觉得Func函数的时间复杂度是多少呢?下面就说一下时间复杂度的算法。我们把图一看就都理解了。

上图显示Func函数执行基本操作的次数,那有什么用呢?

其实在计算时间复杂度时我们可以用执行次数的表达式,用大 O渐近表示法,来表示时间复杂度,但随着n的值变大,我们发现其实对次数变化影响最大的是 n*n这一项,而且时间复杂度是估算的所以我们就剔除掉后面影响不大的两项,取影响最大的进行估算。所以这个函数的时间复杂度就是 O(n^2).


例二:

int Func1(int n ,int m )
{int i = 0;int j = 0;int count;for ( i = 0; i < k; i++){for (j = 0; j < m; j++){++count;}}return count;
}

我们列出数学表达式计算次数:F(n)=n+m. 这里的时间复杂度就是O(n+m)

需要注意的是:如果题目给出n远大于m,那么此时的时间复杂度就是O(n)。


例三:
 

int Func2( )
{int i = 0;int j = 0;int count;for ( i = 0; i < 10; i++){for (j = 0; j < 100; j++){++count;}}return count;
}

 这里列出数学表达式F(n)=10*100=1000。大家是不是以为函数Func2的

时间复杂度为O(1000)了,其实不然,在计算机中我们把常数次基本操作的函数的时间复杂度统一设定为O(1)。故func2的时间复杂度其实为O(1)在计算中这种复杂度是最优的了.

例四:

 

int Func4(arr[],int sz,int x)
{int begin = 0;int end = sz;int n = 0;while (end>begin){int mid = (begin + end) / 2;if (arr[mid] > x){end = mid - 1;}else if (arr[mid] < x){begin = mid + 1;}elsereturn mid;}

列出数学表达式F(n)=log 2 n,但在计算机中这里的底数难以表示,所以在计算机中就自动把底数省略掉,所以这里的空间复杂度就是O(log n) 。


空间复杂度

空间复杂度是对算法在执行过程中所需的额外存储空间的度量。它用于评估算法对内存的使用效率。
 
与时间复杂度类似,空间复杂度通常使用大 O 表示法来表示。空间复杂度描述了算法在解决特定问题时所需的存储空间与问题规模之间的关系。例如,O(n) 表示算法的空间复杂度与问题规模 n 成正比。
 
空间复杂度主要考虑以下几个方面:
 
1. 额外的存储空间:算法可能需要额外的存储来保存中间结果、临时变量或其他数据结构。
2. 输入数据的规模:问题的输入规模可能直接影响算法所需的空间。
3. 数据结构的选择:不同的数据结构可能具有不同的空间复杂度,例如使用数组和使用链表可能会有不同的空间需求。
4. 递归算法:递归算法在执行过程中可能会产生大量的栈空间消耗。
 

较低的空间复杂度意味着算法在内存使用上更高效,尤其在处理大规模问题或资源受限的环境中更为重要。然而,在实际情况中,需要在空间复杂度和算法的其他特性(如时间复杂度、可读性等)之间进行权衡。
 
与时间复杂度一样,空间复杂度的评估是基于算法的最坏情况,并且是一种理论上的估计。实际的空间需求可能受到具体实现、硬件环境和问题特征的影响。
 
在设计算法时,了解和优化空间复杂度可以帮助避免不必要的内存消耗,并提高算法的整体效率。但需要根据具体问题和系统资源来综合考虑空间复杂度与其他因素的平衡。有时候,为了获得更好的时间复杂度或其他优势,可能会接受较高的空间复杂度。
 


了解完后,我们继续举例:

例5:

int Func(int n)
{int i = 0;int j = 0;int count = 0;for (i = 0; i < n; i++){for (j = 0; j < n; j++){++count;}}int k = 0;for (k = 0; k < 2 * n; k++){++count;}int a = 20;while (a){++count;--a;}
}

空间复杂度与时间复杂度计算方法相似,不同的是空间复杂度是用计算变量的个数来估算空间复杂

度,也是用大O 表示法来表示。如上面中我们看到此函数创建的变量的数量为6个,即n,i,j,

k,count,a。与时间复杂度一样常数用O(1)表示,故函数的空间复度为O(1).


例五:

 

int Func5(int n)
{if (n == 1){return 1;}else{return n * Func5(n - 1);}}

 像这里运用·递归来算n的阶乘,我们知道在它每次递推过程中都会在栈区开辟一块空间,在此函

数中共递推n次,故其空间复杂度为O(n)。


总之:空间复杂度和时间复杂度相似只不过一个通过计算变量个数来估算,一个是计算执行基本次

数来估算,都是用大O 渐近表示法来表示,且都是取影响最大的项,剔除掉影响较小的项,有的情

况也需根据实际情况进行改变。


今天这篇博客就写到这了。

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

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

相关文章

Pymysql之Cursor常用API

Cursor常用API 1、cursor.execute(query, argsNone)&#xff1a;执行sql语句。 参数: query (str)&#xff1a;sql语句。 args (tuple, list or dict)&#xff1a;sql语句中如果有变量&#xff0c;或者格式化输出&#xff0c;会在这里填充数据。 Returns&#xff1a;返…

日志报错 git -c dif.mnemonicprefix=false -c core.guotepath=false 解决方法

前言: 在进行下面操作前,必须确保,你是否安装了Git。 查看Git 在命令行窗口中输入`git --version`: 如果这个命令成功显示了Git的版本信息,这表明Git已经被安装。 1. 使用Sourcetree SourceTree 是 Windows 和Mac OS X 下免费的 Git 和 Hg 客户端…

react将选中文本自动滑动到容器可视区域内

// 自动滚动到可视区域内useEffect(() > {const target ref;const wrapper wrapperRef?.current;if (target && wrapperRef) {const rect target.getBoundingClientRect();const wrapperRect wrapper.getBoundingClientRect();const isVisible rect.bottom &l…

NLP入门系列—词嵌入 Word embedding

NLP入门系列—词嵌入 Word embedding 2013年&#xff0c;Word2Vec横空出世&#xff0c;自然语言处理领域各项任务效果均得到极大提升。自从Word2Vec这个神奇的算法出世以后&#xff0c;导致了一波嵌入&#xff08;Embedding&#xff09;热&#xff0c;基于句子、文档表达的wor…

幻兽帕鲁服务器全自动部署教程,小白也能轻松上手

幻兽帕鲁太火了&#xff0c;官方palworld服务器不稳定&#xff1f;不如自建服务器&#xff0c;基于腾讯云幻兽帕鲁服务器成本32元全自动部署幻兽帕鲁服务器&#xff0c;超简单有手就行&#xff0c;全程自动化一键部署10秒钟即可搞定&#xff0c;无需玩家手动部署幻兽帕鲁游戏程…

深入探索:缓冲区溢出漏洞及其防范策略

在网络安全的广阔领域中&#xff0c;缓冲区溢出漏洞一直是一个重要的议题。这种漏洞&#xff0c;如果被恶意利用&#xff0c;可能会导致严重的安全问题&#xff0c;包括数据泄露、系统崩溃&#xff0c;甚至可能被攻击者利用来执行恶意代码。在本文中&#xff0c;我们将深入探讨…

【stm32】hal库学习笔记-ADC模数转换(超详细)

【stm32】hal库学习笔记-ADC模数转换&#xff08;超详细&#xff09; 本篇章介绍了ADC实现电压检测的三种方式 ADC原理及选型 ADC将连续的模拟电压信号转换为二进制的数字信号 选型参数 速度&#xff08;采样频率&#xff09; 功耗 精度 转换原理 ADC hal库驱动函数 普通…

一文读懂转融通

最近多家公司都在讲解关于转融通要求。今天我们就来详细聊聊&#xff01; 转融通是一种证券借贷机制&#xff0c;它允许机构投资者在融资融券交易中借入或借出证券。 具体来说&#xff0c;机构投资者可以向券商借入证券&#xff0c;或者将持有的证券借给券商&#xff0c;以扩大…

VScode实现文件、函数自动添加注释说明信息

常规的手动注释费时费力&#xff0c;不方便&#xff0c;拖慢开发进度&#xff0c;甚至影响开发者心情&#xff0c;因此需要实现自动注释&#xff0c;不仅能减少工作量&#xff0c;也能让编写的代码更加的规范整洁&#xff0c;易于理解。 在VScode的插件搜索栏中&#xff0c;查…

STM32学习笔记——看门狗

目录 一、看门狗概述 1、看门狗工作原理 2、独立看门狗IWDG主要性能&#xff1a; 二、看门狗相关寄存器 1、IWDG_KR (Independent Watchdog_Key Register) 关键词寄存器 2、IWDG_PR (Independent Watchdog_Prescaler Register) 预分频寄存器 3、IWDG_RLR (Independent W…

懒人精灵 之 Lua 捕获 json解析异常 ,造成的脚本停止.

Time: 2024年2月8日20:21:17 by:MemoryErHero 1 异常代码 Expected value but found T_END at character 12 异常代码 Expected value but found T_OBJ_END at character 223 处理方案 - 正确 json 示范 while true do--Expected value but found T_END at character 1--Ex…

鄂尔多斯交警推进东康快线“恶劣天气高影响路段优化工程”,全面提升科技赋能实战水平!

2023年5月29日&#xff0c;三部门联合印发《2023年省级恶劣天气高影响路段优化提升气象保障工作方案》&#xff08;以下简称《工作方案》&#xff09;&#xff0c;持续推动恶劣天气交通预警处置试点成果和优化提升工作经验在第二批试点路段上推广应用。 【安装在东康快线上的应…

面向对象的三大特征之一继承

继承 继承的特性 概念&#xff1a;可以使得子类具有父类的属性(成员变量)和方法(成员方法)&#xff0c;还可以在子类中重新定义&#xff0c;追加属性和方法。 继承的格式&#xff1a; public class 子类名 extends 父类名{} 父类&#xff1a;基类、超类 子类&#xff1a;派生…

【Unity】QFramework通用背包系统优化:TipPanel优化

前言 在学习凉鞋老师的课程《QFramework系统设计&#xff1a;通用背包系统》第五章时&#xff0c;笔者对物品提示TipPanel界面进行了一些优化。 优化内容包括&#xff1a; 解决闪烁问题跟随鼠标移动自适应界面大小生成位置优化 效果还是蛮丝滑的&#xff1a; 解决闪烁问题 …

[linux]:匿名管道和命名管道(什么是管道,怎么创建管道(函数),匿名管道和命名管道的区别,代码例子)

目录 一、匿名管道 1.什么是管道&#xff1f;什么是匿名管道&#xff1f; 2.怎么创建匿名管道&#xff08;函数&#xff09; 3.匿名管道的4种情况 4.匿名管道有5种特性 5.怎么使用匿名管道&#xff1f;匿名管道有什么用&#xff1f;&#xff08;例子&#xff09; 二、命名…

MVCC多版本并发控制

MVCC mvcc是多版本并发控制。维护一个数据的多个版本&#xff0c;使读写没有冲突 隐式字段 DB_TRX_ID:最近修改事务id&#xff0c;记录插入这条记录或最后一次修改该记录的事务id DB_ROLL_PTR:回滚指针&#xff0c;指向这条记录的上一个版本&#xff0c;用于配合undo log&…

筛法思想的题目

这道题目比较经典&#xff0c;或者说这种思想比较经典。 这种筛法的思想。 我们正着想对于每一个 n 、 n − 1 、 n − 2 、 . . . 、 2 、 1 n、 n-1、n-2、...、2、1 n、n−1、n−2、...、2、1都分解一遍质因数显然是来不及的时间复杂度达到 O ( n n ) O(n \sqrt{n}) O(nn ​…

Open CASCADE学习|点和曲线的相互转化

目录 1、把曲线离散成点 1.1按数量离散 1.2按长度离散 1.3按弦高离散 2、由点合成曲线 2.1B样条插值 2.2B样条近似 1、把曲线离散成点 计算机图形学中绘制曲线&#xff0c;无论是绘制参数曲线还是非参数曲线&#xff0c;都需要先将参数曲线进行离散化&#xff0c;通过离…

LayUI中表格树折叠 --

1、先将插件源码进行下载&#xff0c;新建 tableTree.js 文件&#xff0c;将源码放进去 2、将 tableTree.js 文件 配置之后&#xff0c;在需要使用的页面进行引入&#xff1a; layui.define(["tableTree"],function (exports) {var tableTree layui.tableTree;// …

2024年【天津市安全员B证】模拟试题及天津市安全员B证模拟考试题库

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 天津市安全员B证模拟试题是安全生产模拟考试一点通生成的&#xff0c;天津市安全员B证证模拟考试题库是根据天津市安全员B证最新版教材汇编出天津市安全员B证仿真模拟考试。2024年【天津市安全员B证】模拟试题及天津市…