数据结构——算法和算法效率的度量

目录

一、引言

二、算法

1 算法的基本概念

 2 算法的复杂度

2.1 时间复杂度

2.1.1 概念

2.1.2 大O的渐进表示

3 算法的空间复杂度

3.1 概念

 3.2 实例

4 实例分析

5 结论


一、引言

大家在写代码的时候有没有发现写同样功能的代码有多种不同的写法,而不同的代码也会给我们的程序带去不同的影响,比如有的代码执行的快,有的代码执行的慢;有的代码申请的空间大,有的代码申请的空间小,那这是为什么呢?因为是算法不同呀,那为什么不同呢,接下来就由姜糖给大家讲讲算法这一特殊的名词。

二、算法

1 算法的基本概念

算法(Algorithm)是对特定问题求解步骤的一种描述,它是指令的有限序列,其中的每条指令表示一个或多个操作。此外,一个算法还具有下列五个重要特性:

  • 有穷性。一个算法必须总在执行有穷步之后结束,且每一步都可在有穷时间内完成。
  • 确定性。算法中每条指令必须有确切的含义,对于相同的输入只能得出相同的输出。
  • 可行性。算法中描述的操作都可以通过已经实现的基本运算执行有限次来实现。
  • 输入。一个算法有零个或多个输入,这些输入取自于某个特定的对象的集合。
  • 输出。一个算法有一个或多个输出,这些输出是与输入有着某种特定关系的量。

通常,设计一个“好”的算法应考虑达到以下目标:

  • 正确性。算法应能够正确地解决求解问题。
  • 可读性。算法应具有良好的可读性,以帮助人们理解。
  • 健壮性。算法能对输入的非法数据做出反应或处理,而不会产生莫名其妙的输出。
  • 高效率与低存储量需求。效率是指算法执行的时间,存储量需求是指算法执行过程中所需要的最大存储空间,这两者都与问题的规模有关。


 2 算法的复杂度

算法效率的度量是通过时间复杂度和空间复杂度来描述的。

2.1 时间复杂度

说起时间可能有的人就会说,运行时间嘛我也会,把代码放在电脑上面跑一下就知道了。那大家想过没,我拿学校机房大LOL都卡的电脑和家里豪华rog全家桶来跑一个代码,他们的运行时间会一样吗?那有的人可能会说那放在同一台电脑上跑不就行了吗?那万一网卡了呢,时间不就又不一样了。所以算法中就有一个时间复杂度的概念

2.1.1 概念

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

 那接下来我们来看一个程序来找出他的执行次数:

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^{2}+2*N+10

当我们发现当N足够大时,2*N+10对函数的影响可以忽略不记,所以F(N)=N^{2} 。

所有我们计算时间复杂度的时候,我们其实并不一定有计算精确的次数,只需要一个大概就好了,所有我们这里可以用大O的渐进表示法。

2.1.2 大O的渐进表示

 大O符号:是用于描述函数渐进行为的数学符号。

推导大O阶的方法:

  1. 用常数1取代运行时间中的所有加法常数。
  2. 在修改后的运行次数函数中,只保留高阶项。
  3. 如果最高阶项存在且不是1,且去除于这个项目相乘的常数。得到的结果就是大O阶。

所以上面例子代码的时间复杂度为:

                                                     O(N^{2})

*时间复杂度中,变量一般用N表示。

接下来再举一个让我们对大O阶渐进表示有更深一步的认识:

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

 那么这个函数的时间复杂度为什么呢?

F(N)=2N+10,只保留最高项,然后去掉最高项的常数,所以最后为O(N)。

在大O渐进表示中有一些特殊的:

  • 比如有两个变量N和M,在没有特殊说明N或者M远远大于另外一个时:O(N+M);
  • O(常数)时用O(1)表示

接下来我们再来举一个例子:

const char strchr( const char* str, int character)
{while(*str){if(*str==character)return str;++str;}
}

这是一个在字符串中查找的函数

他的次数不固定,最好的情况为 O(1),最坏的情况是O(n),平均情况是O(n/2)。那我们该选择哪种情况呢?

这算法中我们一般选择最坏的运行情况,以保证算法的运行时间不会比它更长。

就如同我们生活中约会一样,我们到达的时间不可能比对象晚,不然后果很严重,所以我们要把最坏的时间告诉她,给我们留下充足的时间赴约。


3 算法的空间复杂度

3.1 概念

空间复杂度:也是一个数学表达式,是对一个算法在运行过程中临时占用存储空间大小的量度 。 空间复杂度不是程序占用了多少bytes的空间,因为这个也没太大意义,所以空间复杂度算的是变量的个数。 空间复杂度计算规则基本跟实践复杂度类似,也使用大O渐进表示法。 注意:函数运行时所需要的栈空间(存储参数、局部变量、一些寄存器信息等)在编译期间已经确定好了,因 此空间复杂度主要通过函数在运行时候显式申请的额外空间来确定。

 3.2 实例

