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

【数据结构】_复杂度

目录

1. 算法效率

2. 时间复杂度

2.1 时间复杂度概念

2.2 准确的时间复杂度函数式

2.3 大O渐进表示法

2.4 时间复杂度的常见量级

2.5 时间复杂度示例

3. 空间复杂度

3.1 空间复杂度概念

3.2 空间复杂度示例


1. 算法效率

一般情况下,衡量一个算法的好坏是从时间和空间两个维度来衡量的。

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

2. 时间复杂度

2.1 时间复杂度概念

在计算机科学中算法的时间复杂度是一个函数,一个算法所花费的时间与其中语句的执行次数成比例,算法中的基本操作的执行次数,为算法的时间复杂度

即:找到某条基本语句与问题规模N之间的数学表达式,就是算出了该算法的时间复杂度。

注:不能直接用运行时间来定义一个算法的时间复杂度,一个算法的运行时间与硬件的配置存在联系,同样一个算法无法算出准确时间。而时间复杂度与具体机器无关。

2.2 准确的时间复杂度函数式

对于以下代码:

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*N+2*N+10,这是准确的时间复杂度函数式,计算的结果是算法运行的准确次数。

但其意义并不大,计算时间复杂度时,并不一定要计算出准确的执行次数,只需要大概执行次数表示算法效率所在量级即可,故而引进大O的渐进表示法。

2.3 大O渐进表示法

当不方便在算法之间比较准确时间复杂度函数式时,使用大O的渐进表示法对其进行简化。

简单而言,大O渐进表示法是估算一个算法的数量级而非准确数值。

具体而言,推导大O阶方法:

(1)用常数1取代运行时间中的所有加法常数;(O(1)代表常数次,而非1次)

(2)在修改后的运行次数函数中,只保留最高阶项

(3)如果最高阶项存在且不是1,则去除与这个项目相乘的常数

得到的结果就是大O阶。

2.4 时间复杂度的常见量级

按数量级递增排列,常见的时间复杂度有:

O(1)<=O(log N)<=O(N)<=O(Nlog N)<=O(n^2)<=O(n^3)<=...<=n^k<=O(2^n)

随着问题规模N的不断增大,上述时间复杂度不断增大,算法的执行效率越低,若复杂度超过O(N^3)则该算法效率已经非常低,没有运行的必要。

2.5 时间复杂度示例

示例1:

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

时间复杂度为O(N)=N;(时间复杂度准确函数式:F(N)=2*N+10)

示例2:

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

当N、M大小未知时,时间复杂度表示为O(N+M);

当N远大于M时,时间复杂度表示为O(N);

当M远大于N时,时间复杂度表示为O(M);

当N、M属于一个量级时,时间复杂度表示为O(M)或O(N)均可;

示例3:

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

时间复杂度表示为O(1);

示例4:

const char * strchr ( const char * str, int character );

该算法的时间复杂度最好1次,最坏N次,时间复杂度一般看最坏情况,为O(N);

注:(1)strstr为字符串查找函数,详细内容见下文:

【C语言】_字符串查找函数strstr_c语言查找字符-CSDN博客文章浏览阅读147次,点赞9次,收藏5次。注:关于上文strstr函数的模拟实现,还有很大优化空间,包括但不限于KMP算法,本篇仅实现简单的匹配功能,暂不考虑效率。(2)待匹配字符串str2需逐字符在str1中进行对应查找匹配,将用于遍历str2的指针变量记为s2,类型为char*;(3)str2需与str1中的字符逐字符进行匹配,需设遍历str1的指针变量,记为s1,类型为char*;(1)返回值为第一次匹配的str2在str1中的位置,记为cur,类型为char*;strstr函数功能:在str1中查找str2;若未找到,则返回空指针;_c语言查找字符https://blog.csdn.net/m0_63299495/article/details/145165702https://blog.csdn.net/m0_63299495/article/details/145165702https://blog.csdn.net/m0_63299495/article/details/145165702(2)在算法时间复杂度计算时,一般会采取保守估计,将最坏情况作为时间复杂度。

最坏情况:任意输入规模的最大运行次数(上界)
平均情况:任意输入规模的期望运行次数
最好情况:任意输入规模的最小运行次数(下界)

