【数据结构与算法基础】算法复杂度

  欢迎光顾我的homepage

前言

        算法就是定义良好的计算过程,它取一个活一组的值输入,并产生出一个或一组值作为输出。简单来说,算法就是一系列的计算步骤,用来将输入数据转化成输出结果。

一、算法效率

        如何去衡量一个算法的好坏?

        算法在编写成可执行程序后,运行时消耗时间和空间资源。因此,一般从时间和空间两个维度来衡量,即时间复杂度和空间复杂度。

时间复杂度和空间复杂度

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

        在计算机发展的早期,计算机的存储容量很小。所以对复杂度很是在乎。但是计算机行业的迅速发展,计算机存储容量已经达到很高的程度,所以我们并不用特别关注算法的空间复杂度

二、时间复杂度

        时间复杂度是指算法在执行过程中,所需要的时间资源和问题规模之间的关系,主要衡量算法的运行效率,用来估算算法在不同规模下的运行时间

        时间复杂度用大O的渐进表示法来表示

2.1时间复杂度的计算

        算法的时间复杂度是一个函数式T(N),它定量描述了该算法的运行时间。

实际上,我们计算时间复杂度时,计算主要涉及到以下几个方面

基本操作次数: 时间复杂度的计算通常关注算法中执行的基本操作次数,例如赋值操作、比较操作、算术运算等。通常将这些操作的数量与输入规模相关联。

循环结构: 算法包含循环结构,需要考虑循环的迭代次数以及每次迭代中的基本操作数量。

递归调用: 对于递归算法,需要考虑递归的深度以及每次递归调用的时间复杂度。通常使用递归方程(递归关系式)来表示递归算法的时间复杂度。

分支结构: 如果算法包含分支结构,需要考虑每个分支的执行次数以及分支中的基本操作数量。

输入规模: 时间复杂度的计算通常与输入规模有关。输入规模表示算法操作的数据量或问题的大小,通常用符号n表示。

        说白了,算法复杂度其实就是计算基本操作的执行次数
看一个案例,来计算时间复杂度

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

这里Func函数基础语句执行次数 T(N)=N^2+2N+10

大O的渐进表示法表示就成了 O(N^2)

大O的渐进表示法

1 . 时间复杂度的函数式T(N)中,只保留最高阶项,去掉那些低阶项

2 . 如果最高项存在且不是1,则去掉这个项的常数系数

3 . T(N)中如果没有N的相关项,只要常数项,用常数1来取代所有加法常数

2.2、时间复杂度计算实例

2.2.1、示例一

void Func1(int N)
{int count = 0;for (int k = 0; k < 2 * N; ++k){++count;}int M = 10;while (M--){++count;}printf("%d\n", count);
}

Func1函数基本操作次数

         T(N)= 2N+10

        大O渐进表示法  Func1的时间复杂度为:O(N)

2.2.2、示例二

void Func2(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);
}

Func1函数基本操作次数

        T(N)= M+N

        因为这里无法确定M和N的大小,所以有大O渐进表示法 就为:O(M+N)

2.2.3、示例三

void Func3(int N)
{int count = 0;for (int k = 0; k < 100; ++k){++count;}printf("%d\n", count);
}

Func3函数的基本操作次数

        T(N)=100

        用大O渐进表示法 表示 O(1)

2.2.4、示例四

const char* strchr(const char* str, int character)
{const char* p_begin = s;while (*p_begin != character){if (*p_begin == '\0')return NULL;p_begin++;}return p_begin;
}

这里计算strchr函数的基本操作次数       

        如果查找的字符在字符串的第一个位置(靠前的位置)则T(N)= 1

        如果查找的字符在字符串最后 则T(N)=  N

        如果查找的字符在字符串中间位置 则T(N)= N/2

这样用大O渐进表示法就要三种情况

情况一: O(1)        情况二: O(N)        情况三: O(N)

这里我们就会发现,有些算法的时间复杂度存在多种情况

        最好情况 : 任意出入规模的最小运行次数(下界)

        最坏情况 : 任意输入规模的最大运行次数(上界)

        平均情况: 任意输入规模的期望运行次数

大O渐进表示法在实际情况中一般关注的是算法的上界,也就是最坏运行情况。

所以这里strchr函数的时间复杂度为:O(N)

2.2.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;}
}

冒泡排序的时间复杂度

        如果数组有序为升序,则T(N) = N (最好情况)

        如果数组有序为降序,则T(N) = (N*(N+1))/2 (最坏情况)

因此BubbleSort的时间复杂度为 O(N^2)

2.2.6、示例六

void func4(int n)
{int cnt = 1;while (cnt < n){cnt *= 2;}
}

Func4函数

        n=2,执行次数为1

        n=4,执行次数为2

        n=16,执行次数为4

        当执行次数为x时,n=2^x

        所以执行次数 x=

所以时间复杂度为:

这里也可以写成log n

        当N接近无穷大时,底数的大小对结果影响不大。因此,一般情况下不管底数为多少都可以省略不写,写成log n