下面我们来看代码进行分析:

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

该函数为阶乘递归,自身的递归每进行一次都会重新创造一个变量N,如图:

所以该函数创造的变量为N+1,用大O渐进法空间复杂度为O(N)。


4 实例分析

我们现在学习了空间复杂度和时间复杂度,那接下来我们用一道题结束今天的文章:

斐波那契数列(递归方法):

#include<stdio.h>int Fibonacci(int N)
{if (N < 3){return 1;}elsereturn Fibonacci(N - 1) + Fibonacci(N - 2);
}int main()
{printf("%d", Fibonacci(10));return 0;
}

大家想想它的时间和空间复杂度为多少呢?

在分析之前我想告诉大家的是,做这类题的时候我们画图是很有利于我们理解的,如图:

根据话题我们可以轻而易举的知道函数时间复杂度的大O为O(2^{N})(绿色部分缺少为常数所以忽略不计)

而时间复杂度呢,可能有人觉得也是O(2^{N}),答案却是错误的。那这是为什么呢?

那是因为函数是按照顺序执行的,如图函数肯定是先执行1然后执行完销毁完内存后才会执行2,

 而空间内存算的是函数执行需要的空间,当部分函数执行完的时候,空间就会被销毁,后续的函数会重新利用这一部分被销毁的空间,所以我们在这里算空间复杂度的时候,又该选择执行最大的一条如图蓝色部分,则最大申请变量为N+1,用大O渐进法表示则为:O(N)。

*大家注意

时间的消逝是回不来了的

空间是一直在的,是可以重复利用的


5 结论

姜糖最近因为特殊情况正逐步向着数据结构的方向前进,如有不足请大佬们帮我指出,姜糖也会不断去更新自己博客,不断反思完善自我,与各位一起迈入大牛之列。希望大家能一键三连,谢谢大家!

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

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

相关文章

51种企业应用架构模式详解

01 什么是企业应用 我的职业生涯专注于企业应用&#xff0c;因此&#xff0c;这里所谈及的模式也都是关于企业应用的。&#xff08;企业应用还有一些其他的说法&#xff0c;如“信息系统”或更早期的“数据处理”。&#xff09;那么&#xff0c;这里的“企业应用”具体指的是什…

[原型资源分享]经典产品饿了么UI模版部件库

​部件库预览链接&#xff1a;https://f13gm0.axshare.com 支持版本: Axrure RP 8 文件大小: 3MB 文档内容介绍 基本部件&#xff1a;表单样式&#xff1a;12款、数据样式&#xff1a;10款、服务样式&#xff1a;6款、导航&#xff1a;5款、业务组件&#xff1a;7款、 模板…

MySQL之查询性能优化(三)

查询性能优化 重构查询的方式 在优化有问题的查询时&#xff0c;目标应该是找到一个更优的方法获得实际需要的记过——而不是一定总是需要从MySQL获取一模一样的结果集。有时候&#xff0c;可以将查询转换一种写法让其返回一样的结果&#xff0c;但是性能更好。但也可以通过修…

Python魔法之旅-魔法方法(14)

目录 一、概述 1、定义 2、作用 二、应用场景 1、构造和析构 2、操作符重载 3、字符串和表示 4、容器管理 5、可调用对象 6、上下文管理 7、属性访问和描述符 8、迭代器和生成器 9、数值类型 10、复制和序列化 11、自定义元类行为 12、自定义类行为 13、类型检…

【Python】pyinstaller打包时添加详细信息

在要被打包的py文件同级目录新建version.txt&#xff0c;写入以下内容 # UTF-8 # # For more details about fixed file info ffi see: # http://msdn.microsoft.com/en-us/library/aa381058.aspx # VSVersionInfo(ffiFixedFileInfo(filevers(1, 4, 0, 5),prodvers(1, 4, 0, 5…

AIGC 011-SAM第一个图像分割大模型-分割一切!

AIGC 011-SAM第一个图像分割大模型-分割一切&#xff01; 文章目录 0 论文工作1论文方法2 效果 0 论文工作 这篇论文介绍了 Segment Anything (SA) 项目&#xff0c;这是一个全新的图像分割任务、模型和数据集。SA 项目是一个具有里程碑意义的工作&#xff0c;它为图像分割领域…

迎七一党史知识竞赛答题怎么做

迎七一党史知识竞赛答题&#xff0c;不仅是对于党史知识的检验&#xff0c;更是对于参赛者学习态度和综合能力的考量。在参与这类竞赛时&#xff0c;我们需要做好充分的准备&#xff0c;掌握一定的答题技巧&#xff0c;才能取得好的成绩。 首先&#xff0c;我们要深入了解竞赛…

FFmpeg播放器的相关概念【1】

播放器框架 相关术语 •容器&#xff0f;文件&#xff08;Conainer/File&#xff09;&#xff1a;即特定格式的多媒体文件&#xff0c;比如mp4、flv、mkv等。 • 媒体流&#xff08;Stream&#xff09;&#xff1a;表示时间轴上的一段连续数据&#xff0c;如一段声音数据、一段…

