数据结构--时间复杂度与空间复杂度

news2024/11/25 22:52:39

数据结构–时间复杂度与空间复杂度

文章目录

  • 数据结构--时间复杂度与空间复杂度
  • 时间复杂度
  • 一、什么是时间复杂度
  • 二、具体实例
    • 1.大O的渐进表示法
    • 2.二分查找的时间复杂度
  • 空间复杂度
  • 一、什么是空间复杂度
  • 二、具体实例
  • 总结


时间复杂度

一、什么是时间复杂度

在计算机科学中,算法的时间复杂度是一个函数,它定量描述了该算法的运行时间。一个算法执行所耗费的时间,从理论上说,是不能算出来的,只有程序在机器上跑起来,才能知道,但是如果所有的算法都需要在机器上运行起来去测试时间复杂度就会很麻烦,所以才有了时间复杂度这个分析方式,一个算法所花费的时间与其中语句的执行次数成正比例,算法的基本操作的执行次数,为算法的时间复杂度。

二、具体实例

1.大O的渐进表示法

代码如下(示例):

// 请计算一下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);
}

F(N) = N^2 + 2*N + 10 这是++count的具体运行次数,但是对于大O的渐进表示法,在修改后的运行次数函数中,只保留最高阶项,所以Func1的时间复杂度应为:O(N^2)

// 计算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);
> }

Func2(N) = 2*N + 10 这是++count的具体运行次数,但是对于大O的渐进表示法,如果最高阶项存在,则去除与这个项目相乘的常数。得到的结果就是大O阶。所以Func2的时间复杂度为:O(N)

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

Func4的时间复杂度是常数次,所以统一使用O(1)来表示,1不是指一次,而是指常数次

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

通过计算分析发现基本操作递归了2^N次 ,时间复杂度为O(2^N)

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

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

2.二分查找的时间复杂度

代码如下(示例):

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

最坏情况就是:区间缩放到一个值时,要么找到,要么找不到,假设N是数组个数,X是最坏查找次数:
N/2/2/2/…/2 = 1
折半查找多少次就除多少个2
用数学表达式应为:2^X = N
则时间复杂度应为
在这里插入图片描述


空间复杂度

一、什么是空间复杂度

空间复杂度也是一个数学表达式,是对一个算法在运行过程中临时占用存储空间大小的量度 。
空间复杂度不是程序占用了多少bytes的空间,因为这个也没太大意义,所以空间复杂度算的是变量的个数
空间复杂度计算规则基本跟实践复杂度类似,也使用大O渐进表示法。

二、具体实例

代码如下(示例):

// 计算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;
 }
}
  1. 冒泡排序算法里面的数组属于本身就存在的,不是临时创建的,是因为有数组存在,有排序的需求,才会有这个排序算法。
  2. 临时占用存储空间的大小指的是创建额外的空间
  3. 这个代码里面临时创建了 n ;end;exchange;i;常数个变量,所以是O(1)。
// 计算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;
}
  1. 这个数组就是额外开辟的,为了计算斐波那契数列而开辟的,所以空间复杂度就是O(N)。
// 计算阶乘递归Fac的空间复杂度?
long long Fac(size_t N)
{
 if(N == 0)
 return 1;
 
 return Fac(N-1)*N;
}
  1. 递归调用了N次,开辟了N个栈帧,每个栈帧使用了常数个空间。空间复杂度为O(N)

总结

  1. 计算时间复杂度最好的办法就是画图,数循环次数很容易出错误
  2. 常见的复杂度
    在这里插入图片描述
  3. 复杂度的变化速率
    在这里插入图片描述

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

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

相关文章

字符串相加(力扣)

Problem: 415. 字符串相加 文章目录 思路Code复杂度运行结果 思路 创建一个StringBuilder对象使用append方法追加每位数字相加&#xff0c;使用双指针的方式&#xff0c;指针i&#xff0c;j分别指向num1和num2的每位数字&#xff0c;从后往前&#xff0c;进位用carry存储着。 …

什么是DevOps监控以及如何在组织中实施?

如今的软件开发商经常面临两大挑战——快速交付和大规模创新。DevOps通过在软件开发生命周期(SDLC)中引入自动化来开发和交付高质量的软件&#xff0c;从而帮助解决这些挑战。 持续集成(CI)/持续部署&#xff08;CD)是DevOps实践中自动化的关键组件。它可以自动化代码构建、测试…

【UE4 塔防游戏系列】06-炮塔发射子弹攻击敌人

效果 步骤 1. 新建一个Actor蓝图类&#xff0c;命名为“TotalBulletsCategory”&#xff0c;用来表示子弹蓝图总类&#xff0c;后面会有很多不同类型的子弹会继承该类 打开“TotalBulletsCategory”&#xff0c;添加粒子系统组件、盒体碰撞组件和发射物移动组件 调整发射物重力…

GitHub上整理的一些实用的工具

1. Visual Studio Code 简称VScode&#xff0c;是一个轻量且强大的跨平台开源代码编辑器&#xff08;IDE&#xff09;&#xff0c;支持Windows&#xff0c;OS X和Linux。内置JavaScript、TypeScript和Node.js支持&#xff0c;而且拥有丰富的插件生态系统&#xff0c;可通过安装…

【明解STM32】一文读懂STM32芯片总线

目录 一、前言 二、总线基础知识概述 (1)、总线在芯片中的角色 (2)、总线的类型 (3)、总线的指标 (4)、AHB和APB 三、总线框架结构 (1)、结构类型 (2)、总线模块 (3)、总线交互 四、总结 一、前言 本篇介绍STM32芯片内部的总线系统结构&#xff0c;嵌入式芯片内部的…

Unity自定义后处理——Vignette暗角

