【数据结构初阶】时间复杂度和空间复杂度详解

今天我们来详细讲讲时间复杂度和空间复杂度,途中如果有不懂的地方可翻阅我之前文章。

个人主页:小八哥向前冲~-CSDN博客

数据结构专栏:数据结构【c语言版】_小八哥向前冲~的博客-CSDN博客

c语言专栏:c语言_小八哥向前冲~的博客-CSDN博客

 在平常写代码时,碰见一个问题,有时候第一种思路代码量相对较多,而第二种思路代码量相对较小。这时候你可能会选择代码量较小的思路进行解答。但真的代码量越少,代码运行效率更快嘛?

那可不一定,有时候代码量大的反而更好,算法效率并不取决于代码量的,衡量一个算法或一个思路好不好,主要看的是时间复杂度和空间复杂度的

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

我们率先讲讲时间复杂度。

时间复杂度概念

我们先来看看它的定义:

在计算机科学中,算法的时间复杂度是一个函数,它定量描述了该算法的运行时间。一 个算法执行所耗费的时间,从理论上说,是不能算出来的,只有你把你的程序放在机器上跑起来,才能知 道。但是我们需要每个算法都上机测试吗?是可以都上机测试,但是这很麻烦,所以才有了时间复杂度这个 分析方式。一个算法所花费的时间与其中语句的执行次数成正比例,算法中的基本操作的执行次数,为算法的时间复杂度。

也就是说:算法中基本操作的执行次数就是时间复杂度

我们来看个例子:

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);}

要计算它的时间复杂度,我们不妨计算count执行了多少次,显然执行了N*N+2*N+10次,到这里你不会就以为它的空间复杂度就是N*N+2*N+10了吧。那可就大错特错了!

实际中我们计算时间复杂度时,我们其实并不一定要计算精确的执行次数,而只需要大概执行次数,那么这 里我们使用大O的渐进表示法

大o的渐进表示法

这里我们不妨看图:

不难看出F(N)的值主要取决于N*N,那么我们说这个算法的时间就是o(N*N),也就是说我们只取对这个算法影响最深的一项

也就是说大O的渐进表示法去掉了那些对结果影响不大的项,简洁明了的表示出了执行次数。

但是有时候我们的算法会出现最好情况,最坏情况。什么意思呢?我们看个例子(二分查找):

 // 计算BinarySearch的时间复杂度?
int BinarySearch(int* a, int n, int x){assert(a);int begin = 0;int end = n-1;// [begin, end]:begin和end是左闭右闭区间,因此有=号while (begin <= end){int mid = begin + ((end-begin)>>1);if (a[mid] < x)begin = mid+1;else if (a[mid] > x)end = mid-1;elsereturn mid;}return -1;}

这个例子的最坏情况:一次就找到。最坏情况:log2N次。为什么呢?我们分析一下:查找一次对半砍,两次对半砍两次,一直到砍到只剩最后一个值了或者最后一个值都不是要找的数,这就是最坏情况。

我们计算一下:

注意:如果有多种情况的话,我们一般算最坏情况。

我们来看看其他例子。

计算时间复杂度例题

冒泡排序例子

// 计算BubbleSort的时间复杂度?
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;}}

我们来计算一下:N个数排序,第一次N-1趟冒泡,第二次N-2次冒泡,依次递减,其中每趟冒泡两两比较,我们不难算出N-1+N-2+N-3+N-4+........+1,也就是等差数列,我们算出为N*(N-1)/2,到这里是不是豁然开朗?最终为o(N*N)

常数例子

我们再来看一下另一个常数例子:

// 计算Func4的时间复杂度?
void Func4(int N){int count = 0;for (int k = 0; k < 100; ++ k){++count;}printf("%d\n", count);}

我们不难看出执行了100次(非常准确),但不会你以为时间复杂度为o(100)吧?其实不然,确实执行行了100次,但因为是常数次,我们一律规定为o(1)。

注意:这里的o(1)并不是只执行了1次,而是代表执行了常数次!

递归例子

// 计算阶乘递归Fac的时间复杂度?
long long Fac(size_t N){if(0 == N)return 1;return Fac(N-1)*N;}

刚刚接触递归例子是不是有点摸不着头脑?别急!

我们知道当N为0时就停止,当N>0时就一直调用这个函数,调用多少次呢?调用到0就停止!不难算出调用了N次,时间复杂度也就是o(N)!

我们可以上图理解一下:

我们来看一个另一个典型例子----斐波拉及数列!

// 计算斐波那契递归Fib的时间复杂度?
long long Fib(size_t N){if(N < 3)return 1;return Fib(N-1) + Fib(N-2);}

我们不难看出:

