什么是时间复杂度和空间复杂度

news2024/11/16 1:45:08

什么是时间复杂度和空间复杂度

🍕博客主页:️自信不孤单

🍬文章专栏:数据结构与算法

🍚代码仓库:破浪晓梦

🍭欢迎关注:欢迎大家点赞收藏+关注

文章目录

  • 什么是时间复杂度和空间复杂度
  • 1. 什么是数据结构?
  • 2. 什么是算法?
  • 3. 算法的复杂度
    • 3.1 时间复杂度
      • 大O的线性表示法
      • 大O的渐进表示法
      • 常见时间复杂度计算举例
    • 3.2 空间复杂度
      • 常见空间复杂度计算举例
    • 常见复杂度对比


1. 什么是数据结构?

数据结构(Data Structure)是计算机存储、组织数据的方式,指相互之间存在一种或多种特定关系的数据元素的集合。

2. 什么是算法?

算法(Algorithm):就是定义良好的计算过程,他取一个或一组的值为输入,并产生出一个或一组值作为输出。简单来说算法就是一系列的计算步骤,用来将输入数据转化成输出结果。

3. 算法的复杂度

算法在编写成可执行程序后,运行时需要耗费时间资源和空间(内存)资源 。因衡量一个算法的好坏,一般是从时间和空间两个维度来衡量的,即时间复杂度和空间复杂度。
时间复杂度主要衡量一个算法的运行快慢,而空间复杂度主要衡量一个算法运行所需要的额外空间。在计算机发展的早期,计算机的存储容量很小。所以对空间复杂度很是在乎。但是经过计算机行业的迅速发展,计算机的存储容量已经达到了很高的程度。所以我们如今已经不需要再特别关注一个算法的空间复杂度。

3.1 时间复杂度

概念

时间复杂度的定义:在计算机科学中,算法的时间复杂度是一个函数,它定量描述了该算法的运行时间。

一个算法执行所耗费的 时间理论上来说是算不出来的,因为它不仅仅与你写的算法有关,还与运行这个算法的机器也有关系,如果你的机器很好,那么你所耗费的时间就可能会更少,所以,一个算法耗费的时间是需要放在机器上实际测验才能知道的,但是我们总不能每个算法都拿来上机测试,来记录该算法的时间,所以我们就有了时间复杂度这样的分析方式。

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

大O的线性表示法

大O符号(Big O notation):是用于描述函数渐进行为的数学符号。
我们来计算一下下面代码的时间复杂度

// 请计算一下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 中 ++count 语句总共执行了多少次?
F ( N ) = N 2 + 2 ∗ N + 10 F(N)=N^2+2*N+10 F(N)=N2+2N+10

  • N = 10 F(N) = 130
  • N = 100 F(N) = 10210
  • N = 1000 F(N) = 1002010

实际中我们计算时间复杂度时,我们其实并不一定要计算精确的执行次数,而只需要大概执行次数,那么这里我们使用大O的渐进表示法。

大O的渐进表示法

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

推导大O阶方法:
1、用常数1取代运行时间中的所有加法常数。
2、在修改后的运行次数函数中,只保留最高阶项。
3、如果最高阶项存在且不是1,则去除与这个项目相乘的常数。得到的结果就是大O阶。

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

  • N = 10 F(N) = 100
  • N = 100 F(N) = 10000
  • N = 1000 F(N) = 1000000

通过上面我们会发现大O的渐进表示法去掉了那些对结果影响不大的项,简洁明了的表示出了执行次数。

另外有些算法的时间复杂度存在最好、平均和最坏情况:
最坏情况:任意输入规模的最大运行次数(上界)
平均情况:任意输入规模的期望运行次数
最好情况:任意输入规模的最小运行次数(下界)

例如:在一个长度为N数组中搜索一个数据x
最好情况:1次找到
最坏情况:N次找到
平均情况:N/2次找到

在实际中一般情况关注的是算法的最坏运行情况,所以数组中搜索数据时间复杂度为O(N)

常见时间复杂度计算举例

