数据结构-时间、空间复杂度-详解

news2024/11/24 17:16:00

数据结构-时间复杂度-详解

  • 1.前言
    • 1.1数据结构与算法
    • 1.2如何衡量一个算法的好坏
    • 1.3复杂度
  • 2.时间复杂度
    • 2.1是什么
    • 2.2大O符号
      • 只保留最高阶项
      • 不带系数
      • 常数次为`O(1)`
    • 2.3示例
      • 示例2.1
      • 示例2.2
      • 示例2.3
      • 示例2.4
    • 2.4题目
  • 3.空间复杂度
    • 3.1是什么
    • 3.2大O符号
    • 3.3示例
      • 示例1
      • 示例2
      • 示例3
      • 示例4
  • 4.题目类型
      • IO型
      • 接口型

1.前言

1.1数据结构与算法

在计算机科学中,数据结构是一种数据组织、管理和存储的格式。
算法是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制。

通俗来讲,数据结构就是如何在内存中对数据进行管理。
算法就是指如何对内存中的数据进行处理。

1.2如何衡量一个算法的好坏

当小A写了一个快速排序,小B写了一个冒泡排序,二者想要比谁的算法更好。
同样的数据,小A在其低配版的电脑上处理,小B则在高配版的电脑上处理,最后小B的冒泡排序竟比小A的快速排序还快,这能说明快速排序比冒泡排序差吗?显然不能。
为了排除环境差异对算法运行结果的影响,引入了复杂度的概念。

1.3复杂度

复杂度是衡量算法效率的重要标准,分为时间复杂度空间复杂度,今天讲时间复杂度。

2.时间复杂度

2.1是什么

算法的时间复杂度是一个函数,描述了算法运行时间与输入数据规模之间的关系。
简单讲,时间复杂度就是一个算法运行时,大概的基本操作的执行次数


示例1.1:

int fun(int N)
{
	for(int i=0;i<N;i++)
	{
		for(int j=0;j<N;j++)
		{
			//语句一
		}
	}
	for(int i=0;i<2*N;i++)
	{
		//语句二
	}
	for(int i=0;i<10;i++)
	{
		//语句三
	}
}

其中语句一被执行N^2
语句二被执行2*N
语句三被执行10
fun()基本操作的执行次数:

N101001000
次数130102101002010

可以看到,随N增大,次数与最高阶的关系最大,因此在分析时间复杂度时,我们通常关注的是算法运行时间随着输入规模趋于无穷大时的趋势,这里我们使用大O符号

2.2大O符号

大O符号(Big O notation)是用于描述函数渐近行为的数学符号。更确切地说,它是用另一个(通常更简单的)函数来描述一个函数数量级的渐近上界。

推导方法:

只保留最高阶项

如在上面的示例1.1中,f(N)=N^2 + 2*N + 10 ,只保留最高阶项,则时间复杂度O(N^2)

不带系数

示例1.2:

int fun(int N)
{
	for(int i=0;i<2*N;i++)
	{
		//语句二
	}
	for(int i=0;i<10;i++)
	{
		//语句三
	}
}

时间复杂度O(N)
N趋近于无穷,系数的影响可以忽略不计,因此不带系数

常数次为O(1)

示例1.3:

int fun(int N)
{
	for(int i=0;i<10;i++)
	{
		//语句三
	}
}

时间复杂度N(1)
这里的1不是指一次,而是常数次

2.3示例

示例2.1

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

strchr为字符查找函数,作用是在字符串str中寻找目标字符character
查找次数:

最好平均最坏
1次N/2 次N次

当情况不唯一时,选最坏的情况,
时间复杂度O(N),这样可以保证任何情况都能满足预期

示例2.2

冒泡排序

最好最坏
N次N*N/2 次

在冒泡排序前,我们并不知道数组有序无序,因此最好需N
而最坏需N+(N-1)+(N-2)+...+2+1 == N*N/2
因此,时间复杂度O(N^2)

示例2.3

二分查找

最好最坏
1次log2N 次

时间复杂度O(logN)