例如:在一个长度为N数组中搜索一个数据x
最好情况:1次找到
最坏情况:N次找到
平均情况:N/2次找到
在实际中一般情况关注的是算法的最坏运行情况,所以数组中搜索数据时间复杂度为O(N);

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

时间复杂度准确函数式式F(N) = N-1+N-2+...+2+1=((N-1+1)*(N-1))/2=(N*(N-1))/2;

故时间复杂度为O(N^2);

示例6:(二分查找)

int BinarySearch(int* a, int n, int x)
{assert(a);int begin = 0;int end = n - 1;while (begin < end){int mid = begin + ((end - begin) >> 1);if (a[mid] < x)begin = mid + 1;else if (a[mid] > x)end = mid;elsereturn mid;}return -1;
}

二分查找用于有序数组的查找,查找区间变化为N -> N/2 -> N/2/2 -> N/2/2/2 -> ...  -> N/2/2/.../2

① 查找的最好情况为查找一次即找到,即O(1);

② 查找的最坏情况为查找区间只剩一个数或没找到,即 N/2/2/.../2=1,假设查找了x次,即2^x=N,求得最坏情况为O(log N)   ,故时间复杂度为O(log N) ;

注:在时间复杂度的表示中,log₂N 可简写为 log N,不准确表达也有lg N。

在时间复杂度表示中,默认 log N 的底数为2。

示例7:(阶乘)

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

Fac(N)调用Fac(N-1), Fac(N-1)调用Fac(N-2)...Fac(2)调用Fac(1),Fac(1)调用Fac(0),共调用N+1次,且单次调用复杂度为O(1),递归的时间复杂度是所有递归调用次数的累加:

故时间复杂度为O(N);

示例8:

long long Fib(size_t N)
{if (N < 3)return 1;return Fib(N - 1) + Fib(N - 2);
}

 复杂度具体函数可以近似为Fib(N)=2^0 + 2^1 + 2^2 + ...... + 2^(N-2) = 2^(N-1) - 1:

时间复杂度为O(2^N);(仅有理论意义,实际几乎不用)

注:当N不是非常大时,通常使用循环代替递归计算斐波那契数列,可降低时间复杂度为O(N):

long long Fib(size_t N) {long long f1 = 1;long long f2 = 2;long long f3 = 0;for (size_t i = 3; i <= N; i++) {f3 = f1 + f2;f1 = f2;f2 = f3;}return f3;
}

3. 空间复杂度

3.1 空间复杂度概念

空间复杂度也是一个数学表达式,是对一个算法在运行过程中临时占用存储空间大小的量度。

同时间复杂度一样,具体占用了多少字节的空间大小没有意义,也采用大O渐进表示法,空间复杂度计算的是变量个数

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

3.2 空间复杂度示例

示例1:

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

示例2:

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

空间复杂度是O(N);

示例3:

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

递归调用了N+1次,量级为N,开辟了N个栈帧,每个栈帧使用了常数个空间,空间复杂度为O(N);

示例4:

long long Fib(size_t N)
{if (N < 3)return 1;return Fib(N - 1) + Fib(N - 2);
}

(时间是累积的;空间不累积,可以重复利用)空间复杂度是O(N); 

相较于时间复杂度,空间复杂度更为简单,通常情况下最常见的空间复杂度有O(1)、O(N)(一维数组)、O(N^2)(二维数组);

相关文章:

【数据结构】_复杂度

目录 1. 算法效率 2. 时间复杂度 2.1 时间复杂度概念 2.2 准确的时间复杂度函数式 2.3 大O渐进表示法 2.4 时间复杂度的常见量级 2.5 时间复杂度示例 3. 空间复杂度 3.1 空间复杂度概念 3.2 空间复杂度示例 1. 算法效率 一般情况下&#xff0c;衡量一个算法的好坏是…...

pytorch实现循环神经网络

人工智能例子汇总&#xff1a;AI常见的算法和例子-CSDN博客 PyTorch 提供三种主要的 RNN 变体&#xff1a; nn.RNN&#xff1a;最基本的循环神经网络&#xff0c;适用于短时依赖任务。nn.LSTM&#xff1a;长短时记忆网络&#xff0c;适用于长序列数据&#xff0c;能有效解决…...

Java 16进制 10进制 2进制数 相互的转换

