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

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

什么是算法效率?

算法效率是指算法执行的速度或完成任务所需的资源(如时间和空间)的度量。它通常用于评估算法的性能和比较不同算法的优劣。
 
算法效率的主要考量因素包括:
 
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.rhkb.cn/news/253988.html

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

相关文章

字节3面真题,LeetCode上hard难度,极具启发性题解

文章目录 &#x1f680;前言&#x1f680;LeetCode&#xff1a;41. 缺失的第一个正整数&#x1f680;思路&#x1f680;整个代码思路串一下&#x1f680;Code &#x1f680;前言 铁子们好啊&#xff01;阿辉来讲道题&#xff0c;这道题据说是23年字节3面真题&#xff0c;LeetC…

jmeter的简单使用

1、打开jmeter 打开Jmeter 安装包&#xff0c;进入\bin 中&#xff0c;找到“ApacheJMeter.jar”或"jmeter.bat", 双击打开即可 2、建立线程组 如下图所示&#xff0c;右击TestPlan&#xff0c;点击ADD->Threads(Users)->ThreadGroup 线程组页面分析&#xf…

数字图像处理实验记录六(图像的傅里叶变换和频域处理)

前言&#xff1a; 一、基础知识 1&#xff0c;傅里叶变换是什么 傅里叶变换是一种线性积分变换&#xff0c;通俗来说&#xff0c;通过傅里叶变换就是把一段信号分解成若干个简谐波。 二、实验要求 1&#xff0e;产生一幅如图所示亮块图像f(x,y)&#xff08;256256 大小、…

【npm】修改npm全局安装包的位置路径

问题 全局安装的默认安装路径为&#xff1a;C:\Users\admin\AppData\Roaming\npm&#xff0c;缓存路径为&#xff1a;C:\Users\admin\AppData\Roaming\npm_cache&#xff08;其中admin为自己的用户名&#xff09;。 由于默认的安装路径在C盘&#xff0c;太浪费C盘内存啦&#…

网络协议与攻击模拟_15FTP协议

了解FTP协议 在Windows操作系统上使用serv-U软件搭建FTP服务 分析FTP流量 一、FTP协议 1、FTP概念 FTP&#xff08;文件传输协议&#xff09;由两部分组成&#xff1a;客户端/服务端&#xff08;C/S架构&#xff09; 应用场景&#xff1a;企业内部存放公司文件、开发网站时利…