:在时间复杂度中,由于log2N不好打,因此常用logN代替

对二分查找,只需几组数据就能体会其优越性:

N1000100万10亿
大概的执行次数10次20 次30次

如果将全中国人的信息排好序放入数组,给出一个身份证号码,最多只需31次即可找到那个人的信息。
但二分查找实用性却不强,因为使用其的前提是有序数组
因此,在生活中,用得更多的是红黑树,即一种自平衡二叉查找树

示例2.4

斐波拉契数列的递归写法:
在这里插入图片描述
时间复杂度O(2^N)

N10次20 次30次
大概的执行次数1000100万10亿

这与二分查找处于两个极端,即较少数据就需大量的计算,因此极不推荐使用

2.4题目

消失的数字

题目描述:数组nums包含从0到n的所有整数,但其中缺了一个。请编写代码找出那个缺失的整数。你有办法在O(n)时间内完成吗?

示例 1:

输入:[3,0,1]
输出:2

示例 2:

输入:[9,6,4,2,3,5,7,0,1]
输出:8

法一:
为了做这道题,我首先想到先排序在查找,即使用qsort,但很遗憾,qsort的时间复杂度为O(N*logN)
法二:
异或

int missingNumber(int* nums, int numsSize)
{
    int ret=0;
    for(int i=0;i<numsSize;i++)
    {
        ret^=nums[i];
    }
    for(int i=0;i<=numsSize;i++)
    {
        ret^=i;
    }
    return ret;
}

时间复杂度O(N)
思路:a^a=0a^0=a,因此,ret分别异或数组各元素,并分别异或0~N,得消失的数字
法三:
公式

int missingNumber(int* nums, int numsSize)
{
    int ret=0;
    int i=0;
    for(i=0;i<numsSize;i++)
    {
        ret+=(nums[i]-i);
    }
    return i-ret;
}

时间复杂度O(N)

思路:计算0~N的总和,减去数组元素总和,得消失的数字

3.空间复杂度

3.1是什么

前面我讲到了时间复杂度,它是一个算法运行时,大概的基本操作的执行次数
与此相应,空间复杂度并非指算法运行时所占空间具体大小,如几个比特、几个字节,而指所额外创建的变量个数

3.2大O符号

这里的大O符号,与时间复杂度中的用法完全一致,遵循一下三点:

  • 仅保留最高阶项
  • 不带系数
  • 常数次为 O(1)

在这里插入图片描述

3.3示例

示例1

冒泡排序
在冒泡排序中,更多的是在循环、比较、交换,而未创建新的数组。
为了执行循环、交换,创建了常数个变量,因此,空间复杂度N(1)
这也意味着无论输入数组的大小如何,所需的额外空间都是固定的。

示例2

打印斐波拉契数列前N项
为了打印前N项,必须能够储存这些信息,可创建元素个数为N的数组。
数组的大小直接与输入 N 相关,空间复杂度O(N)

示例3

递归求阶乘
求阶乘的递归方法中,通过函数调用函数、N不断变小,最终返回N!
在此过程中,在函数中只进行了判断、调用、返回等操作,未创建额外的变量。
但,函数在调用时会创建其函数栈帧,每个函数栈帧占常数个空间。
因此,空间复杂度O(N)

示例4

斐波拉契数列递归求第N项
当使用了递归,就意味着会创建新的函数栈帧。
此处,递归写法中,每个函数栈帧未创建额外的变量,占常数个空间。
因此,空间复杂度取决于最多的同时创建的函数栈帧数量。
需明确,在遇到return Fib(n-1)+Fib(n-2),首先执行的是Fib(n-1)
N=5的情况,可得下图:
在这里插入图片描述
可见,最多的同时创建的函数栈帧数量为N-1
空间复杂度O(N)

4.题目类型

平常做题时,大多会遇到两种类型,这里略做介绍:

IO型

scanf拿输入条件,由printf打印输出结果,写的是完整程序。

接口型

输入条件为参数,由返回值返回结果,目的是实现一个函数,写的是部分程序。