实例1:

// 计算Func2的时间复杂度?
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);
}

实例2:

// 计算Func3的时间复杂度?
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);
}

实例3:

// 计算Func4的时间复杂度?
void Func4(int N)
{
	int count = 0;
	for (int k = 0; k < 100; ++k)
	{
		++count;
	}
	printf("%d\n", count);
}

实例4:

// 计算strchr的时间复杂度?
const char* strchr(const char* str, int character);

实例5:

// 计算BubbleSort的时间复杂度?
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;
	}
}

实例6:

// 计算BinarySearch的时间复杂度?
int BinarySearch(int* a, int n, int x)
{
	assert(a);
	int begin = 0;
	int end = n - 1;
	// [begin, end]:begin和end是左闭右闭区间,因此有=号
	while (begin <= end)
	{
		int mid = begin + ((end - begin) >> 1);
		if (a[mid] < x)
			begin = mid + 1;
		else if (a[mid] > x)
			end = mid - 1;
		else
			return mid;
	}
	return -1;
}

实例7:

// 计算阶乘递归Fac的时间复杂度?
long long Fac(size_t N)
{
	if (0 == N)
		return 1;
	return Fac(N - 1) * N;
}

实例8:

// 计算斐波那契递归Fib的时间复杂度?
long long Fib(size_t N)
{
	if (N < 3)
		return 1;
	return Fib(N - 1) + Fib(N - 2);
}

实例答案及分析:

  1. 实例1基本操作执行了2N+10次,通过推导大O阶方法知道,时间复杂度为 O(N)。

  2. 实例2基本操作执行了M+N次,有两个未知数M和N,时间复杂度为 O(N+M)。

  3. 实例3基本操作执行了10次,通过推导大O阶方法,时间复杂度为 O(1)。

  4. 实例4基本操作执行最好1次,最坏N次,时间复杂度一般看最坏,时间复杂度为 O(N)。

  5. 实例5基本操作执行最好N次,最坏执行了(N*(N+1)/2次,通过推导大O阶方法+时间复杂度一般看最
    坏,时间复杂度为 O(N2)。

  6. 实例6基本操作执行最好1次,最坏O(logN)次,时间复杂度为 O(logN) ps:logN在算法分析中表示是底
    数为2,对数为N。有些地方会写成lgN。

  7. 实例7通过计算分析发现基本操作递归了N次,时间复杂度为O(N)。

  8. 实例8通过计算分析发现基本操作递归了2N次,时间复杂度为O(2N)。(如图)

在这里插入图片描述

3.2 空间复杂度

概念

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

空间复杂度不是程序占用了多少bytes的空间,因为这个也没太大意义,所以空间复杂度算的是变量的个数。
空间复杂度计算规则基本跟实践复杂度类似,也使用大O渐进表示法

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

常见空间复杂度计算举例

实例1:

// 计算BubbleSort的空间复杂度?
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;
	}
}

实例2:

// 计算Fibonacci的空间复杂度?
// 返回斐波那契数列的前n项
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;
}

实例3:

// 计算阶乘递归Fac的空间复杂度?
long long Fac(size_t N)
{
	if (N == 0)
		return 1;
	return Fac(N - 1) * N;
}

实例答案及分析:

  1. 实例1使用了常数个额外空间,所以空间复杂度为 O(1)

  2. 实例2动态开辟了N个空间,空间复杂度为 O(N)

  3. 实例3递归调用了N次,开辟了N个栈帧,每个栈帧使用了常数个空间。空间复杂度为O(N)

常见复杂度对比

一般算法常见的复杂度如下:

在这里插入图片描述

在这里插入图片描述


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

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

相关文章

【服务器数据恢复】 EXT4文件系统下KVM虚拟机数据恢复案例

服务器数据恢复环境&#xff1a; Linux系统服务器&#xff0c;EXT4文件系统&#xff0c;部署KVM虚拟机。 服务器故障&#xff1a; 服务器上的KVM虚拟机被误操作删除&#xff0c;每台虚拟机包含一个qcow2格式的磁盘文件和一个raw格式的磁盘文件&#xff0c;需要恢复raw格式的磁…

