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

数据结构(1)——算法时间复杂度与空间复杂度

目录

前言

一、算法

1.1算法是什么?

1.2算法的特性

1.有穷性

2.确定性

3.可行性

4.输入

5.输出

二、算法效率

2.1衡量算法效率

1、事后统计方法

2、事前分析估计方法

2.2算法的复杂度

2.3时间复杂度

2.3.1定义

2.3.2大O渐进表示法

2.3.3常见时间复杂度举例

1、O(N)

2、O(N+M)

3.O(1)

4、O(N²)

5、O(logN)

6、O(N)递归

7、O(N²)斐波那契

2.4空间复杂度

2.4.1定义

2.4.2空间复杂度举例

1、O(1)

2、O(N)

2.5常见的函数增长率

总结


前言

“数据结构”是计算机程序设计的重要理论技术基础,它不仅是计算机的核心课程,而且已成为其它理工专业的热门选修课。                                                     ——《数据结构C语言版》严蔚敏


一、算法

1.1算法是什么?

首先,我们总能听见算法算法的,到最后一问你算法是什么?你支支吾吾的回答说不就是一些计算的方式吗?难不成还有其它解释方法。对此,在严蔚敏的书中是这么解释的:

算法(algorithm)是对特定问题求解步骤的一种描述,它是指令的有限序列,其中每一条指令表示一个或者多个操作

我们生活中的问题都需要一定步骤的解决,算法亦如此,你解决一个问题,需要有先后的顺序和方法,最后才能解决好,经过这些操作和步骤,整合起来才是这特定问题的算法。

1.2算法的特性

当然解决问题的算法也是有一些特性的,在这里说明出来:

1.有穷性

一个算法必须是又穷的,要不然在解决什么问题,我们要的是通过算法来获取最后的结果,实现最后的结果,而不是无穷下去,最后什么都得不到。当然是对一些合法的输入值,每一步都可以在有穷的时间内完成,最后也在有穷步之后结束。

2.确定性

算法中每一条操作和指令必须要有明确的含义,这样才能确定要做什么,要干什么,在任何条件下,算法只有唯一的一条执行路径,即对于相同的输入只能得出相同的输出。你得到最后这个结果后,你不能再来一次后不得这个结果了,那么肯定就是出问题了。

3.可行性

这个算法必须是可行的,因为你不可行那你在算什么,算法中的实现都是可以通过已经实现的基本运算执行有限的次数下实现的。

4.输入

一个算法有零个或者多个的输入,这些输入取自某个特定的对象的集合。像有一些不用输入就只需要进行操作的命令。

5.输出

一个算法有一个或者多个的输出,这些输出是同输入有着某些特定的关系的量。

而且通常一个算法的好坏,看看有没有下面的五条:

1、正确性

2、可读性

3、健壮性

4、效率与低存储量需求

如果你的算法满足了这些,那么它就是一个“好”的算法。

二、算法效率

2.1衡量算法效率

一般衡量算法效率有两种方法:

1、事后统计方法

因为很多计算机内部都有计时器的功能,有些可能会精细到毫秒级别,不同的算法的程序可以通过一组或者成千上万组的数据来区分这个算法的优势和劣势,但有这种方式有一个缺陷,就是每一次衡量都需要先运行依据算法编制的程序,并且所得的时间的统计量还依赖于计算机硬件,软件环境等因素,所以有时候会掩盖算法本身的优势和劣势。

2、事前分析估计方法

一个高级程序语言编写的程序在计算机上消耗的时间取决于算法选用的策略、问题的规模、书写程序的语言(因为语言级别越高,执行效率就越低)、编译程序所产生的机器代码的质量、机器执行指令的速度。基于这些要求,我们可以用一个问题规模的函数来分析估计。

2.2算法的复杂度

我们之前提到了算法满足五条就是一个“”的算法,但其中的第四条提到了“效率与低存储需求”,这里判断的方法就涉及到了时间与空间两个方面,也就是看时间复杂度和空间复杂度。

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

2.3时间复杂度

2.3.1定义

在计算机科学中,算法的时间复杂度是一个函数,它定量描述了该算法的运行时间,一个算法执行所耗费的时间,从理论上来说,是不能算出来的,但一个算法所花费的时间与其中的语句的执行次数成正比例,算法中的基本操作的执行次数,为算法的时间复杂度。