F(N)调用F(N-1)和F(N-2),F(N-1)调用F(N-2)和F(N-3)........直到调用到N<3就停止

既然这样仍然看不出执行次数,我们上图看看:

这样看是不是更加清楚呢?但是仍然存在一些瑕疵和疏漏:有些项并没有那么多项

我们再上图:

值得注意的是不影响算时间复杂度!

显然这个递归算法不实用!因为次数一旦大一点,计算机就算不出来(要耗费一点时间,不信可以自行试试!)

空间复杂度概念

空间复杂度也是一个数学表达式,是对一个算法在运行过程中临时占用存储空间大小的量度 。 空间复杂度不是程序占用了多少bytes的空间,因为这个也没太大意义,所以空间复杂度算的是变量的个数。 空间复杂度计算规则基本跟实践复杂度类似,也使用大O渐进表示法

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

一般理解了时间复杂度,空间的复杂度就手到擒来了!

我们来看一些例题感受一下!

计算空间复杂度例题

常数例子

一个最常见的常数例子就是冒泡排序了,我们来看看:

// 计算BubbleSort的空间复杂度?
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)

常见例子

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;

不难看出:开辟了n+1个额外空间,也就是o(N)

递归例子

// 计算阶乘递归Fac的空间复杂度?
long long Fac(size_t N){if(N == 0)return 1;return Fac(N-1)*N;}

不难看出:递归调用了N次,开辟了N个栈帧,每个栈帧使用了常数个空间。空间复杂度为O(N)

常见复杂度对比

算法有很多种,只要存在就有它的道理----存在即合理!只要我们理解它的底层逻辑,那么什么都不在话下!

好了,我们下期见!

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

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

相关文章

matlab新手快速上手6(引力搜索算法)

本文根据一个较为简单的matlab引力搜索算法框架详细分析蚁群算法的实现过程&#xff0c;对matlab新手友好&#xff0c;源码在文末给出。 引力搜索算法简介&#xff1a; 引力搜索算法是一种启发式优化算法&#xff0c;最初于2009年由伊朗的Esmat Rashedi、Hossein Nezamabadi-p…

uniapp 对接facebook第三方登录

1.登录facebook开发者中心&#xff0c;打开我的应用页面在这里插入图片描述 2.创建应用 3.选择类型 4.填写信息 5.添加登录 6.添加平台 安卓密钥生成【需要 Java 环境!!! 和 openssl库】 Google Code Archive 的 Windows 版 openssl-for-windows OpenSSL 库 将openssl下载到…

如何利用FMEA进行不良事件分析——FMEA软件

免费试用FMEA软件-免费版-SunFMEA FMEA&#xff08;Failure Modes and Effects Analysis&#xff09;是一种预防性的质量工具&#xff0c;它帮助识别产品或过程中可能的故障模式&#xff0c;评估其对系统的影响&#xff0c;并优先处理那些对系统性能影响最大的故障模式。在医疗…

新时代教师口才演讲稿(3篇)

新时代教师口才演讲稿&#xff08;3篇&#xff09; 新时代教师口才演讲稿&#xff08;一&#xff09; 尊敬的各位领导、亲爱的同事们&#xff1a; 大家好&#xff01; 今天&#xff0c;我站在这里&#xff0c;深感荣幸与激动。在这个新时代里&#xff0c;教师的口才不仅仅是传…

webpack3升级webpack4遇到的各种问题汇总