大数据-玩转数据-oracle创建dblink及应用

一、创建DBLINK的应用场景 oracle在进行跨库访问时&#xff0c;可以通过创建dblink实现。 二、创建DBLINK应用场景 在tnsnames.ora中配置两个数据库别名&#xff1a;orcl(用户名&#xff1a;wangyong 密码&#xff1a;1988)、orcl2(用户名&#xff1a;wangyong 密码&#xf…

第5章 uniapp开发ImoocBlog

收获&#xff1a; 1.微信小程序 2.uni-app开发慕课热搜项目 3.构建企业级项目的编程思维 4.上线可商用的企业项目 第5章 uniapp开发ImoocBlog uniapp开发ImoocBlog 5-1&#xff1a;开篇 经过前面四个章节&#xff0c;我们已经完成了 微信小程序 的学习。那么从这一章开始我…

【微服务笔记10】微服务组件之Hystrix实现服务降级和服务熔断

这篇文章&#xff0c;主要介绍微服务组件之Hystrix实现服务降级和服务熔断。 目录 一、服务降级 1.1、什么是服务降级 1.2、实现服务降级 &#xff08;1&#xff09;引入依赖 &#xff08;2&#xff09;编写Service层代码 &#xff08;3&#xff09;编写Controller层代码…

CesiumForUnreal实现鹰眼地图(MiniMap)效果

文章目录 1.实现目标2.实现过程3.参考资料1.实现目标 基于CesiumForUnreal插件加载的在线地形和影像数据,使用Widget实现鹰眼小地图的效果,GIF动图如下: 2.实现过程 在UE开发中,常用的以Widget方法实现小地图的形式有两种。一种是动态的小地图,即地图的纹理图片会发生变化…

【Spark】RDD缓存机制

1. RDD缓存机制是什么&#xff1f; 把RDD的数据缓存起来&#xff0c;其他job可以从缓存中获取RDD数据而无需重复加工。 2. 如何对RDD进行缓存&#xff1f; 有两种方式&#xff0c;分别调用RDD的两个方法&#xff1a;persist 或 cache。 注意&#xff1a;调用这两个方法后并不…

腾讯云轻量服务器和云服务器区别对比(超详细全方位)

腾讯云轻量服务器和云服务器有什么区别&#xff1f;为什么轻量应用服务器费用更低&#xff1f;是因为轻量服务器CPU内存性能比云服务器CVM性能差吗&#xff1f;轻量应用服务器适合中小企业或个人开发者搭建企业官网、博客论坛、微信小程序或开发测试环境&#xff0c;云服务器CV…

Parcel 实践:轻松打包前端项目

结论 Parcel 是一个功能强大且易于使用的前端构建工具&#xff0c;它可以帮助您快速地构建 Web 项目。本文提供了关于如何开始使用 Parcel、配置和优化性能的实践方法。希望这些内容对您有所帮助&#xff01; Parcel 是一个快速&#xff0c;零配置的 Web 应用打包工具。它的简单…

7nm舱泊一体SoC的新玩家

2016年&#xff0c;高通推出基于14纳米工艺的汽车座舱芯片骁龙820A&#xff0c;彼时&#xff0c;传统座舱SoC霸主NXP主推的是28纳米工艺的iMX8系列。不过&#xff0c;两款芯片都没有能够达到预期的量产效果。 真正的时代变革&#xff0c;来自于高通在2019年发布的全球首款量产7…

【产品设计】电商后台系统设计--订单管理

电商后台产品&#xff0c;涉及众多模块&#xff0c;而以商品、订单、库存&#xff0c;为核心模块&#xff0c;模块之间存在大量交互。订单较为重要&#xff0c;它记录了所有的交易数据 对电商公司来讲&#xff0c;最核心最难做的有三部分&#xff1a;商品、订单、库存。商品与店…

记一次中大规模数据库迁移过程,从MySql到PostgreSQL.

