数据结构(Java版)第一期:时间复杂度和空间复杂度
目录
一、数据结构的概念
1.1. 什么是数据结构
1.2. 算法与数据结构的关系
二、算法效率
三、时间复杂度
3.1. 大O的渐进表⽰法
3.2. 计算冒泡排序的时间复杂度
3.3. 计算二分查找的时间复杂度
四、空间复杂度
4.1. 空间复杂度
4.2. 冒泡排序的空间复杂度
4.3. 斐波那契数列的空间复杂度
五、学习时间复杂度和空间复杂度的好处
一、数据结构的概念
1.1. 什么是数据结构
什么是数据结构呢?相信很多老铁尤其是非计算机专业的老铁还是第一次听说这个词。通俗地说,数据结构就是在内存当中对我们的数据进行一个管理和建立数据见关系,我们熟知的内存条(如下图所示)就是存储数据的介质,我们对数据的管理就是存储在内存条上的。
计算机这个学科最重要的是做软件开发,软件可以帮助我们实现各种功能,比如我们微信好友列表里面,表面上就是一堆姓名的数据,透过计算机我们看到的只是01010,而这些数据就存在内存条上。

1.2. 算法与数据结构的关系
算法就是定义良好的计算过程,它取⼀个或⼀组的值为输⼊,并产⽣出⼀个或⼀组值作 为输出。简单来说算法就是利用计算机处理问题的步骤,比如我们对数据进行一个排名,就要用到排序算法,以及需要这个区域来进行排名,就需要堆来实现。
那么数据结构与算法之间的关系呢?二者相辅相成,你中有我,我中有你。解决一些算法问题需要用到数据结构;实现一些数据结构时,又需要用到一些算法。
二、算法效率
如何衡量⼀个算法的好坏,就需要用到算法效率去衡量。算法效率分析分为两种:第⼀种是时间效率,第⼆种是空间效率。时间效率被称为时间复杂度,⽽空 间效率被称作空间复杂度。时间复杂度主要衡量的是⼀个算法的运⾏速度,⽽空间复杂度主要衡量⼀ 个算法所需要的额外空间。
通俗点说,时间复杂度和空间复杂度用来衡量代码消耗资源开销的多少,衡量的标准应该是与代码有关,与运行的设备无关。
三、时间复杂度
⼀个算法所花费的时间与其中语句的执⾏次数成正⽐例,算法中的 基本操作的执⾏次数,为算法的时间复杂度。站在数学的角度来看,时间复杂度可以看作是计算关键操作的次数与使用问题规模的函数关系,再对这个函数关系进行一个化简和近似。化简就是只取最高次项,把最高次项的系数也忽略掉,记作O() 。
下面博主将结合代码带大家来具体体会一下时间复杂度。
3.1. 大O的渐进表⽰法
import java.util.Scanner;public class Main {public static int func(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--)>0){count++;}return count;}public static void main(String[] args) {Scanner num = new Scanner(System.in);int b = num.nextInt();int a = func(b);System.out.println(a);}
}
上面的基本操作就是count的自增,那么count的被执行次数与N的函数关系就是。那么我们就要记作
。
import java.util.Scanner;public class Main {public static int func(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--)>0){count++;}return count;}public static void main(String[] args) {Scanner num = new Scanner(System.in);int b = num.nextInt();int a = func(b);System.out.println(a);}
}
上面这段代码的函数关系是,那么依旧是记作
。随着N值的增大,两个函数的值会越来越接近。
所以说,计算时间复杂度,一定要先找到核心的基本操作是什么。这个基本操作可能是打印、修改、比较或者是删除。
我们下面一段代码,因为描述问题规模的方式,不一定就只有一个变量,也可以是多个。此时我们应该记作。
import java.util.Scanner;public class Main {public static int func2(int M,int N){int count = 0;for (int k = 0; k < M; k++) {count++;}for (int k = 0; k < N; k++) {count++;}return count;}public static void main(String[] args) {Scanner num = new Scanner(System.in);int m = num.nextInt();int n = num.nextInt();System.out.println(func2(m, n));}
}
我们再来看下面一段代码,下面的时间复杂度就比较固定了,基本操作的次数与N无关,无论N是多少,count永远被循环了100次。那么此时的时间复杂度要记作,常数级时间复杂度。及时这里的i<1亿,时间复杂度照样是
。
import java.util.Scanner;public class Main {public static int func3(int N){int count = 0;for (int i = 0; i < 100; i++) {count++;}return count;}public static void main(String[] args) {Scanner num = new Scanner(System.in);int a = num.nextInt();System.out.println(func3(a));}
}
如果说出现了两段代码,一个时间复杂度是,另一个是
,那么
不一定比
慢,有可能当N比较小时,时间复杂度要比
。所以说,在这里要牢记时间复杂度衡量的是问题规模和时间的变化趋势,不能直接决定快慢。
3.2. 计算冒泡排序的时间复杂度
public class Main {public static void BubbleSort(int[] arrays){for (int end = arrays.length; end > 0; end--) {boolean sorted = true;for (int i = 0; i < end; i++) {if(arrays[i-1] > arrays[i]){Swap(arrays, i - 1, i);sorted = false;}}if (sorted == true){break;}}}
}
我们想要计算这个BubbleSort的时间复杂度,同理,首先也要搞清楚基本操作是什么。其中我们调用Swap方法进行交换的时候,在里面是不涉及内嵌循环的,所以计算时间复杂度的时候不用计算Swap内部的交换。我们先看外层循环,起始end的值是数组的长度N;内层循环呢,由于end的值不固定,当end=N时,i循环了N次,当end=N-1时,i循环了N-1次。所以时间复杂度的计算就是,结果就是
。
3.3. 计算二分查找的时间复杂度
public class Main {public static int BinarySearch(int[] arrays,int value){int begin = 0;int end = arrays.length - 1;while(begin <= end){int mid = begin + ((end-begin) / 2);if (arrays[mid] < value){begin = mid + 1;}else if(arrays[mid] > value){end = mid - 1;}else{return mid;}}return -1;}
}
二分查找,每循环一次,区间就会缩小一半,当区间缩小为1的时候,我们才得出“找到或者是没找到”的结论。我们可能说不好直接得出时间复杂度来,那我们就利用特殊值法。当数组元素为8时,最多要经历4次循环;当数组元素为16时,最多要经历5次循环。所以我们可以得出时间复杂度为。
对数级别的复杂度,及时问题规模变得很大,核心操作次数增长依然缓慢。
综合冒泡排序和二分查找的时间复杂度时,准确地说要涉及到三种情况:1.最好情况下,最需要循环一次就能找到;2.平均情况下,循环一半的次数;3.最坏情况下,循环了最多次。
四、空间复杂度
4.1. 空间复杂度
空间复杂度是衡量代码运行中消耗的临时空间,也就是我们的代码在运行时所创建的空间,至运行结束被销毁的空间。比如一个数组,长度为N,在后续代码中,并没有创建任何临时的空间。此时这个数组的空间复杂度就是常数级复杂度。
4.2. 冒泡排序的空间复杂度
public class Main {public static void BubbleSort(int[] arrays){for (int end = arrays.length; end > 0; end--) {boolean sorted = true;for (int i = 0; i < end; i++) {if(arrays[i-1] > arrays[i]){Swap(arrays, i - 1, i);sorted = false;}}if (sorted == true){break;}}}
}
上面的代码都创建了三个临时变量,sorted和i都创建了N次,那么空间复杂度就是2N+1,也就是。但其实不是的,因为空间和时间不一样,时间是一去不复返的,而空间是可以重复利用的,都是销毁了前一个才创建下一个,前一个和下一个共用同一块空间。一共三个临时变量,所以空间复杂度就是
。
4.3. 斐波那契数列的空间复杂度
int[] fibonacci(int n) {long[] fibArray = new long[n + 1];fibArray[0] = 0;fibArray[1] = 1;for (int i = 2; i <= n ; i++) {fibArray[i] = fibArray[i - 1] + fibArray [i - 2];}return fibArray;}
我们可以看到这次创建了临时空间,方法进来之后才创建,方法出去之后才销毁。下面除了i,也没有创建额外的临时空间了,所以上面代码的空间复杂度才是。
五、学习时间复杂度和空间复杂度的好处
学习时间复杂度,目的是为了能够正确的使用数据结构。数据结构有很多种,比如数组、队列、哈希表、栈、二叉树以及平衡树等,这些数据结构在不同场景中会有不同的应用。要想知道那种数据结构更合适,就要使用时间复杂度和空间复杂度来衡量。
相关文章:
数据结构(Java版)第一期:时间复杂度和空间复杂度
目录 一、数据结构的概念 1.1. 什么是数据结构 1.2. 算法与数据结构的关系 二、算法效率 三、时间复杂度 3.1. 大O的渐进表⽰法 3.2. 计算冒泡排序的时间复杂度 3.3. 计算二分查找的时间复杂度 四、空间复杂度 4.1. 空间复杂度 4.2. 冒泡排序的空间复杂度 4.3.…...
基于web的音乐网站(Java+SpringBoot+Mysql)
目录 1系统概述 1.1 研究背景 1.2研究目的 1.3系统设计思想 2相关技术 2.1 MYSQL数据库 2.2 B/S结构 2.3 Spring Boot框架简介 3系统分析 3.1可行性分析 3.1.1技术可行性 3.1.2经济可行性 3.1.3操作可行性 3.2系统性能分析 3.2.1 系统安全性 3.2.2 数据完整性 …...
用go语言后端开发速查
文章目录 一、发送请求和接收请求示例1.1 发送请求1.2 接收请求 二、发送form-data格式的数据示例 用go语言发送请求和接收请求的快速参考 一、发送请求和接收请求示例 1.1 发送请求 package mainimport ("bytes""encoding/json""fmt""ne…...
GeekChallenge 2024 第十五届极客大挑战 pwn AK
GeekChallenge 2024 第十五届极客大挑战 pwn AK 🍀前言☘️ez_shellcode(shellcode,栈溢出)🌿分析🌿解题🌿exp ☘️买黑吗喽了吗(整数溢出,栈溢出)dz…...
禅道是什么,nas是什么,ssh是什么,finalshell是什么,git命令feat 、fix分别什么意思
禅道(Zentao)是一款开源的项目管理软件,专为软件开发团队设计。它集成了项目管理、产品管理、质量管理、文档管理和事务管理等多种功能,旨在帮助团队提高工作效率和项目交付质量。禅道支持敏捷开发方法,同时也适用于传…...
点云-半径搜索法-Radius Search
核心作用 在于通过设定一个空间范围(半径)寻找点的邻域点集合,从而支持对局部区域的分析和操作。 因为空间半径不会随着密度变化而改变点云输出的结果,处理密度变化大的点云时很重要。 应用场景 稀疏点检测:当点云密度…...
P11290 【MX-S6-T2】「KDOI-11」飞船
题目大意:有i种加油站,最开始速度为1,每次加油可以使速度*v,每次加油有一个时间代价,求到达终点所需最小时间。 思路:不妨考虑dp,贪心是错误的。 对于速度而言,,所以速…...
WebGIS地图框架有哪些?
地理信息系统(GIS)已经成为现代应用开发中不可或缺的一部分,尤其在前端开发中。随着Web技术的快速发展,许多强大而灵活的GIS框架涌现出来,为开发人员提供了丰富的工具和功能,使他们能够创建交互式、高性能的…...
量化加速知识点(整理中。。。)
量化的基本概念 通过减少模型中计算精度,从而减少模型计算所需要的访存量。 参考...
BLIP-2模型的详解与思考
大模型学习笔记------BLIP-2模型的详解与思考 1、BLIP-2框架概述2、BLIP-2网络结构详解3、BLIP-2的几点思考 上一篇文章上文中讲解了 BLIP(Bootstrapping Language-Image Pretraining)模型的一些思考,本文将讲述一个BLIP的升级版 BLIP-2&am…...
2024年11月22日 十二生肖 今日运势
小运播报:2024年11月22日,星期五,农历十月廿二 (甲辰年乙亥月庚寅日),法定工作日。 红榜生肖:马、猪、狗 需要注意:牛、蛇、猴 喜神方位:西北方 财神方位:…...
小米C++ 面试题及参考答案上(120道面试题覆盖各种类型八股文)
进程和线程的联系和区别 进程是资源分配的基本单位,它拥有自己独立的地址空间、代码段、数据段和堆栈等。线程是进程中的一个执行单元,是 CPU 调度的基本单位。 联系方面,线程是进程的一部分,一个进程可以包含多个线程。它们都用于…...
SQL SELECT 语句:基础与进阶应用
SQL SELECT 语句:基础与进阶应用 SQL(Structured Query Language)是一种用于管理关系数据库的编程语言。在SQL中,SELECT语句是最常用的命令之一,用于从数据库表中检索数据。本文将详细介绍SELECT语句的基础用法&#…...
微服务即时通讯系统的实现(服务端)----(1)
目录 1. 项目介绍和服务器功能设计2. 基础工具安装3. gflags的安装与使用3.1 gflags的介绍3.2 gflags的安装3.3 gflags的认识3.4 gflags的使用 4. gtest的安装与使用4.1 gtest的介绍4.2 gtest的安装4.3 gtest的使用 5 Spdlog日志组件的安装与使用5.1 Spdlog的介绍5.2 Spdlog的安…...
《Spring 依赖注入方式全解析》
一、Spring 依赖注入概述 Spring 依赖注入(Dependency Injection,DI)是一种重要的设计模式,它在 Spring 框架中扮演着关键角色。依赖注入的核心概念是将对象所需的依赖关系由外部容器(通常是 Spring 容器)进…...
【C++动态规划】1411. 给 N x 3 网格图涂色的方案数|1844
本文涉及知识点 C动态规划 LeetCode1411. 给 N x 3 网格图涂色的方案数 提示 你有一个 n x 3 的网格图 grid ,你需要用 红,黄,绿 三种颜色之一给每一个格子上色,且确保相邻格子颜色不同(也就是有相同水平边或者垂直…...
外包干了3年,技术退步明显...
先说情况,大专毕业,18年通过校招进入湖南某软件公司,干了接近6年的功能测试,今年年初,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落! 而我已经在一个企业干了四年的功能…...
SpringBoot 2.x 整合 Redis
整合 1)添加依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!-- 如果没有使用下面给出的工具类,那么就不需要引入 -…...
React的API✅
createContext createContext要和useContext配合使用,可以理解为 “React自带的redux或mobx” ,事实上redux就是用context来实现的。但是一番操作下来我还是感觉,简单的context对视图的更新的细粒度把控比不上mobx,除非配合memo等…...
什么是全渠道客服中心?都包括哪些电商平台?
什么是全渠道客服中心?都包括哪些电商平台? 作者:开源呼叫中心系统 FreeIPCC,Github地址:https://github.com/lihaiya/freeipcc 全渠道客服中心是一种能够同时接入并处理来自多个渠道客户咨询和请求的综合服务平台。以…...
label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...
23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...
今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存
文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...
USB Over IP专用硬件的5个特点
USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...
网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...
push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...
day36-多路IO复用
一、基本概念 (服务器多客户端模型) 定义:单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用:应用程序通常需要处理来自多条事件流中的事件,比如我现在用的电脑,需要同时处理键盘鼠标…...
ubuntu系统文件误删(/lib/x86_64-linux-gnu/libc.so.6)修复方案 [成功解决]
报错信息:libc.so.6: cannot open shared object file: No such file or directory: #ls, ln, sudo...命令都不能用 error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory重启后报错信息&…...