例如下面的代码:

for (int i = 0; i < N; i++)
{for (int j = 0; j < N; j++){sum=i+j}
}

我们只需要计算基本语句和问题规模N的数学表达式就可以。

这里是两次循环,每一个循环都是N次循环,所以F(N)=N²。而在这里我们用大O表示法来表示时间复杂度,也就是O(N²)。

2.3.2大O渐进表示法

实际我们在计算机时间复杂度的时候,并不需要一定要计算精准准确的执行次数,而只需要大概执行次数就可以。

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

推导大O阶的方法:

1、用常数1取代运行时间中的所有加法常数

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

3、如果高阶项存在且不是1,则去除与这个项目相乘的常数,得不到的结果就是大O阶。

有些算法的时间复杂度会存在最好、平均和最坏的情况:

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

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

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

例如我们如果在一组数中找一个数:

1 2 3 4 5 6 7 8 9....N

如果找1的话就是最好的情况一次就找到了,最坏的情况就是N次找到,平均就是N/2次找到。

在实际中一般情况关注的是算法最坏的情况,所以它的时间复杂度就是O(N)。

2.3.3常见时间复杂度举例

1、O(N)

void Func1(int N)
{int cout = 0;for (int n = 0; n < 2 * N; n++){++cout;}int cout1 = 5;while (cout1--){++cout;}printf("%d \n", cout);
}

这里我们可以进行推导,来计算基本语句和问题规模N的函数等于什么?这里经历了一个循环N次,接下来又是一个常数的循环,最后也就是F(N)=N+5。

因为时间复杂度里面有常数要舍去,所以最后用大O表示也就是O(N)。

2、O(N+M)

void Func2(int N, int M)
{int cout = 0;for (int i = 0; i < N; i++){cout++;}for (int i = 0; i < M; i++){cout++;}printf("%d \n", cout);
}

这里同样的,计算基本语句和问题规模N,M的数学表达式:

第一个循环循环了N次,第二个循环了M次,所以最后是F(N,M)=N+M,时间复杂度也就是O(N+M)。

3.O(1)

void Func3(int N)
{int cout = 0;for (int i = 0; i < 10000; i++){cout++;}printf("%d \n", cout);
}

这里也就是找N和基本语句的表达式,我们发现这里就一个循环了10000次,是一个常数,用大O表示就是O(1)。

4、O(N²)

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

这里是一个简单的冒泡排序,Swap是用来交换数字的,这里计算一下问题规模n的函数表达式;

这是一个嵌套循环,外面一层循环走了n次,里面的从1开始循环,如果前一个大于当前的数字就交换,这里可以发现得需要除以2,所以最好的情况下就是一趟循环就找到了,也就是O(N),最坏就是两层,也就是F(N)=N*(N+1)/2,也就是O(N²)。

5、O(logN)

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

这是一个经典的用二分查找x的值,这里就是找出问题规模n的表达式。我们知道二分查找是折半的,每一次都是平方倍的,所以n=N²,则F(N)=logN,(以二为敌N的对数),最好情况就是O(1),最坏就是O(logN)。

6、O(N)递归

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

这里给出了一个递归计算阶乘,找问题规模N的表达式,这里我们反着推也就是N*(N-1)*(N-2)...*1,我们发现中间经历的N次,所以F(N)=N;所以用大O表示就是O(N)。

7、O(2ⁿ)斐波那契

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

这里就是一个斐波那契数列,这里也是通过递归进行两次两次的实现,所以最后也就是表示N需要2ⁿ次,也就是用大O表示法就是O(2ⁿ)。

2.4空间复杂度

2.4.1定义

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

空间复杂度不是程序占用了多少字节的空间,而是算的是变量的个数,计算规则基本和时间复杂度类似,也是用大O渐进表示法。

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

这里说一下:根据经验大多数空间复杂度都是O(1)或者O(N)。

2.4.2空间复杂度举例