在 Java 中&#xff0c;进行进制之间的转换时&#xff0c;除了功能的正确性外&#xff0c;效率和安全性也很重要。为了确保高效和相对安全的转换&#xff0c;我们通常需要考虑&#xff1a; 性能&#xff1a;使用内置的转换方法&#xff0c;如 Integer.toHexString()、Integer.…...

力扣动态规划-14【算法学习day.108】

前言 ###我做这类文章一个重要的目的还是给正在学习的大家提供方向&#xff08;例如想要掌握基础用法&#xff0c;该刷哪些题&#xff1f;建议灵神的题单和代码随想录&#xff09;和记录自己的学习过程&#xff0c;我的解析也不会做的非常详细&#xff0c;只会提供思路和一些关…...

数据结构day02

1 线性表的定义和基本操作 1.1 线性表的定义 分析&#xff1a; 1.1.1 问题一&#xff1a;我们为什么探讨线性表的定义和基本操作 在研究数据结构时&#xff0c;需要重点关注三个方面&#xff1a;逻辑结构、物理结构以及数据的运算。在本节内容里&#xff0c;我们首先来介绍线…...

随笔 | 写在一月的最后一天

. 前言 这个月比预想中过的要快更多。突然回看这一个月&#xff0c;还有点不知从何提笔。 整个一月可以总结为以下几个关键词&#xff1a; 期许&#xff0c;保持期许出现休息 . 期许 关于期许&#xff0c;没有什么时候比一年伊始更适合设立目标和计划的了。但令人惭愧的…...

JVM方法区

一、栈、堆、方法区的交互关系 二、方法区的理解: 尽管所有的方法区在逻辑上属于堆的一部分&#xff0c;但是一些简单的实现可能不会去进行垃圾收集或者进行压缩&#xff0c;方法区可以看作是一块独立于Java堆的内存空间。 方法区(Method Area)与Java堆一样&#xff0c;是各个…...

一文读懂fgc之cms

一文读懂 fgc之cms-实战篇 1. 前言 线上应用运行过程中可能会出现内存使用率较高&#xff0c;甚至达到95仍然不触发fgc的情况&#xff0c;存在内存打满风险&#xff0c;持续触发fgc回收&#xff1b;或者内存占用率较低时触发了fgc&#xff0c;导致某些接口tp99&#xff0c;tp…...

MYSQL 商城系统设计 商品数据表的设计 商品 商品类别 商品选项卡 多表查询

介绍 在开发商品模块时&#xff0c;通常使用分表的方式进行查询以及关联。在通过表连接的方式进行查询。每个商品都有不同的分类&#xff0c;每个不同分类下面都有商品规格可以选择&#xff0c;每个商品分类对应商品规格都有自己的价格和库存。在实际的开发中应该给这些表进行…...

HTB:Administrator[WriteUP]

目录 连接至HTB服务器并启动靶机 信息收集 使用rustscan对靶机TCP端口进行开放扫描 将靶机TCP开放端口号提取并保存 使用nmap对靶机TCP开放端口进行脚本、服务扫描 使用nmap对靶机TCP开放端口进行漏洞、系统扫描 使用nmap对靶机常用UDP端口进行开放扫描 使用nmap对靶机…...

开源项目Umami网站统计MySQL8.0版本Docker+Linux安装部署教程

Umami是什么&#xff1f; Umami是一个开源项目&#xff0c;简单、快速、专注用户隐私的网站统计项目。 下面来介绍如何本地安装部署Umami项目&#xff0c;进行你的网站统计接入。特别对于首次使用docker的萌新有非常好的指导、参考和帮助作用。 Umami的github和docker镜像地…...

FBX SDK的使用:基础知识

Windows环境配置 FBX SDK安装后&#xff0c;目录下有三个文件夹&#xff1a; include 头文件lib 编译的二进制库&#xff0c;根据你项目的配置去包含相应的库samples 官方使用案列 动态链接 libfbxsdk.dll, libfbxsdk.lib是动态库&#xff0c;需要在配置属性->C/C->预…...

VisionMamba安装

1.安装python环境 conda create -n mamba python3.10.13 -y conda activate mamba2.安装torch环境 conda install cudatoolkit11.8 -c nvidia pip install torch2.1.1 torchvision0.16.1 torchaudio2.1.1 --index-url https://download.pytorch.org/whl/cu1183.安装其他包 c…...

h2oGPT

