当前位置: 首页 > news >正文

【数据结构】初探时间与空间复杂度:算法评估与优化的基础

🚩纸上得来终觉浅, 绝知此事要躬行。
🌟主页:June-Frost
🚀专栏:数据结构

🔥该文章主要了解算法的时间复杂度与空间复杂度等相关知识。

目录:

  • 🌏 时间复杂度
    • 🔭 一些例子
  • 🌎 空间复杂度
  • ❤️ 结语

📗时间复杂度和空间复杂度是计算机科学中用来评估算法效率的两个重要概念。它们分别描述了算法在执行时间和额外内存使用方面的需求,帮助我们了解算法在处理输入数据时所需的资源。在计算机发展的早期,计算机的存储容量很小。所以对空间复杂度很是在乎。但是经过计算机行业的迅速发展,计算机的存储容量已经达到了很高的程度。所以我们如今已经不需要再特别关注一个算法的空间复杂度。

🌏 时间复杂度

 在计算机科学中,算法的时间复杂度是一个函数,用于度量算法执行时间的指标。因为一个算法所花费的时间与其中语句的执行次数成正比例,所以可以认为在算法中的基本操作的执行次数,为算法的时间复杂度
 计算时间复杂度时,其实并不一定要计算精确的执行次数,只需要大概执行次数即可。

✨表示方式为大O的渐进表示法,记作T(n) = O(f(n)),其中T(n)表示算法执行时间,f(n)表示问题规模n的函数。具体来说,当n趋近于无穷大时,算法执行时间的增长趋势与f(n)的增长趋势相同的最高阶项即为该算法的时间复杂度。
✨推导方式:

  • 用常数1取代运行时间中的所有加法常数。
  • 运行次数函数中,只保留最高阶项。
  • 只关注数量级,而忽略常数因子,即去掉系数。

🔭 一些例子

void exampleAlgorithm(int N)
{for (int i = 0; i < N; i++){for (int j = 0; j < N; j++){printf("This is O(n^2) operation.\n");}}for (int k = 0; k < 2 * N; k++){printf("This is O(n) operation.\n");}for (int M = 5; M > 0; M--){printf("This is O(1) operation.\n");}}

 这个例子的函数表达式为 F(N) = N2 +2*N + 5,随着N的不断增加,N2 对最终结果具有决定性的作用,所以N2就是它的量级,运用大O的渐进表示法就可以表示为O(N2) 。

void exampleAlgorithm(int N)
{for (int k = 0; k < 2 * N; k++){printf("This is O(n) operation.\n");}for (int M = 5; M > 0; M--){printf("This is O(1) operation.\n");}}

 如果没有了嵌套,这个函数的表达式就变成了 F(N) = 2*N + 5,这样随着N的增加,有决定性效果的就是2 * N,但是为了简化复杂度的表示,并突出算法随输入数据规模增长的趋势,又因为系数对于这种增长趋势的影响较小,所以一般需要去除系数,时间复杂度为O(N) 。

void exampleAlgorithm()
{for (int M = 1000; M > 0; M--){printf("This is O(1) operation.\n");}}

 如果只有常数阶,那么就可以直接表示为O(1) 。

⚠注意:

📙通过上面这些例子,我们会发现大O的渐进表示法去掉了那些对结果影响不大的项,简洁明了的表示出了执行次数,但是有些算法的时间复杂度存在最好、平均和最坏情况,在实际中一般关注的是算法的最坏运行情况。

④冒泡排序:

void bubble_sort(int* arr, int sz)
{int i = 0;for (i = 0; i < sz - 1; i++){int flag = 1; //标记int j = 0;for (j = 0; j < sz - 1 - i; j++){if (arr[j] > arr[j + 1]){flag = 0;int temp = 0;temp = arr[j + 1];arr[j + 1] = arr[j];arr[j] = temp;}}if (flag == 1)//如果等于1表示数组数据已经有序{break;}}
}

 对于冒泡排序,最好的情况就是本身有序,只需遍历比较一遍数组即可,这时的时间复杂度为O(N),最坏的情况就是逆序,排好第一个数据需要比较N-1次,排好第二个数据需要比较N-2次,…,排好倒数第二个数据需要比较1次,最后一个数据不需要比较,将次数相加就是 [N*(N-1)] / 2,量级为N2,时间复杂度就是O(N2),最终的时间复杂度需要取最坏情况,即O(N2)。

⑤二分查找

int BinarySearch(int* arr, int sz, int k)
{int left = 0;int right = sz - 1;while (left <= right){int mid = (right + left) / 2;if (arr[mid] < k){left = mid + 1;//调整范围}else if (arr[mid] > k){right = mid - 1;//调整范围}else{return mid;}}return -1;
}

📘最好的情况是第一次查找就找到了,为O(1)。
📙最坏的情况为数据在边缘或者数组中没有要查找的数据:
在这里插入图片描述
 一般将 log2N 简写为logN ,所以时间复杂度为 O(logN)。

⑥ 阶乘

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

 调用函数需要创建栈帧,传入参数后,会调用Factorial(N) ,再调用Factorial(N-1),不断调用,直到调用到Factorial(0),共调用了N+1次,每次调用的时间复杂度为O(1),所以最终的时间复杂度为O(N) 。

⑦ 斐波那契数

long long Fibonacci(size_t N)
{if (N <= 2)return 1;return Fibonacci(N - 1) + Fibonacci(N - 2);
}



 将 20 一直加到 2(n-2) ,算法的量级为2n,虽然实际上右边的分支会缺少一部分,但是不会影响到这个量级。


🌎 空间复杂度

 空间复杂度也是一个数学表达式,是对一个算法在运行过程中临时占用存储空间大小的量度 。空间复杂度算的是变量的个数,计算规则基本跟实践复杂度类似,也使用大O渐进表示法。

⚠注意:

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

① 冒泡排序

 冒泡排序属于原地排序,在排序过程中并没有使用额外的空间来帮助排序,那些用来循环的变量,可以看作常数阶,所以冒泡排序的空间复杂度为O(1) 。

②阶乘

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

 阶乘可以看作额外开辟了N个栈帧,每个栈帧空间内部没有额外创建空间,即每个栈帧空间为O(1),最终的空间复杂度为O(N) 。

③斐波那契数

long long Fibonacci(size_t N)
{if (N <= 2)return 1;return Fibonacci(N - 1) + Fibonacci(N - 2);
}


 栈帧空间是可以复用的,所以通常用计算算法所占用的内存空间的最大值来评估算法的空间复杂度,只需要知道在递归中会最大开辟多少栈帧空间就可以进行计算,这个算法最多开辟栈帧数量的量级为N,每个栈帧空间为O(1),所以最终的空间复杂度为O(N)。


❤️ 结语

 文章到这里就结束了,如果对你有帮助,你的点赞将会是我的最大动力,如果大家有什么问题或者不同的见解,欢迎大家的留言~

相关文章:

【数据结构】初探时间与空间复杂度:算法评估与优化的基础

&#x1f6a9;纸上得来终觉浅&#xff0c; 绝知此事要躬行。 &#x1f31f;主页&#xff1a;June-Frost &#x1f680;专栏&#xff1a;数据结构 &#x1f525;该文章主要了解算法的时间复杂度与空间复杂度等相关知识。 目录&#xff1a; &#x1f30f; 时间复杂度&#x1f52d…...

SpringCloud Alibaba - Sentinel 限流规则(案例 + JMeter 测试分析)

目录 一、Sentinel 限流规则 1.1、簇点链路 1.2、流控模式 1.2.1、直接流控模式 1.2.2、关联流控模式 a&#xff09;在 OrderController 中新建两个端点. b&#xff09;在 Sentinel 控制台中对订单查询端点进行流控 c&#xff09;使用 JMeter 进行测试 d&#xff09;分…...

uniapp 条件编译 APP 、 H5 、 小程序

一、#ifdef、#ifndef、 #endif三者的区别、 标识作用#ifdef仅在某个平台上使用#ifndef在除了这个平台的其他平台上使用(非此平台使用&#xff09;#endif结束条件编译 二、平台标识 标识平台APP-PLUS5AppMP微信小程序/支付宝小程序/百度小程序/头条小程序/QQ小程序MP-WEIXIN微…...

深度学习——权重衰减(weight_decay)

深度学习——权重衰减&#xff08;weight_decay) 文章目录 前言一、权重衰减1.1. 范数与权重衰减1.2. 高维线性回归1.3. 从零开始实现1.3.1.初始化模型参数1.3.2. 定义L₂范数惩罚1.3.3. 定义训练代码实现1.3.4. 不管正则化直接训练1.3.5. 使用权重衰减 1.4. 简洁实现 总结 前言…...

nignx如何部署让前端不用清缓存就可以部署

在Nginx中&#xff0c;可以使用以下方法来部署前端应用程序&#xff0c;使前端用户无需清空缓存即可进行部署&#xff1a; 1、使用版本号&#xff1a;在前端应用程序的构建过程中&#xff0c;可以添加一个独特的版本号到应用程序的名称中。每次部署时&#xff0c;将版本号更新…...

CSS3实现动画加载效果

<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>加载效果</title><link rel"style…...

springboot定时任务Scheduled使用和弊端分析

1.springboot定时任务Scheduled使用说明: (1)创建定时任务类 import com.one.utils.DateUtil; import org.springframework.beans.factory.annotation.Autowired; import...

openGauss学习笔记-93 openGauss 数据库管理-访问外部数据库-oracle_fdw

文章目录 openGauss学习笔记-93 openGauss 数据库管理-访问外部数据库-oracle_fdw93.1 编译oracle_fdw93.2 使用oracle_fdw93.3 常见问题93.4 注意事项 openGauss学习笔记-93 openGauss 数据库管理-访问外部数据库-oracle_fdw openGauss的fdw实现的功能是各个openGauss数据库及…...

【Git】Git下载安装环境配置 下载速度慢的解决方案

这里写自定义目录标题 介绍一、下载官网下载镜像站 二、安装安装成功 三、Git三种界面介绍Git cmd界面展示git bash界面展示git GUI界面展示 四、环境配置配置流程1、打开环境变量界面2、添加环境变量 /删除环境变量3、在变量中找到Git\cmd的值就表示配置成功4、没有找到点击新…...

常见源协议介绍

开源协议&#xff08;Open Source License&#xff09;是一种法律文档&#xff0c;用于规定如何使用、修改和分发开源软件和其他开源项目的规则和条件。这些协议允许创作者或组织将其创造的代码或作品以开放源代码的形式共享给他人&#xff0c;以促进协作、创新和知识共享。常见…...

大数据概述(林子雨慕课课程)

文章目录 1. 大数据概述1.1 大数据概念和影响1.2 大数据的应用1.3 大数据的关键技术1.4 大数据与云计算和物联网的关系云计算物联网 1. 大数据概述 大数据的四大特点&#xff1a;大量化、快速化、多样化、价值密度低 1.1 大数据概念和影响 大数据摩尔定律 大数据由结构化和非…...

ES6 class类关键字super

super关键字 在 JavaSCript 中&#xff0c;能通过 extends 关键字去继承父类 super 关键字在子类中有以下用法&#xff1a; 当成函数调用 super() 作为 "属性查询" super.prop 和 super[expr] super() super 作为函数调用时&#xff0c;代表父类的构造函数。 ES6 要求…...

C++并发与多线程(4) | 传递临时对象作为线程参数的一些问题Ⅰ

一、陷阱1 写一个传递临时对象作为线程参数的示例: #include <iostream> #include <vector> #include <thread> using namespace std;void myprint(const int& i, char* pmybuf) {cout << i << endl;cout << pmybuf << endl;r…...

CentOS Integration SIG 正式成立

导读CentOS 董事会已批准成立 CentOS Integration Special Interest Group (SIG)。该小组旨在帮助那些在 Red Hat Enterprise Linux (RHEL) 或特别是其上游 CentOS Stream 上构建产品和服务的人员&#xff0c;验证其能否在未来版本中继续运行。 红帽 RHEL CI 工程师 Aleksandr…...

智能AI系统源码ChatGPT系统源码+详细搭建部署教程+AI绘画系统+已支持OpenAI GPT全模型+国内AI全模型

一、AI创作系统 SparkAi创作系统是基于OpenAI很火的ChatGPT进行开发的Ai智能问答系统&#xff0c;支持OpenAI GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作Chat…...

软考程序员考试大纲(2023)

文章目录 前言一、考试说明1.考试目标2.考试要求3&#xff0e;考试科目设置 二、考试范围考试科目1&#xff1a;计算机与软件工程基本知识1&#xff0e;计算机科学基础2&#xff0e;计算机系统基础知识3&#xff0e;系统开发和运行知识4&#xff0e;网络与信息安全基础知识5&am…...

【重拾C语言】七、指针(一)指针与变量、指针操作、指向指针的指针

目录 前言 七、指针 7.1 指针与变量 7.1.1 指针类型和指针变量 7.1.2 指针所指变量 7.1.3 空指针、无效指针 7.2 指针操作 7.2.1 指针的算术运算 7.2.2 指针的比较 7.2.3 指针的递增和递减 7.3 指向指针的指针 前言 指针是C语言中一个重要的概念正确灵活运用指针 可…...

Kafka源码简要分析

目录 一、生产者的初始化流程 二、生产者到缓冲队列的流程 三、Sender拉取数据到Kafka流程 四、消费者初始化 五、主题订阅原理 六、消费者抓取数据原理 七、消费者组初始化 八、消费者组消费流程 九、提交offset原理 一、生产者的初始化流程 首先获取事务id和客户端…...

react 按住ctrl键,点击时会出现菜单的问题修复

问题描述&#xff1a;我需要按住crtl键&#xff0c;然后鼠标点击后做一些逻辑操作&#xff0c;但是出现如下问题 问题一&#xff1a;按住ctrl键后&#xff0c;点击时不触发click事件&#xff0c;只触发 mousedown和mouseup事件。 问题二&#xff1a;按住ctrl键点击时出现菜单…...

【虚拟机栈】

文章目录 1. 虚拟机栈概述2. 局部变量表(Local Variables)3. 操作数栈4. 动态链接4.1 方法的调用&#xff1a;解析与分配 5. 方法返回地址6. 栈的相关面试题 1. 虚拟机栈概述 每个线程在创建时都会创建一个虚拟机栈&#xff0c;其内部保存一个个的栈帧&#xff08;Stack Frame…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明&#xff1a; 想象一下&#xff0c;你正在用eNSP搭建一个虚拟的网络世界&#xff0c;里面有虚拟的路由器、交换机、电脑&#xff08;PC&#xff09;等等。这些设备都在你的电脑里面“运行”&#xff0c;它们之间可以互相通信&#xff0c;就像一个封闭的小王国。 但是&#…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

HTML 列表、表格、表单

1 列表标签 作用&#xff1a;布局内容排列整齐的区域 列表分类&#xff1a;无序列表、有序列表、定义列表。 例如&#xff1a; 1.1 无序列表 标签&#xff1a;ul 嵌套 li&#xff0c;ul是无序列表&#xff0c;li是列表条目。 注意事项&#xff1a; ul 标签里面只能包裹 li…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

css的定位(position)详解:相对定位 绝对定位 固定定位

在 CSS 中&#xff0c;元素的定位通过 position 属性控制&#xff0c;共有 5 种定位模式&#xff1a;static&#xff08;静态定位&#xff09;、relative&#xff08;相对定位&#xff09;、absolute&#xff08;绝对定位&#xff09;、fixed&#xff08;固定定位&#xff09;和…...

Linux 内存管理实战精讲:核心原理与面试常考点全解析

Linux 内存管理实战精讲&#xff1a;核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用&#xff0c;还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...

Java数值运算常见陷阱与规避方法

整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...

Qemu arm操作系统开发环境

使用qemu虚拟arm硬件比较合适。 步骤如下&#xff1a; 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载&#xff0c;下载地址&#xff1a;https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...

通过 Ansible 在 Windows 2022 上安装 IIS Web 服务器

拓扑结构 这是一个用于通过 Ansible 部署 IIS Web 服务器的实验室拓扑。 前提条件&#xff1a; 在被管理的节点上安装WinRm 准备一张自签名的证书 开放防火墙入站tcp 5985 5986端口 准备自签名证书 PS C:\Users\azureuser> $cert New-SelfSignedCertificate -DnsName &…...

9-Oracle 23 ai Vector Search 特性 知识准备

很多小伙伴是不是参加了 免费认证课程&#xff08;限时至2025/5/15&#xff09; Oracle AI Vector Search 1Z0-184-25考试&#xff0c;都顺利拿到certified了没。 各行各业的AI 大模型的到来&#xff0c;传统的数据库中的SQL还能不能打&#xff0c;结构化和非结构的话数据如何和…...