2.2.7、示例七

long long Fac(size_t N)
{if (0 == N)return 1;return Fac(N - 1) * N;
}

这里每一次调用Fac函数的时间复杂度为O(1)

        而一共有n次递归,所以阶乘递归的时间复杂度为O(N)

三、空间复杂度

        空间复杂度也是一个数学表达式,是对一个算法在运行过程中因为算法的需要额外临时开辟的空间

        空间复杂度表示程序占用了多少bytes的空间,因为常规情况下每个对象大小 差异不会很大,所以空间复杂度计算的是变量的个数

        空间复杂度也使用大O渐进表示法

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

空间复杂度计算

示例一

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

函数栈帧在编译期间已经确定好了,只需关注函数在运行时额外申请的空间

BubbleSort额外申请的空间有exchange等有限个局部变量,使用了常数个额外的空间

        因此时间复杂度为:O(1)

示例二

long long Fac(size_t N)
{if (N == 0)return 1;return Fac(N - 1) * N;
}

Fac递归调用了N次,额外开辟了N个函数栈帧,每个栈帧使用了常数个空间

        因此时间复杂度为:O(N)

感谢各位大佬支持并指出问题,

                如果本篇内容对你有帮助,可以一键三连支持以下,感谢支持!!!

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

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

相关文章

[C++]——同步异步日志系统(3)

同步异步日志系统 一、日志系统框架设计1.1模块划分1.1.1 日志等级模块1.1.2 日志消息模块1.1.3 日志消息格式化模块1.1.4 日志落地模块&#xff08;日志落地的方向是工厂模式&#xff09;1.1.5 日志器模块&#xff08;日志器的生成是建造者模式&#xff09;1.1.6 异步线程模块…

强化学习总结(有具体代码实现)

文章目录 第一部分 强化学习基础第1章 强化学习概述1.1 强化学习概念1.2 强化学习的环境1.3 强化学习的目标1.4 强化学习的数据 第2章 多臂老虎机问题&#xff08;MAB问题&#xff09;2.1 问题描述2.1.1 问题定义2.1.2 形式化描述2.1.3 累积懊悔2.1.4 估计期望奖励 2.2 解决方法…

【机器学习】必会数学知识:一文掌握数据科学核心数学知识点(上),值得收藏~

核心数学知识点 1、引言2、数据科学必会数学知识2.1 线性代数2.2 微积分2.3 概率论2.4 数理统计2.5 随机过程2.6 数据分布2.7 贝叶斯统计2.8 线性回归2.9 逻辑回归2.10 矩阵分解2.11 主成分分析&#xff08;PCA&#xff09;2.12 奇异值分解&#xff08;SVD&#xff09; 3、总结…

【人工智能大语言模型技术发展研究报告 2024】

文末‍有福利&#xff01; 人工智能作为引领新一轮科技产业革命的战略性技术和新质生产力重要驱动力&#xff0c;正在引发经济、社会、文化等领域的变革和重塑&#xff0c;2023 年以来&#xff0c;以 ChatGPT、GPT-4 为代表的大模型技术的出台&#xff0c;因其强大的内容生成及…

提升教师健康,聚焦智慧校园人事系统的职工体检功能

智慧校园人事管理系统内置的职工体检管理&#xff0c;是专为教职员工设计的一项健康管理创新实践&#xff0c;巧妙融合先进信息技术&#xff0c;致力于为教职工提供更加便捷、易懂且持续性的健康检查与管理支持。该服务从多个维度出发&#xff0c;全面呵护教职工的身心健康。 该…

给你的博客加上评论区

一个网站如果有评论功能&#xff0c;可以更好的和读者互动。VuePress 也有很多评论插件&#xff0c;这里简单介绍下&#xff0c;最后介绍本站所使用的 Twikoo。 大部分评论插件都是使用的 Github 或 Gitee 的 issue 功能&#xff0c;也就是用 issue 去存储评论&#xff1b;而 …

脚本实现保留文本中特定字符之后的字符串

#目的背景 原始txt文本如下图 目的是为了去除序号&#xff0c;每行只单独呈现域名 手工删除漫长又麻烦&#xff0c;使用脚本快捷些 代码实现逻辑&#xff1a; 1.使用open函数打开文本&#xff0c;之后用变量lines存储文本的所有行&#xff0c;使用for循环&#xff0c;让变量te…

暑假学习计划怎么做 用待办计划软件安排更科学

暑期来临&#xff0c;无论是学生还是老师&#xff0c;做好暑期计划都至关重要。记得去年暑假&#xff0c;我给自己定下了阅读十本书的目标&#xff0c;却因为缺乏明确的计划&#xff0c;最后只草草读完了两本。而今年&#xff0c;我决定尝试一种新的方式——使用待办计划软件来…

谷粒商城实战笔记-24-分布式组件-SpringCloud Alibaba-Nacos配置中心-命名空间与配置分组