UFS Explorer Professional Recovery: 如何从启用了 mSATA 缓存的 Drobo 设备中恢复数据

天津鸿萌科贸发展有限公司是 UFS Explorer Professional Recovery 数据恢复软件的授权代理商。 UFS Explorer Professional Recovery 数据恢复软件提供综合性的解决方案&#xff0c;用于解决复杂的数据恢复案例&#xff0c;包括那些采用特殊存储技术的案例&#xff0c;或介质受…

上海亚商投顾:创业板指震荡收涨 超70家ST股跌停

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 沪指昨日震荡震荡&#xff0c;创业板指走势稍强&#xff0c;盘中一度涨超1%&#xff0c;黄白二线分化严重。算…

vue ts 导入 @/assets/ 红色显示的问题解决

vue ts 导入 /assets/ 红色显示的问题解决 一、问题描述 在使用的时候这样导入会出现如上的错误。 在使用的时候&#xff0c;导入的类型也没有对应的代码提示&#xff0c;说明导入有问题。 二、解决 在 tsconfig.json 中添加如下内容&#xff1a; {"compilerOptions&…

AI大模型探索之路-实战篇15: Agent智能数据分析平台之整合封装Tools和Memory功能代码

系列篇章&#x1f4a5; AI大模型探索之路-实战篇4&#xff1a;深入DB-GPT数据应用开发框架调研 AI大模型探索之路-实战篇5&#xff1a;探索Open Interpreter开放代码解释器调研 AI大模型探索之路-实战篇6&#xff1a;掌握Function Calling的详细流程 AI大模型探索之路-实战篇7…

46.ThreadPoolExcutor接口

线程池状态 ThreadPoolExcutor使用int高3位来表示线程池状态&#xff0c;低29位表示线程数量 状态高三位接收新任务处理阻塞队列任务说明RUNNING111YYSHUTDOWN000NY不会接收新任务&#xff0c;但会处理阻塞队列剩余任务&#xff0c;比较温和&#xff0c;已经提交的任务都会执…

C++ STL-迭代器函数对象适配器

目录 一.迭代器 二. 函数对象 三. 适配器 一.迭代器 是一种通用的指针类型&#xff0c;可以用来遍历 STL 容器中的元素。 具有以下作用和意义&#xff1a; 提供一种通用的方式来访问容器中的元素。允许对不同类型的容器进行统一的操作。增强了代码的灵活性和可扩展性。 一…

【C++题解】1085 - 寻找雷劈数

问题&#xff1a;1085 - 寻找雷劈数 类型&#xff1a;for循环 题目描述&#xff1a; 把整数 3025 从中剪开分为 30 和 25 两个数&#xff0c;此时再将这两数之和平方&#xff0c;计算结果又等于原数。 (3025)(3025)55553025 &#xff0c;这样的数叫“雷劈数”。 求所有符合这…

Photoshop版本选择及系统要求

1、ps2018cc/2020cc版本 适合新手&#xff0c;增加了很多智能化操作&#xff0c;非常方便好上手。 2020&#xff1a; 2、ps2015版本 cc2015版本不论是功能还是硬件上&#xff0c;都是不二选择&#xff0c;适合于配置较低的电脑&#xff0c;该有的基本功能它都有。 3、2021/2…

std::numeric_limits::max和宏定义重复报错问题

问题描述 今天在编译Beckhoff ADS开源组件的时候发现编译报错&#xff0c;报错代码如下 long AdsDevice::ReadReqEx2(uint32_t group, uint32_t offset, size_t length, void* buffer, uint32_t* bytesRead) const {if (length > std::numeric_limits<uint32_t>::ma…

Algorand 的复兴之路:改变游戏规则,打造 RWA 第一公链

TLDR 发布 AlgoKit 2.0&#xff0c;支持 Python 原生语言&#xff0c;打造开发者友好的开发环境&#xff0c;Algorand 的开发者社区规模迅速扩大。 升级共识激励机制&#xff0c;用 ALGO 奖励共识节点参与共识的执行&#xff0c;增加 ALGO 的应用场景&#xff0c;同时进一步确…

如何从官网下载 mysql 二进制安装包

一.下载二进行包 1. 官网网址: https://www.mysql.com/ 如图所示进入官网 2. 点击 DOWNLOADS ,进入如下图 在该页面找到 MySQL Community (GPL) Downloads 点进去 如上图页面&#xff0c;找到 MySQL Community Server 在点进去 下载 linux 通用版 点击最下面 Compressed …

(十四)统计学基础练习题八(选择题T351-400)

本文整理了统计学基础知识相关的练习题&#xff0c;共50道&#xff0c;适用于想巩固统计学基础或备考的同学。来源&#xff1a;如荷学数据科学题库&#xff08;技术专项-统计学三&#xff09;。序号之前的题请看往期文章。 351&#xff09; 352&#xff09; 353&#xff09; 3…