【初探数据结构】时间复杂度和空间复杂度

💬 欢迎讨论:在阅读过程中有任何疑问,欢迎在评论区留言,我们一起交流学习!
👍 点赞、收藏与分享:如果你觉得这篇文章对你有帮助,记得点赞、收藏,并分享给更多对数据结构感兴趣的朋友

文章目录

    • 时间复杂度
      • 时间复杂度的概念
      • 大O渐进表示法
      • 易错建议
    • 空间复杂度
    • 常见的复杂度对比
    • 总结

时间复杂度

时间复杂度的概念

算法执行时间随输入规模(N)增长的渐进趋势的数学函数,具体表现为算法中基本操作的执行次数

由于一个算法所花费的时间与其中语句的执行次数成正比例,所以算法中的基本操作的执行次数,为算法的时间复杂度。

为什么不用时间呢?

  • 不同硬件设备运行速度差异大,实际时间不具备普适性。

即:

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

// 请计算一下Func1中++count语句总共执行了多少次?
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);
}

Func1执行的基本操作次数:
F ( N ) = N 2 + 2 ∗ N + 10 F(N)=N^2+2*N+10 F(N)=N2+2N+10

那么,我们每次表示时间复杂度都要写像这样长长的表达式吗?

麻烦,而且我们没有必要去精确计算执行次数,只需要一个大概次数,所以我们使用大O渐进表示法。

大O渐进表示法

大O符号(Big O notation):是用于描述函数渐进行为的数学符号。
推导大O阶方法:

目标:忽略低阶项和常数系数,聚焦最高阶项的增长趋势。

推导步骤

  1. 用常数1替代所有加法常数(如 F(N)=1000O(1))。

  2. 只保留最高阶项(如 F(N)=N³ + N² + 1O(N³))。

  3. 去除最高阶项的系数(如 F(N)=3N²O(N²))。

使用大O的渐进表示法后,Func1的时间复杂度为:
O ( N 2 ) O(N^2) O(N2)

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

此外,有一些算法的时间复杂的存在最好、最坏和平均的情况:

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

看一个例子:在一个长度为N数组中搜索一个数据x

  • 最坏情况:N次且没有找到
  • 平均情况:N/2次找到
  • 最好情况:1次找到

一般时间复杂度取用算法的最坏运行情况

所以:数组中搜索数据的时间复杂度为O(N)

易错建议

  1. 很多初学者,找时间复杂度习惯用循环去计算,实则很容易出错。建议读者一定要去观察程序的执行逻辑。
    误区:循环层数越多,时间复杂度一定越高。
    反例
		for (int i = 0; i < N; i++) {       // O(N)
		    for (int j = 0; j < 100; j++) { // 固定执行100次
		        // 操作
		    }
		}
		

总时间复杂度为 O(N),而非 O(N²)

  1. 时间复杂度代表的是一个量级。你可以尽你最大的想象力去想象他有多大,我的意思是,他是无法被轻易改变的。如: N − 9999999999999999999999 … … N-9999999999999999999999…… N9999999999999999999999……他的时间复杂度依然为: O ( N ) O(N) O(N)同样的: 9999999999999999999999 … … 9999999999999999999999…… 9999999999999999999999……他的时间复杂度依然为: O ( 1 ) O(1) O(1)

空间复杂度

空间复杂度也是一个数学表达式(函数),是对一个算法在运行过程中临时占用存储空间大小的量度(注意这个临时) 。也使用大O渐进表示法

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

你知道为什么要有这个”临时“吗?

因为空间是可以重复利用的,算法中开辟过的空间重复使用空间复杂度不会增加。
而时间是一去不复返的,无法重复使用。

看一个例题你就明白了

// 计算Fib的空间复杂度?
// 返回斐波那契数列的前n项
long long Fib(size_t N)
{
if(N < 3)
return 1;
return Fib(N-1) + Fib(N-2);
}

这里的时间复杂度不难推导:O(2^N)

那么空间复杂度呢?
也是O(2^N)吗?
没错,这里重复利用了空间,实际上空间复杂度为:
O ( N ) O(N) O(N)

  • 误区:递归算法的空间复杂度一定很高。
    反例:递归遍历链表的空间复杂度为 O(N)(递归栈深度),而迭代法为 O(1)

常见的复杂度对比

在这里插入图片描述
在这里插入图片描述