1、O(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、O(N)

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

这里是那个阶乘的递归,我们知道递归调用的时候是调用自身,并且也是占用栈帧的,所以这里就是调用了N次,也就是开辟了N个栈帧,而每一个栈帧用了常数个变量,所以这里的空间复杂度就是O(N)。

2.5常见的函数增长率

这里给出常见的函数增长率:


总结

今天主要对算法,算法的时间、空间复杂度进行了分析和学习,这里会计算会看就可以。

相关文章:

数据结构(1)——算法时间复杂度与空间复杂度

目录 前言 一、算法 1.1算法是什么&#xff1f; 1.2算法的特性 1.有穷性 2.确定性 3.可行性 4.输入 5.输出 二、算法效率 2.1衡量算法效率 1、事后统计方法 2、事前分析估计方法 2.2算法的复杂度 2.3时间复杂度 2.3.1定义 2.3.2大O渐进表示法 2.3.3常见时间复…...

K8s运维管理平台 - xkube体验:功能较多

目录 简介Lic安装1、需要手动安装MySQL&#xff0c;**建库**2、启动命令3、[ERROR] GetNodeMetric Fail:the server is currently unable to handle the request (get nodes.metrics.k8s.io qfusion-1) 使用总结优点优化 补充1&#xff1a;layui、layuimini和beego的详细介绍1.…...

spring源码阅读系列文章目录

对于spring认识首先要了解 spring相关概念术语&#xff0c;然后是如下的几句话牢记并反射出来&#xff1a; Bean怎么来的&#xff0c;通过BeanDefinitionBeanDefinition有Spring框架内置的&#xff0c;有手动定义或者自动配置扫描出来的&#xff08;写个Demo工程&#xff09;B…...

快速提升网站收录:利用网站新闻发布功能

本文转自&#xff1a;百万收录网 原文链接&#xff1a;https://www.baiwanshoulu.com/63.html 利用网站新闻发布功能快速提升网站收录是一个有效的策略。以下是一些具体的建议&#xff0c;帮助你更好地利用这一功能&#xff1a; 一、保持新闻更新频率 搜索引擎尤其重视网站的…...

【14】WLC3504 HA配置实例

1.概述 本文档使用 Cisco WLC 3504 实现无线控制器的高可用性。这里所指的HA是指WLC设备box-to-box的冗余。换句话说,即1:1的设备冗余,其中一个 WLC 将处于Active活动状态,而第二个 WLC 将处于Standby-hot热待机状态,通过RP冗余端口持续监控活动 WLC 的运行状况。两个 WLC…...

什么是LPU?会打破全球算力市场格局吗?

在生成式AI向垂直领域纵深发展的关键节点&#xff0c;一场静默的芯片革命正在改写算力规则。Groq研发的LPU&#xff08;Language Processing Unit&#xff09;凭借其颠覆性架构&#xff0c;不仅突破了传统GPU的性能天花板&#xff0c;更通过与DeepSeek等国产大模型的深度协同&a…...

智慧物业管理系统实现社区管理智能化提升居民生活体验与满意度

内容概要 智慧物业管理系统&#xff0c;顾名思义&#xff0c;是一种将智能化技术融入社区管理的系统&#xff0c;它通过高效的手段帮助物业公司和居民更好地互动与沟通。首先&#xff0c;这个系统整合了在线收费、停车管理等功能&#xff0c;让居民能够方便快捷地完成日常支付…...

Vue3 表单:全面解析与最佳实践

Vue3 表单&#xff1a;全面解析与最佳实践 引言 随着前端技术的发展&#xff0c;Vue.js 已经成为最受欢迎的前端框架之一。Vue3 作为 Vue.js 的最新版本&#xff0c;带来了许多改进和新的特性。其中&#xff0c;表单处理是 Vue 应用中不可或缺的一部分。本文将全面解析 Vue3 …...

MySQl的日期时间加

MySQL日期相关_mysql 日期加减-CSDN博客MySQL日期相关_mysql 日期加减-CSDN博客 raise notice 查询目标 site:% model:% date:% target:%,t_shipment_date.site,t_shipment_date.model,t_shipment_date.plant_date,v_date_shipment_qty_target;...

实战:如何利用网站日志诊断并解决收录问题?

本文转自&#xff1a;百万收录网 原文链接&#xff1a;https://www.baiwanshoulu.com/50.html 利用网站日志诊断并解决收录问题是一种非常有效的方法。以下是一个实战指南&#xff0c;帮助你如何利用网站日志来诊断并解决网站的收录问题&#xff1a; 一、获取并分析网站日志 …...

每日一题——有效括号序列

有效括号序列 题目描述数据范围&#xff1a;复杂度要求&#xff1a; 示例题解代码实现代码解析1. 定义栈和栈操作2. 栈的基本操作3. 主函数 isValid4. 返回值 时间和空间复杂度分析 题目描述 给出一个仅包含字符 (, ), {, }, [, ] 的字符串&#xff0c;判断该字符串是否是一个…...

PyTorch数据建模

回归分析 import torch import numpy as np import pandas as pd from torch.utils.data import DataLoader,TensorDataset import time strat = time.perf_counter()...

OpenAI 实战进阶教程 - 第二节:生成与解析结构化数据:从文本到表格

目标 学习如何使用 OpenAI API 生成结构化数据&#xff08;如 JSON、CSV 格式&#xff09;。掌握解析数据并导出表格文件的技巧&#xff0c;以便适用于不同实际场景。 场景背景 假设你是一名开发人员&#xff0c;需要快速生成一批产品信息列表&#xff08;如名称、价格、描述…...

二叉树--链式存储

1我们之前学了二叉树的顺序存储&#xff08;这种顺序存储的二叉树被称为堆&#xff09;&#xff0c;我们今天来学习一下二叉树的链式存储&#xff1a; 我们使用链表来表示一颗二叉树&#xff1a; ⽤链表来表⽰⼀棵⼆叉树&#xff0c;即⽤链来指⽰元素的逻辑关系。通常的⽅法是…...

Windows 中的 WSL:开启你的 Linux 之旅

今天在安装windows上安装Docker Desktop的时候&#xff0c;遇到了WSL。下面咱们就学习下。 欢迎来到涛涛聊AI 一、什么是 WSL&#xff1f; WSL&#xff0c;全称为 Windows Subsystem for Linux&#xff0c;是微软为 Windows 系统开发的一个兼容层&#xff0c;它允许用户在 Win…...

2.3学习总结

今天做了下上次测试没做出来的题目&#xff0c;作业中做了一题&#xff0c;看了下二叉树&#xff08;一脸懵B&#xff09; P2240&#xff1a;部分背包问题 先求每堆金币的性价比&#xff08;价值除以重量&#xff09;&#xff0c;将这些金币由性价比从高到低排序。 对于排好…...

前端力扣刷题 | 6:hot100之 矩阵

73. 矩阵置零 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 法一&#xff1a; var setZeroes function(matrix) {let setX new Set(); // 用于存储需要置零的行索引let setY new Set(); //…...

docker gitlab arm64 版本安装部署

前言&#xff1a; 使用RK3588 部署gitlab 平台作为个人或小型团队办公代码版本使用 1. docker 安装 sudo apt install docker* 2. 获取arm版本的gitlab GitHub - zengxs/gitlab-arm64: GitLab docker image (CE & EE) for arm64 git clone https://github.com/zengxs…...

路径规划之启发式算法之二十九:鸽群算法(Pigeon-inspired Optimization, PIO)

鸽群算法(Pigeon-inspired Optimization, PIO)是一种基于自然界中鸽子群体行为的智能优化算法,由Duan等人于2014年提出。该算法模拟了鸽子在飞行过程中利用地标、太阳和磁场等导航机制的行为,具有简单、高效和易于实现的特点,适用于解决连续优化问题。 更多的仿生群体算法…...

【AudioClassificationModelZoo-Pytorch】基于Pytorch的声音事件检测分类系统

源码&#xff1a;https://github.com/Shybert-AI/AudioClassificationModelZoo-Pytorch 模型测试表 模型网络结构batch_sizeFLOPs(G)Params(M)特征提取方式数据集类别数量模型验证集性能EcapaTdnn1280.486.1melUrbanSound8K10accuracy0.974, precision0.972 recall0.967, F1-s…...

Opyrator UI设计技巧:5个Streamlit自动生成界面教程

Opyrator UI设计技巧&#xff1a;5个Streamlit自动生成界面教程 【免费下载链接】opyrator &#x1fa84; Turns your machine learning code into microservices with web API, interactive GUI, and more. 项目地址: https://gitcode.com/gh_mirrors/op/opyrator Opyr…...

2003 - MySQL连接localhost失败(10061错误)的全面排查指南

1. 为什么会出现MySQL连接localhost失败&#xff08;10061错误&#xff09;&#xff1f; 当你兴致勃勃地打开数据库客户端准备大干一场时&#xff0c;突然蹦出个"2003 - Cant connect to MySQL server on localhost(10061)"的错误提示&#xff0c;是不是瞬间就懵了&a…...

Go UUID终极指南:为什么选择go.uuid而非标准库的5大理由

Go UUID终极指南&#xff1a;为什么选择go.uuid而非标准库的5大理由 【免费下载链接】go.uuid UUID package for Go 项目地址: https://gitcode.com/gh_mirrors/go/go.uuid 在Go语言开发中&#xff0c;生成全局唯一标识符&#xff08;UUID&#xff09;是常见的需求。虽然…...

5分钟搞定高精度人脸检测:MogFace工具零基础部署与使用教程

5分钟搞定高精度人脸检测&#xff1a;MogFace工具零基础部署与使用教程 1. 前言&#xff1a;为什么选择MogFace&#xff1f; 人脸检测技术已经广泛应用于我们的日常生活中&#xff0c;从手机相册的人脸分类到社交媒体的美颜滤镜&#xff0c;都离不开这项基础技术。然而在实际…...

Marin说PCB之GMSL2 POC电路优化实战---从仿真到测试的完整解析

1. GMSL2 POC电路问题诊断与优化思路 最近在测试GMSL2 POC电路时遇到了一个典型问题&#xff1a;多路信号的插损&#xff08;S21&#xff09;和回损&#xff08;S11&#xff09;指标不达标。这种情况在实际项目中并不少见&#xff0c;但每次遇到都需要我们仔细分析原因并找到有…...

PyTorch训练监控神器:用TensorBoard实时可视化Loss曲线与特征图变化(附代码)

PyTorch训练监控神器&#xff1a;用TensorBoard实时可视化Loss曲线与特征图变化&#xff08;附代码&#xff09; 深度学习模型的训练过程往往如同黑箱操作&#xff0c;特别是当模型复杂度增加时&#xff0c;仅靠打印日志很难全面把握训练动态。本文将手把手教你使用TensorBoar…...

解放双手!用Open-AutoGLM实现微信自动回复消息,亲测可用

解放双手&#xff01;用Open-AutoGLM实现微信自动回复消息&#xff0c;亲测可用 1. 为什么需要微信自动回复&#xff1f; 每天我们都会收到大量微信消息&#xff1a;工作群的通知、朋友的问候、家人的关心...但总有那么些时刻&#xff0c;我们无法及时回复&#xff1a; 开会…...

革新性暗黑破坏神2存档管理开源工具:d2s-editor全功能解析

革新性暗黑破坏神2存档管理开源工具&#xff1a;d2s-editor全功能解析 【免费下载链接】d2s-editor 项目地址: https://gitcode.com/gh_mirrors/d2/d2s-editor 暗黑破坏神2存档修改门槛高&#xff1f;复杂二进制格式难以操作&#xff1f;d2s-editor作为免费开源的Web端…...

OpenClaw 网关重启指南:常用指令与故障修复

手把手教你一键部署OpenClaw&#xff0c;连接微信、QQ、飞书、钉钉等&#xff0c;1分钟全搞定&#xff01; 一、几种快速重启的法子 看你当初是怎么部署的&#xff0c;挑下面最适合你的那条命令就行&#xff1a; 适用情况具体命令最省事的&#xff08;系统托管模式&#xff…...

NaViL-9B多模态提示工程:图文联合prompt编写技巧与示例

NaViL-9B多模态提示工程&#xff1a;图文联合prompt编写技巧与示例 1. 多模态模型简介 NaViL-9B是一款原生支持多模态交互的大语言模型&#xff0c;能够同时处理文本和图像输入。与传统的纯文本模型不同&#xff0c;它具备视觉理解能力&#xff0c;可以分析图片内容并与用户进…...