从MySql到PostgreSQL迁移的决策过程就不说了。我也是第一次用PostgreSQL&#xff0c;也没法说好不好。决策已经定了&#xff0c;下面介绍一下执行过程。 一、数据基本情况 服务器&#xff1a;4核CPU&#xff0c;8G内存&#xff0c;1T硬盘&#xff0c;8Mbit网速。 数据库&…

【建站】手把手教你搭建惊艳的博客

系列文章目录 第一章 手把手教你搭建自己的博客 文章目录系列文章目录前言一、网站软件的选择二、网站空间的选择1. 建议选择有名、大厂的2. 上手容易&#xff0c;丰富而详实的文档3. 要稳定&#xff0c;少出问题4. 及时处理并有能力处理问题三、 环境准备四、 安装PHP81. 首先…

sql知识点复习以及项目中的例子

常见的聚合函数&#xff1a; avg&#xff08;&#xff09;&#xff0c;求平均值&#xff1b; sum&#xff08;&#xff09; 求和&#xff1b; count&#xff08;&#xff09;&#xff0c;计算和&#xff1b; min&#xff08;&#xff09;求最小值&#xff1b; max&#xff…

ChatGPT想干掉开发人员,做梦去吧

很多人都发现ChatGPT可以做一些代码相关的工作&#xff0c;不仅可以写一些基础的类似python、java、js的代码段&#xff0c;还可以做一定量的调优&#xff0c;于是就开始担忧起来&#xff0c;到哪天我的开发工作会不会被ChatGPT这个工具给取代了&#xff1f; 目录 1. ChatGPT…

腾讯云轻量应用服务器镜像修改限制说明(必看)

腾讯云轻量应用服务器镜像可以更换或修改吗&#xff1f;可以&#xff01;镜像可以修改&#xff0c;镜像是指轻量服务器的预装操作系统&#xff0c;轻量服务器创建成功后镜像也是可以更换的&#xff0c;如下图&#xff1a; 腾讯云轻量应用服务器镜像可以修改 目录 轻量服务器修…

计算机系统基本组成于基本功能

什么是计算机系统 计算机系统中的各个抽象层&#xff1a; C语言程序设计层 数据的机器级表示&#xff0c;运算语句和过程调用的机器级表示操作系统、编译和链接指令集体系架构&#xff08;ISA&#xff09;和汇编层 指令系统、机器代码&#xff0c;汇编语言微体系结构和硬件层 …

365天深度学习训练营-第J9周:Inception v3算法实战与解析

目录 一、前言 二、论文解读 1、Inception网络架构描述 2、Inception网络架构的优点 3、InceptionV3的改进 三、模型搭建 1、Inception-A 2、Inception-B 3、Inception-C 4、Reduction-A 5、Reduction-B 6、辅助分支 7、InceptionV3实现 一、前言 &#x1f368; 本…

ASP一个简单的网上教务系统模型的设计与实现

对于一个学校来说&#xff0c;大量教师信息&#xff0c;学生信息管理&#xff0c;学生成绩管理&#xff0c;基本数据的维护都难于通过传统的方法进行管理&#xff1a;这就迫切需要利用计算机技术来帮助学校管理者处理这些日常管理。本系统正是为了简化教学任务的管理&#xff0…

FreeRTOS 任务调度及相关函数详解(一)

文章目录一、任务调度器开启函数 vTaskStartScheduler()二、内核相关硬件初始化函数 xPortStartScheduler()三、启动第一个任务 prvStartFirstTask()四、中断服务函数 xPortPendSVHandler()五、空闲任务一、任务调度器开启函数 vTaskStartScheduler() 这个函数的功能就是开启任…

【ROS2指南-1】配置ROS2环境

资料来源Configuring your ROS 2 environment — ROS 2 Documentation: Dashing documentationhttp://docs.ros.org/en/dashing/Tutorials/Configuring-ROS2-Environment.html 目标&#xff1a;本教程将向您展示如何准备 ROS 2 环境。 教程级别&#xff1a;初学者 时间&…