总结

  • 时间复杂度关注算法执行次数的增长趋势,空间复杂度关注额外空间的占用。

  • 大O渐近表示法通过简化表达式,聚焦主要矛盾。

  • 实际应用中需结合具体场景选择最优算法。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于 MySQL 递归 CTE 实现表,父级id与子级id拼接

1、函数 xr_test.tb_content替换成自己的表 CREATE DEFINERroot% FUNCTION get_related_ids(start_id BIGINT) RETURNS varchar(1000) CHARSET utf8mb4 COLLATE utf8mb4_general_ciDETERMINISTIC BEGINDECLARE result_ids VARCHAR(1000);-- 使用递归 CTE 查找所有相关的 idWI…

Redission可重试、超时续约的实现原理(源码分析)

Redission遇到其他进程已经占用资源的时候会在指定时间waitTime内进行重试。实现过程如下&#xff1a; 执行获取锁的lua脚本时&#xff0c;会返回一个值&#xff0c; 如果获取锁成功&#xff0c;返回nil&#xff0c;也就是java里的null 如果获取锁失败&#xff0c;用语句“PT…

ue----git局域网内部署裸仓库,别的机器进行访问

最近由于经常迁移项目到另一台机器上进行部署更新一点就要整个迁移 弄得麻烦了 就在网上学了一下这个方式 首先我们在想要建立裸仓库的电脑上找到一个文件夹放置我们的裸仓库 在此点击鼠标右键选择 open git bash here 输入命令 创裸仓库 git init --bare gitTestName.git…

输入搜索、分组展示选项、下拉选取,el-select 实现:即输入关键字检索,返回分组选项,选取跳转到相应内容页 —— VUE 项目-全局模糊检索

后端数据代码写于下一篇&#xff1a;输入搜索、分组展示选项、下拉选取&#xff0c;全局跳转页&#xff0c;el-select 实现 —— 后端数据处理代码&#xff0c;抛砖引玉展思路 【效果图】&#xff1a;分组展示选项 >【提供界面操作体验】 【录制效果视频展示】&#xff1a…

【UCB CS 61B SP24】Lecture 11 - Inheritance 4: Iterators, Object Methods学习笔记

本文内容为集合&#xff08;Set&#xff09;的介绍与使用&#xff0c;并通过数组手动实现集合&#xff0c;接着介绍了迭代器&#xff0c;使用迭代器我们能够更方便地遍历集合中的元素。 1. Set 1.1 Set介绍与Java实现类的使用 集合&#xff08;Set&#xff09;是一种常见的数…

玩机日记 12 fnOS使用lucky反代https转发到外网提供服务

目录 1、安装lucky 2、更新lucky 3、上传ssl证书 4、设置安全入口&#xff0c;替换fnOS的应用url 5、添加https反代 这一篇主要是解决一下飞牛反代https的问题。可以先看玩机日记 12.5 在PVE Windows11上部署本地AI模型&#xff0c;使用群晖反代https转发到外网提供服务&a…

神经网络八股(3)

1.什么是梯度消失和梯度爆炸 梯度消失是指梯度在反向传播的过程中逐渐变小&#xff0c;最终趋近于零&#xff0c;这会导致靠前层的神经网络层权重参数更新缓慢&#xff0c;甚至不更新&#xff0c;学习不到有用的特征。 梯度爆炸是指梯度在方向传播过程中逐渐变大&#xff0c;…

【ARM】MDK如何生成指定大小的bin文件,并指定空区域的填充数据

1、 文档目标 解决MDK如何生成指定大小的bin文件&#xff0c;并指定空区域的填充数据 2、 问题场景 客户有这样的需求&#xff0c;客户本身的工程编译生成bin文件后&#xff0c;bin文件大小为200k。整体芯片的内存有512k。客户想要最终生成的bin文件可以达到512k的一个情况&a…

Linux-----进程间通信

一、按通信范围分类 同一主机进程通信 传统IPC方式&#xff1a; 管道&#xff08;无名管道、有名管道&#xff09;信号&#xff08;Signal&#xff09; System V IPC&#xff1a; 共享内存&#xff08;效率最高&#xff09;消息队列信号量 POSIX IPC&#xff08;较新标准&#…

Part 3 第十二章 单元测试 Unit Testing