文章目录 一、关于 h2oGPT二、现场演示特点 三、开始行动安装h2oGPT拼贴画演示资源文档指南开发致谢为什么选择 H2O.ai&#xff1f;免责声明 一、关于 h2oGPT 使用文档、图像、视频等与本地GPT进行私人聊天。100%私人&#xff0c;Apache 2.0。支持oLLaMa、Mixtral、llama. cpp…...

Win10安装MySQL、Pycharm连接MySQL,Pycharm中运行Django

一、Windows系统mysql相关操作 1、 检查系统是否安装mysql 按住win r &#xff08;调出运行窗口&#xff09; 输入service.msc&#xff0c;点击【确定】 image.png 打开服务列表-检查是否有mysql服务 &#xff08;compmgmt.msc&#xff09; image.png 2、 Windows安装MySQL …...

使用Pygame制作“俄罗斯方块”游戏

1. 前言 俄罗斯方块&#xff08;Tetris&#xff09; 是一款由方块下落、行消除等核心规则构成的经典益智游戏&#xff1a; 每次从屏幕顶部出现一个随机的方块&#xff08;由若干小方格组成&#xff09;&#xff0c;玩家可以左右移动或旋转该方块&#xff0c;让它合适地堆叠在…...

【Block总结】ODConv动态卷积,适用于CV任务|即插即用

一、论文信息 论文标题&#xff1a;Omni-Dimensional Dynamic Convolution作者&#xff1a;Chao Li, Aojun Zhou, Anbang Yao发表会议&#xff1a;ICLR 2022论文链接&#xff1a;https://arxiv.org/pdf/2209.07947GitHub链接&#xff1a;https://github.com/OSVAI/ODConv 二…...

RK3568 opencv播放视频

文章目录 一、opencv相关视频播放类1. `cv::VideoCapture` 类主要构造方法:主要方法:2. 视频播放基本流程代码示例:3. 获取和设置视频属性4. 结合 FFmpeg 使用5. OpenCV 视频播放的局限性6. 结合 Qt 实现更高级的视频播放总结二、QT中的代码实现一、opencv相关视频播放类 在…...

《LLM大语言模型+RAG实战+Langchain+ChatGLM-4+Transformer》

文章目录 Langchain的定义Langchain的组成三个核心组件实现整个核心组成部分 为什么要使用LangchainLangchain的底层原理Langchain实战操作LangSmithLangChain调用LLM安装openAI库-国内镜像源代码运行结果小结 使用Langchain的提示模板部署Langchain程序安装langserve代码请求格…...

【搜索回溯算法篇】:拓宽算法视野--BFS如何解决拓扑排序问题

✨感谢您阅读本篇文章&#xff0c;文章内容是个人学习笔记的整理&#xff0c;如果哪里有误的话还请您指正噢✨ ✨ 个人主页&#xff1a;余辉zmh–CSDN博客 ✨ 文章所属专栏&#xff1a;搜索回溯算法篇–CSDN博客 文章目录 一.广度优先搜索&#xff08;BFS&#xff09;解决拓扑排…...

变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析

一、变量声明设计&#xff1a;let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性&#xff0c;这种设计体现了语言的核心哲学。以下是深度解析&#xff1a; 1.1 设计理念剖析 安全优先原则&#xff1a;默认不可变强制开发者明确声明意图 let x 5; …...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下&#xff0c;越来越多的求职者将目光投向了日本及中日双语岗位。但是&#xff0c;一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧&#xff1f;面对生疏的日语交流环境&#xff0c;即便提前恶补了…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

可靠性+灵活性:电力载波技术在楼宇自控中的核心价值

可靠性灵活性&#xff1a;电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中&#xff0c;电力载波技术&#xff08;PLC&#xff09;凭借其独特的优势&#xff0c;正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据&#xff0c;无需额外布…...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢

随着互联网技术的飞速发展&#xff0c;消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁&#xff0c;不仅优化了客户体验&#xff0c;还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用&#xff0c;并…...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户&#xff0c;但你不希望用 root 权限运行 ns-3&#xff08;这是对的&#xff0c;ns3 工具会拒绝 root&#xff09;&#xff0c;你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案&#xff1a;创建非 roo…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词

Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵&#xff0c;其中每行&#xff0c;每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid&#xff0c;其中有多少个 3 3 的 “幻方” 子矩阵&am…...

纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join

纯 Java 项目&#xff08;非 SpringBoot&#xff09;集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...