大家好&#xff0c;我是阿赵。   继续说一下屏幕后处理的做法&#xff0c;这一期讲的是Vignette暗角效果。 一、Vignette效果介绍 Vignette暗角的效果可以给画面提供一个氛围&#xff0c;或者模拟一些特殊的效果。 还是拿这个角色作为底图 添加了Vignette效果后&#xff0…

网络安全(黑客)万字自学笔记

目录 特别声明&#xff1a; 一、前言 二、定义 三、分类 1.白帽黑客&#xff08;White Hat Hacker&#xff09; 2.黑帽黑客&#xff08;Black Hat Hacker&#xff09; 3.灰帽黑客&#xff08;Gray Hat Hacker&#xff09; 四、黑客文化 五、伦理问题 六、黑客的作用 …

论文--高通量田间植物表型:一种用于分割重叠植物的自监督序列CNN方法

Title: High-Throughput Field Plant Phenotyping: A Self-Supervised Sequential CNN Method to Segment Overlapping Plants Abstract: High-throughput plant phenotyping—the use of imaging and remote sensing to record plant growth dynamics—is becoming more wide…

为什么企业需要集中采购?

大多数企业在寻找合适的采购系统时都会遇到困难。尤其是大多数 CPO 和 CFO &#xff0c;他们在集中采购系统与分散采购系统之间难以选择。如果你的企业尚未建立集中采购&#xff0c;那么将会失去集中采购系统所能实现的杠杆定价。 什么是集中采购&#xff1f; 集中采购可定义…

cookie 生命周期和cookie有效路径超级详细讲解

文章目录 cookie 生命周期和cookie有效路径超级详细讲解cookie 生命周期介绍代码示例完成测试 , 注意抓包看数据 cookie 有效路径有效路径规则规则如下:代码示例完成测试 , 注意抓包看创建 Cookie 时,返回的数据完成测试 , 注意抓包看读取 Cookie 时,返回的数据 代码示例html页…

ChatGPT 最佳实践指南之:系统地测试变化

Test changes systematically 系统地测试变化 Improving performance is easier if you can measure it. In some cases a modification to a prompt will achieve better performance on a few isolated examples but lead to worse overall performance on a more representa…

Failed to start File System Cehck on Root Device

偶遇服务器异常断电&#xff0c;Ubuntu后无法启动&#xff0c;出现如标题所示提示信息&#xff0c;详细内容出下图&#xff1a; 解决办法&#xff1a;将系统磁盘更换至另一台Ubuntu服务器中&#xff0c;对sda3分区中的ubuntu--vg-root分区进行修复后即可&#xff0c;操作内容如…

【UE4 塔防游戏系列】08-敌人到达终点对玩家造成伤害

目录 效果 步骤 一、敌人到终点时扣除玩家生命值 二、显示玩家生命值 效果 可以看到敌人进入终点后&#xff0c;左上角的玩家生命值会减少。 步骤 一、敌人到终点时扣除玩家生命值 新建一个Actor蓝图类&#xff0c;命名为“BP_EnemyEndPlace”&#xff0c;用来表示终点…

(学习笔记)TCP基础知识

什么是TCP? TCP 是面向连接的、可靠的、基于字节流的传输层通信协议。 面向连接&#xff1a;一定是[一对一]才能连接&#xff0c;不能像UDP协议可以一个主机同时向多个主机发送消息&#xff0c;也就是一对多是无法做到的&#xff1b;可靠的&#xff1a;无论网络链路中出现了…

spring复习:(38)ProxyFactoryBean中使用jdk动态代理生成代理对象时,业务方法调用时的执行流程

当调用代理对象的业务方法时&#xff0c;会直接执行JdkDynamicAopProxy类的invoke方法 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Object oldProxy null;boolean setProxyContext false;TargetSource targetSource this.advised…

Matter初探

这是运行gn_build.sh之后输出的日志 Script started on 2023-07-17 09:39:460800 ]0;userubuntu: ~/Matter/connectedhomeip[01;32muserubuntu[00m:[01;34m~/Matter/connectedhomeip[00m$ source gn_build.sh [0;33m.--------------------------------[0m [0;33m-- Environmen…

【项目 进程2】2.3 进程创建 2.4父子进程虚拟地址空间 2.5GDB多进程调试

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 2.3 进程创建2.4 父子进程虚拟地址空间父子进程之间的关系&#xff1a; 2.5 GDB多进程调试 2.3 进程创建 系统允许一个进程创建新进程&#xff0c;新进程即为子进程…

特征缩放(归一化处理)

在我们面对多维特征问题的时候&#xff0c;我们要保证这些特征都具有相近的尺度&#xff0c;这将帮助梯度下降算法更快地收敛。 以房价问题为例&#xff0c;假设我们使用两个特征&#xff0c;房屋的尺寸和房间的数量&#xff0c;尺寸的值为 0-2000平方英尺&#xff0c;而房间数…

CAPL(vTESTStudio) - CAPL实现CANCANFD接收

诊断作为CAN&CANFD总线测试中最大也是很重要的一块内容,虽然测试过程比较简单,但是作为诊断接收函数,我想大家在测试中都会遇到多种多样的自研函数,经过多年的工作,我也是一直希望写出一个能够适配我所能想到的所有情况的诊断应答接收,以下函数是我最近对于诊断接收函…

欧姆龙cp11以太网设置连接力控方法

JM-ETH-CP转以太网模块采用即插即用设计&#xff0c;不占用 PLC 通讯口&#xff0c;即编程软件/上位机软件通过以太网对 PLC 数据监控的同时&#xff0c;触摸屏可以通过复用接口与 PLC 进行通讯。捷米特JM-ETH-CP转以太网模块支持工控领域内绝大多数 SCADA 软件&#xff0c;支持…