概述 第十二章围绕单元测试展开&#xff0c;阐述了单元测试的实践与重要性&#xff0c;通过对比其他测试类型&#xff0c;突出其特点&#xff0c;还介绍了单元测试的最佳实践、避免的反模式以及与测试替身相关的内容&#xff0c;为编写高质量单元测试提供指导。 章节概要 1…

Windows10配置C++版本的Kafka,并进行发布和订阅测试

配置的环境为&#xff1a;Release x64下的环境 完整项目&#xff1a;https://gitee.com/jiajingong/kafka-publisher 1、首先下载相应的库文件&#xff08;.lib&#xff0c;.dll&#xff09; 参考链接&#xff1a; GitHub - eStreamSoftware/delphi-kafka GitHub - cloade…

Deepseek引爆AI热潮 防静电地板如何守护数据中心安全

近期&#xff0c;Deepseek的爆火将人工智能推向了新的高度&#xff0c;也引发了人们对AI背后基础设施的关注。作为AI运行的“大脑”&#xff0c;数据中心承载着海量数据的存储、处理和传输&#xff0c;其安全稳定运行至关重要。而在这背后&#xff0c;防静电地板扮演着不可或缺…

Spring框架基本使用(Maven详解)

前言&#xff1a; 当我们创建项目的时候&#xff0c;第一步少不了搭建环境的相关准备工作。 那么如果想让我们的项目做起来方便快捷&#xff0c;应该引入更多的管理工具&#xff0c;帮我们管理。 Maven的出现帮我们大大解决了管理的难题&#xff01;&#xff01; Maven&#xf…

QSplashScreen --软件启动前的交互

目录 QSplashScreen 类介绍 使用方式 项目中使用 THPrinterSplashScreen头文件 THPrinterSplashScreen实现代码 使用代码 使用效果 QSplashScreen 类介绍 QSplashScreen 是 Qt 中的一个类&#xff0c;用于显示启动画面。它通常在应用程序启动时显示&#xff0c;以向用户显…

【Vscode 使用】集合1

一、使用make工具管理工程 windows下&#xff0c;下载mingw64&#xff0c;配置好mingw64\bin 为 Win10系统全局变量后。 在mingw64/bin目录下找到mingw32-make.exe工具。复制一份改名为&#xff1a;make.exe&#xff0c;没错&#xff0c;就是那么简单&#xff0c;mingw64自带m…

PHP-create_function

[题目信息]&#xff1a; 题目名称题目难度PHP-create_function2 [题目考点]&#xff1a; create_function ( string args , string args , string code )[Flag格式]: SangFor{wWx5dEGHHhDUwmST4bpXwfjSzq43I6cz}[环境部署]&#xff1a; docker-compose.yml文件或者docker …

golang内存泄漏

golang也用了好几年了&#xff0c;趁着有空 整理归纳下&#xff0c;以后忘了好看下 一般认为 Go 10次内存泄漏&#xff0c;8次goroutine泄漏&#xff0c;1次是真正内存泄漏&#xff0c;还有1次是cgo导致的内存泄漏 1:环境 go1.20 win10 2:goroutine泄漏 单个Goroutine占用内存&…

Python Seaborn库使用指南:从入门到精通

1. 引言 Seaborn 是基于 Matplotlib 的高级数据可视化库,专为统计图表设计。它提供了更简洁的 API 和更美观的默认样式,能够轻松生成复杂的统计图表。Seaborn 在数据分析、机器学习和科学计算领域中被广泛使用。 本文将详细介绍 Seaborn 的基本概念、常用功能以及高级用法,…

修改与 Git 相关的邮箱

要修改与 Git 相关的邮箱信息&#xff0c;需要区分以下两种情况&#xff1a; 1. 修改 Git 提交时使用的邮箱&#xff08;影响提交记录&#xff09; Git 提交记录中的邮箱由本地 Git 配置的 user.email 决定&#xff0c;与 SSH 密钥无关。修改方法如下&#xff1a; 全局修改&a…

用PyTorch从零构建 DeepSeek R1:模型架构和分步训练详解

DeepSeek R1 的完整训练流程核心在于&#xff0c;在其基础模型 DeepSeek V3 之上&#xff0c;运用了多种强化学习策略。 本文将从一个可本地运行的基础模型起步&#xff0c;并参照其技术报告&#xff0c;完全从零开始构建 DeepSeek R1&#xff0c;理论结合实践&#xff0c;逐步…