webpack3升级webpack4遇到的各种问题汇总 问题1 var outputNamecompilation.mainTemplate.applyPluginWaterfull(asset-path,outputOptions.filename,{......)TypeError: compilation.mainTemplate.applyPluginsWaterfall is not a function解决方法 html-webpack-plugin 版…

上市公司-双重差分模型手动匹配绿色企业数据及参考资料

01、数据简介 双重差分模型&#xff08;DID&#xff0c;Differences-in-Differences&#xff09;是一种用于估计某个政策或处理效果的经济计量学模型。通过双重差分模型&#xff0c;可以控制一些不易观察的个体特征和时间趋势&#xff0c;以更准确地估计政策的效应。将绿色企业…

文件上传漏洞(upload-labs)

目录 一、文件上传漏洞 1.什么是文件上传漏洞 常见的WebShell 2.文件上传产生漏洞的原因 二、文件上传绕过 &#xff08;一&#xff09;客服端绕过-JS验证 1.前端验证 upload-labs第一关 &#xff08;二&#xff09;绕过黑名单验证 黑名单验证 1.特殊解析后缀 upl…

快速掌握Yarn:软件包管理工具的安装与使用指南【写作AI免费】

首先&#xff0c;这篇文章是基于笔尖AI写作进行文章创作的&#xff0c;喜欢的宝子&#xff0c;也可以去体验下&#xff0c;解放双手&#xff0c;上班直接摸鱼~ 按照惯例&#xff0c;先介绍下这款笔尖AI写作&#xff0c;宝子也可以直接下滑跳过看正文~ 笔尖Ai写作&#xff1a;…

Linux第十五章

&#x1f436;博主主页&#xff1a;ᰔᩚ. 一怀明月ꦿ ❤️‍&#x1f525;专栏系列&#xff1a;线性代数&#xff0c;C初学者入门训练&#xff0c;题解C&#xff0c;C的使用文章&#xff0c;「初学」C&#xff0c;linux &#x1f525;座右铭&#xff1a;“不要等到什么都没有了…

MySQL随便聊----之MySQL的调控按钮-启动选项和系统变量

-------MySQL是怎么运行的 基本介绍 如果你用过手机&#xff0c;你的手机上一定有一个设置的功能&#xff0c;你可以选择设置手机的来电铃声、设置音量大小、设置解锁密码等等。假如没有这些设置功能&#xff0c;我们的生活将置于尴尬的境地&#xff0c;比如在图书馆里无法把手…

Hive安装部署

Apache Hive是一个基于Hadoop分布式文件系统、使用MapReduce算法执行大规模离线数据分析的数据仓库&#xff0c;本文主要描述Hive的安装部署。 如上所示&#xff0c;Hive总体应用架构图&#xff0c;其中&#xff0c;Hive基于HBase或者使用Hadoop分布式文件系统执行MapReduce的分…

注意力机制(四)(多头注意力机制)

​&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;《深度学习基础知识》 相关专栏&#xff1a; ⚽《机器学习基础知识》 &#x1f3d0;《机器学习项目实战》 &#x1f94e;《深度学习项目实…

react报错:Warning: Each child in a list should have a unique “key“ prop.

我是万万没想到的&#xff0c;使用Popconfirm不添加key属性也会报错&#xff1a; react-refresh:160Warning: Each child in a list should have a unique "key" prop. Check the render method of Cell. Seehttps://reactjs.org/link/warning-keys for more informa…

nginx--安装

yum安装 官方包链接&#xff1a;nginx: Linux packages 官方yum源链接&#xff1a;nginx: Linux packages 配置yum源 [rootlocalhost ~]# yum install -y nginx [nginx-stable] namenginx stable repo baseurlhttp://nginx.org/packages/centos/$releasever/$basearch/ gp…

零基础HTML教程(31)--HTML5多媒体

文章目录 1. 背景2. audio音频3. video视频4. audio与video常用属性5. 小结 1. 背景 在H5之前&#xff0c;我们要在网页上播放音频、视频&#xff0c;需要借助第三方插件。 这些插件里面最火的就是Flash了&#xff0c;使用它有几个问题&#xff1a; 首先要单独安装Flash&…

竞争分析:波特五力模型

波特五力模型是分析企业竞争环境的一个分析模型。 根据波特的观点&#xff0c;每家企业都受到“直接竞争对手、顾客、供应商、潜在新进公司和替代性产品”这五个“竞争作用力”的影响。 我们用波特五力模型试着分析下实体书店竞争是否激励。 直接竞争对手&#xff1a;如果直接…

01.Kafka简介与基本概念介绍

1 Kafka 简介 Kafka 是最初由 Linkedin公司开发&#xff0c;是一个分布式、支持分区(partition)的、多副本(replica)的&#xff0c;基于 Zookeeper 协调的分布式消息系统&#xff0c;它的最大的特性就是可以实时的处理大量数据以满足各种需求场景&#xff1a;比如基于 hadoop 的…

Spring AOP详解,简单Demo

目录 一、Spring AOP 是什么&#xff1f; 二、学习AOP 有什么作用&#xff1f; 三、AOP 的组成 四、 Spring AOP 简单demo 一、Spring AOP 是什么&#xff1f; Spring AOP&#xff08;Aspect-Oriented Programming in Spring&#xff09;是Spring框架中的一个重要组件&…

c# 构造函数 静态构造函数 内联字段(即静态字段和实例字段) 父类构造函数 父类静态构造函数 父类内联字段 执行顺序

顺序如下&#xff1a; 1.子类的内联字段 2.子类的静态构造函数 3.父类的内联字段 4.父类的静态构造函数 5.父类的构造函数 6.子类的构造函数 7.子类的方法 public class A{public static string a1"A0";static A(){Console.WriteLine("父类内联字段&#xff1a;…

基于遗传优化算法的TSP问题求解matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于遗传优化算法的TSP问题求解&#xff0c;分别对四个不同的城市坐标进行路径搜索。 2.测试软件版本以及运行结果展示 MATLAB2022A版本运行 3.核心程序 ....…