本文示例中代码部分较少,很多只给了思路,而未给具体代码,
因为我认为,想求复杂度,最好的方法不是死盯代码,而是画、想。

希望本篇文章对你有所帮助!并激发你进一步探索数据结构和算法的兴趣!

本人仅是个C语言初学者,如果您有任何疑问或建议,欢迎随时留言讨论!让我们一起学习,共同进步!

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

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

相关文章

用4种不同视角理解矩阵乘法

目录 1. 背景 2. 线性方程组视角&#xff08;向量点积视角&#xff09; 3. 列向量观点视角 4. 向量变换视角&#xff08;矩阵函数&#xff09; 5. 坐标变换视角 1. 背景 矩阵诞生于线性方程组的求解&#xff0c;最基本的运算方法来自于高斯消元法&#xff0c;所以矩阵整个…

一些问题的解决方案【持续更新ing】

一些问题的解决方案【持续更新ing】 WindowsCUDA 安装失败解决方案VS 添加现有项无反应无法定位程序输入点 于动态链接库 xxx.exe 上不同工具集生成的库无法通用更改只读属性 UbuntuVTK cmake 过程中找不到QT5目录Ubuntu添加环境变量&#xff08;永久最简单&#xff09;Wandb强…

书橱系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;图书信息管理&#xff0c;图书类型管理&#xff0c;电子书论坛&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;图书信息&#xff0c;电子书论坛&#xff0c;我的 开发系统…

SSRF实验

SSRF实验 SSRF概述实验测试结果 SSRF概述 SSRF服务端请求伪造&#xff0c;是因为网页提供的参数可以获取其他资源&#xff0c;接受网址在本地解析&#xff0c;来获取服务器本身的资源&#xff0c;但解析没过滤导致出现的问题 主要有几个方面的方法 dict 协议是一个在线网络字…

旅游社交小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;每日签到管理&#xff0c;景点推荐管理&#xff0c;景点分类管理&#xff0c;防疫查询管理&#xff0c;美食推荐管理&#xff0c;酒店推荐管理&#xff0c;周边推荐管理 微信端账…

C语言高手参考手册:网络编程高级话题与技术细节(续)

在前两篇文章中&#xff0c;我们介绍了基本的网络编程概念和一些高级话题。本文将继续深入探讨网络编程的高级话题和技术细节&#xff0c;包括更复杂的错误处理策略、高级I/O模型、高级多路复用技术、高级套接字选项、安全编程的最佳实践以及网络编程的调试技巧等。 1. 高级错…

探索数据结构:跳表的分析与实现

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;数据结构与算法 贝蒂的主页&#xff1a;Betty’s blog 1. 跳表的概念 **跳表(Skiplist)**是在有序链表基础上增加了“跳跃”功…

【数据存储】大/小端存储与字节顺序转换函数详解

学习目的是使用&#xff0c;网络编程中主机字节顺序与网络字节顺序转换这块就用到了这些概念及其函数&#xff01; 【Linux网络编程入门】Day5_socket编程基础 文章目录&#xff1a; 大端存储与小端存储 1.1 低地址与高地址 1.2 数据的高位与低位 1.3 大端存储 1.3.1 定义 1.…

轻松打造一个可以切换AI平台的网站

亮色主题 暗色主题 停止按键 设置界面 浏览器缓存设置 Kimi 通义千问 ChatGPT 手机版 部分代码如下&#xff1a; # -*- coding: utf-8 -*- from flask import Flask, request, jsonify, render_template, Response import requests import json import os from gevent import p…

Go反射四讲---第二讲:反射与结构体,使用反射如何操纵结构体?

反射-结构体 这是我们反射四讲的第二讲&#xff0c;本次给大家讲解如何使用反射处理结构体。 使用反射如何输出结构体的字段名字和值,使用反射如何给结构体字段设置值。 为了确保反射输出所有的字段名字和值&#xff0c;关键在于一点只有 Kind Struct 的才有。 注意&#…

Neo4J下载安装