文章目录 一&#xff0c;命名空间1&#xff0c;简介1.1&#xff0c;命名空间的主要功能和特点1.2&#xff0c;使用场景1.3&#xff0c;如何指定命名空间 2&#xff0c;命名空间实战2.1&#xff0c;环境隔离2.2&#xff0c;服务隔离 二&#xff0c;配置集三&#xff0c;配置集ID…

js原型和类---prototype,__proto__,new,class

原型和原型链 在js中&#xff0c;所有的变量都有原型&#xff0c;原型也可以有原型&#xff0c;原型最终都指向Object 什么是原型 在js中&#xff0c;一个变量被创建出来&#xff0c;它就会被绑定一个原型&#xff1b;比如说&#xff0c;任何一个变量都可以使用console.log打…

PostgreSQL 中如何实现数据的增量更新和全量更新的平衡?

文章目录 一、增量更新与全量更新的概念增量更新全量更新 二、考虑的因素1. 数据量2. 数据更改的频率和规模3. 数据一致性要求4. 系统性能和资源利用5. 业务逻辑和流程 三、解决方案&#xff08;一&#xff09;混合使用增量更新和全量更新&#xff08;二&#xff09;使用临时表…

暑期旅游季必备,用这款客服神器应对爆棚的客流咨询

解决暑期旅游客流高峰问题 暑期是旅游高峰季节&#xff0c;客流量剧增&#xff0c;客户咨询纷至沓来。在这个时候&#xff0c;如何高效处理客户的咨询成为每家旅游机构和景点不可忽视的挑战。 聊天宝快捷回复助手是一款强大的工具&#xff0c;可帮助企业在客流高峰期快速回复客…

MemFire Cloud: 一种全新定义后端即服务的解决方案

在这个快节奏的互联网时代&#xff0c;开发者们最希望的就是能够省时省力地完成项目&#xff0c;快速上线。然而&#xff0c;搭建服务、开发接口API、处理各种后端问题&#xff0c;往往让人头疼不已。别担心&#xff0c;现在有了MemFire Cloud&#xff0c;一款为懒人开发者量身…

制作电子名片的小程序系统源码 快速生成电子名片

在当今数字化时代&#xff0c;传统的纸质名片已逐渐被智能电子名片所取代。电子名片小程序作为一种基于微信生态的创新名片交换方式&#xff0c;凭借其便捷性、高效性和环保性&#xff0c;成为了众多商务人士的首选。小编分享一个制作电子名片的小程序系统源码&#xff0c;无忧…

malloc实现原理【Liunx】

malloc实现原理 malloc是什么&#xff1f;malloc,calloc, realloc的区别malloc的实现原理malloc的两种实现方式为什么使用brk&#xff1f;为什么使用mmap&#xff1f; malloc怎么定界的malloc分配的是虚拟内存上的空间吗&#xff1f; malloc是什么&#xff1f; 通过malloc&…

LinK3D: Linear Keypoints Representation for 3D LiDAR Point Cloud【翻译与解读】

LinK3D: Linear Keypoints Representation for 3D LiDAR Point Cloud 摘要 特征提取和匹配是许多机器人视觉任务的基本组成部分&#xff0c;如 2D 或 3D 目标检测、识别和配准。2D 特征提取和匹配已取得巨大成功。然而&#xff0c;在 3D 领域&#xff0c;当前方法由于描述性差…

2024前端面试题之Vue3

2024前端面试题之Vue3 在面试具有五年经验的前端工程师时&#xff0c;对于 Vue 3 的掌握程度是一个重要的考核点。本文将提供一系列针对这一级别工程师的 Vue 3 面试题&#xff0c;并附上详细的解析&#xff0c;帮助面试官全面评估候选人的技术实力和项目经验。 一、Vue 3 基础…

vscode-server安装和部分配置

文章目录 前言code-server安装rpm包安装tar.gz安装 vscode部分配置vscode配置函数跳转安装插件 vscode的structurevscode的hierarchy更改颜色主题 前言 vscode确实彳亍&#xff0c;虽然我觉得Clion(c/c语言版的IDEA)更方便&#xff0c;但是毕竟我没钱买license 这里记录一下网…

11410-00SF 同轴连接器

型号简介 11410-00SF是Southwest Microwave的连接器。该连接器的外壳采用优质不锈钢&#xff0c;材质为 CRES ALLOY UNS-S303500&#xff0c;符合 ASTM-A582 标准。首先&#xff0c;不锈钢材料经过锻造加工&#xff0c;形成转接器的基本形状。然后&#xff0c;外壳进行精密的 C…

CentOS7忘记root密码无法登陆解决方法

重启服务器&#xff0c;等到如图下所示界面的时候&#xff0c;快速按下键盘的↑或者↓按键&#xff0c;等固定住画面&#xff0c;然后按下e按键 然后按键盘上的↓按键&#xff0c;找到图下所示的linux16开头的那段&#xff0c;然后把光标挪到ro这里 按照图下所示&#xff0c;把…