[ChatGPT们】ChatGPT 如何辅助编程初探

主页&#xff1a;元存储的博客 全文 9000 字&#xff0c; 原创请勿转载。 我没有写过诗&#xff0c;但有人说我的代码像诗一样优雅 -- 雷军 图片来源&#xff1a;https://www.bilibili.com/video/BV1zL411X7oS/ 1. 引言 作为一个程序员&#xff0c;我们不仅要熟悉各种编程语…

C语言实现memcpy、memmove库函数

目录 引言一、库函数介绍二、库函数详解三、源码实现1.memcpy源码实现2.memmove源码实现 四、测试1.memcpy函数2.memmove函数 五、源码1.memcpy源码2.memmove源码 六、参考文献 引言 关于memcpy和memmove这两个函数&#xff0c;不论是算法竞赛还是找工作面试笔试&#xff0c;对…

百卓Smart管理平台 uploadfile.php 文件上传漏洞【CVE-2024-0939】

百卓Smart管理平台 uploadfile.php 文件上传漏洞【CVE-2024-0939】 一、 产品简介二、 漏洞概述三、 影响范围四、 复现环境五、 漏洞复现手动复现小龙验证Goby验证 免责声明&#xff1a;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工…

vue3集成bpmn

文章目录 前言一、依赖二、汉化配置1.引入文件2.样式文件 总结 前言 vue3 集成bpmn 配置工作流 一、依赖 "bpmn-js": "^7.3.1", "bpmn-js-properties-panel": "^0.37.2", "bpmn-moddle": "^6.0.0", "camu…

【学网攻】 第(23)节 -- PPP协议

系列文章目录 目录 系列文章目录 文章目录 前言 一、PPP协议是什么&#xff1f; 二、实验 1.引入 实验目的 实验背景你是某公司的网络管理员&#xff0c;现在需要与另一个公司进行通信,需要你配置PPP协议保证双方发送的人是真正的而非黑客 技术原理 实验步骤新建Pack…

专业排版设计软件:QuarkXPress 2024 for mac中文激活版

QuarkXPress 2024 for Mac是一款功能强大、易于使用、高质量输出的专业排版软件。无论您是出版业的专家还是初学者&#xff0c;都可以通过QuarkXPress 2024轻松创建出令人惊叹的出版物。 软件下载&#xff1a;QuarkXPress 2024 for mac中文激活版下载 QuarkXPress 2023 for Mac…

牛客网SQL264:查询每个日期新用户的次日留存率

官网链接&#xff1a; 牛客每个人最近的登录日期(五)_牛客题霸_牛客网牛客每天有很多人登录&#xff0c;请你统计一下牛客每个日期新用户的次日留存率。 有一个登录(login。题目来自【牛客题霸】https://www.nowcoder.com/practice/ea0c56cd700344b590182aad03cc61b8?tpId82 …

前后端数据校验

前端校验内容 前端开发中的必要校验&#xff0c;可以保证用户输入的数据的准确性、合法性和安全性。同时&#xff0c;这些校验也有助于提供良好的用户体验和防止不必要的错误提交到后端。 1、必填字段校验&#xff1a; 对于必填的字段&#xff0c;需确保用户输入了有效的数据…

双非本科准备秋招(19.2)—— 设计模式之保护式暂停

一、wait & notify wait能让线程进入waiting状态&#xff0c;这时候就需要比较一下和sleep的区别了。 sleep vs wait 1) sleep 是 Thread 方法&#xff0c;而 wait 是 Object 的方法 2) sleep 不需要强制和 synchronized 配合使用&#xff0c;但 wait 强制和 s…

Javaweb之SpringBootWeb案例之登录校验功能的详细解析

2. 登录校验 2.1 问题分析 我们已经完成了基础登录功能的开发与测试&#xff0c;在我们登录成功后就可以进入到后台管理系统中进行数据的操作。 但是当我们在浏览器中新的页面上输入地址&#xff1a;http://localhost:9528/#/system/dept&#xff0c;发现没有登录仍然可以进…

【PowerShell】修改Windows网络配置的常用命令

PowerShell&#xff08;PS&#xff09;是一种强大的任务自动化和管理框架&#xff0c;具有丰富的命令和语法&#xff0c;可以用于编写脚本来管理Windows操作系统和其他应用程序。它的开放式架构和跨平台支持使得它成为一个灵活和可扩展的工具。 在网络配置方面&#xff0c;Powe…

Python3 交叉编译 numpy pandas scipy scikit-learn

1. 概述 由于需要将Python3.7 和一些软件包交叉编译到 armv7 平台硬件&#xff0c;如果是arm64位的系统&#xff0c;很多包都有预编译好的版本&#xff0c;可直接下载。本文主要在基于 crossenv(https://github.com/benfogle/crossenv)环境下交叉编译。 2. 编译环境搭建 创建…

时光峰峦文物璀璨,预防性保护筑安全

在璀璨的历史长河中&#xff0c;珍贵文物如同时间的印记&#xff0c;承载着过往的辉煌。《人文山水时光峰峦——多彩贵州历史文化展》便是这样一场文化的盛宴&#xff0c;汇聚了众多首次露面的宝藏。然而&#xff0c;文物的保存对环境要求极为苛刻&#xff0c;温湿度波动都可能…

nodeJS 的 npm 设置国内高速镜像之淘宝镜像的方法

1、我们知道 nodeJS 是老外搞出来的&#xff0c;服务器放在了国外&#xff0c;国内的小朋友访问起来会比较慢&#xff0c;阿里巴巴的淘宝给出了有力支持&#xff0c;现在我们就将 nodeJS 的镜像地址切换为国内的淘宝镜像。 2、查看当前的镜像地址&#xff1a; npm get registr…

尚硅谷Ajax笔记

一天拿下 介绍二级目录三级目录 b站链接 介绍 ajax优缺点 http node.js下载配置好环境 express框架 切换到项目文件夹&#xff0c;执行下面两条命令 有报错,退出用管理员身份打开 或者再命令提示符用管理员身份打开 npm init --yes npm i express请求 <script>//引…