Windows 版本 1、 下载链接安装JDK 下载链接 https://download.oracle.com/java/22/latest/jdk-22_windows-x64_bin.msi 下载完毕后默认安装即可 2、 下载Neo4J 进入Neo4j Deployment Center - Graph Database & Analytics下载页面&#xff0c;选择社区版&#xff0c;…

CentOS全面停服,国产化提速,央国企信创即时通讯/协同门户如何选型?

01. CentOS停服带来安全新风险&#xff0c; 国产操作系统迎来新的发展机遇 2024年6月30日&#xff0c;CentOS 7版本全面停服&#xff0c;于2014年发布的开源类服务器操作系统——CentOS全系列版本生命周期画上了句号。国内大量基于CentOS开发和适配的服务器及平台&#xff0c…

笔记小结:《利用python进行数据分析》之使用pandas和seaborn绘图

matplotlib实际上是一种比较低级的工具。要绘制一张图表&#xff0c;你组装一些基本组件就行&#xff1a;数据展示&#xff08;即图表类型&#xff1a;线型图、柱状图、盒形图、散布图、等值线图等&#xff09;、图例、标题、刻度标签以及其他注解型信息。 在pandas中&#xf…

pyyaml:Python 中的 YAML 处理大师

文章目录 pyyaml&#xff1a;Python 中的 YAML 处理大师背景&#xff1a;为何选择 pyyaml&#xff1f;pyyaml 是什么&#xff1f;如何安装 pyyaml&#xff1f;五个简单的 pyyaml 库函数使用方法1. 加载 YAML 数据2. 转储 YAML 数据3. 从文件加载 YAML4. 将数据写入 YAML 文件5.…

Cockos Reaper:开启专业数字音频制作之旅

Cockos Reaper 是一款备受赞誉的专业数字音频制作软件&#xff0c;适用于 Mac 和 Windows 系统。它以其强大的功能和高度的灵活性&#xff0c;成为众多音乐人和音频制作人的首选工具。 在音乐创作方面&#xff0c;Reaper 提供了丰富的虚拟乐器和音频效果插件&#xff0c;让你能…

如何使用ssm实现ssm框架的购物网站+vue

TOC ssm113ssm框架的购物网站vue 绪论 1.1 研究背景 当前社会各行业领域竞争压力非常大&#xff0c;随着当前时代的信息化&#xff0c;科学化发展&#xff0c;让社会各行业领域都争相使用新的信息技术&#xff0c;对行业内的各种相关数据进行科学化&#xff0c;规范化管理。…

AI 绘画神器 Midjourney 基础使用手册

一、前提条件 需要魔法&#xff1a; 新用户可免费创作 25 张图片&#xff0c;超过需要办会员版权问题&#xff1a;会员生成的图片版权归创作者所有 二、注册/链接 服务器 温馨提示&#xff1a;下方多图预警 1. 注册、创建服务器 ① 打开Midjourney官网&#xff0c;右下角…

机器学习入门指南:如何构建智能预测模型

【机器学习】&#xff1a;入门从零开始的指南 随着人工智能的快速发展&#xff0c;机器学习&#xff08;Machine Learning&#xff09;已经成为技术领域的热点话题。无论是推荐系统、语音识别、自动驾驶汽车&#xff0c;还是自然语言处理&#xff0c;机器学习的应用随处可见。…

minio文件存储

文章目录 参考安装与部署springboot整合miniopom.xmlapplication.ymlMinioPropertiesMinioConfigMinioApp测试基本功能bucket是否存在创建bucket修改bucket的访问权限查询所有的bucket删除指定的bucket上传文件到minio查看对象的描述信息获取文件的预签名访问地址后台获取minio…

第二课《动态规划》

1.1.1 线性dp 2.1.1 区间dp 3.1.1 背包dp 动态规划理论 动态规划算法通常用于求解具有某种最优性质的问题。在这类问题中&#xff0c; 可能会有很多可行解。没一个解都对应于一个值&#xff0c;我们希望找到具有最优值的解。胎动规划算法与分治法类似&#xff0c;其基本思想…