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

数据结构(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的函数关系就是count = N^{2} + 2N + 10。那么我们就要记作O(N^{2})

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 = N^{2} + 10,那么依旧是记作O(N^{2})。随着N值的增大,两个函数的值会越来越接近。

       所以说,计算时间复杂度,一定要先找到核心的基本操作是什么。这个基本操作可能是打印、修改、比较或者是删除。 

        我们下面一段代码,因为描述问题规模的方式,不一定就只有一个变量,也可以是多个。此时我们应该记作O(M + 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次。那么此时的时间复杂度要记作O(1),常数级时间复杂度。及时这里的i<1亿,时间复杂度照样是O(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));}
}

         如果说出现了两段代码,一个时间复杂度是O(N),另一个是O(1),那么O(N)不一定比O(1)慢,有可能当N比较小时,时间复杂度要比O(1)。所以说,在这里要牢记时间复杂度衡量的是问题规模和时间的变化趋势,不能直接决定快慢。

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次。所以时间复杂度的计算就是N+(N-1)+……+2+1,结果就是O(N^{2})

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次循环。所以我们可以得出时间复杂度为2^{循环次数}=N

       对数级别的复杂度,及时问题规模变得很大,核心操作次数增长依然缓慢。 

       综合冒泡排序和二分查找的时间复杂度时,准确地说要涉及到三种情况:1.最好情况下,最需要循环一次就能找到;2.平均情况下,循环一半的次数;3.最坏情况下,循环了最多次。

四、空间复杂度

4.1. 空间复杂度 

        空间复杂度是衡量代码运行中消耗的临时空间,也就是我们的代码在运行时所创建的空间,至运行结束被销毁的空间。比如一个数组,长度为N,在后续代码中,并没有创建任何临时的空间。此时这个数组的空间复杂度就是常数级复杂度O(1)

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,也就是O(N)。但其实不是的,因为空间和时间不一样,时间是一去不复返的,而空间是可以重复利用的,都是销毁了前一个才创建下一个,前一个和下一个共用同一块空间。一共三个临时变量,所以空间复杂度就是O(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,也没有创建额外的临时空间了,所以上面代码的空间复杂度才是O(N)

五、学习时间复杂度和空间复杂度的好处

     学习时间复杂度,目的是为了能够正确的使用数据结构。数据结构有很多种,比如数组、队列、哈希表、栈、二叉树以及平衡树等,这些数据结构在不同场景中会有不同的应用。要想知道那种数据结构更合适,就要使用时间复杂度和空间复杂度来衡量。 

相关文章:

数据结构(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 &#x1f340;前言☘️ez_shellcode&#xff08;shellcode&#xff0c;栈溢出&#xff09;&#x1f33f;分析&#x1f33f;解题&#x1f33f;exp ☘️买黑吗喽了吗&#xff08;整数溢出&#xff0c;栈溢出&#xff09;&#x1f3…...

禅道是什么,nas是什么,ssh是什么,finalshell是什么,git命令feat 、fix分别什么意思

禅道&#xff08;Zentao&#xff09;是一款开源的项目管理软件&#xff0c;专为软件开发团队设计。它集成了项目管理、产品管理、质量管理、文档管理和事务管理等多种功能&#xff0c;旨在帮助团队提高工作效率和项目交付质量。禅道支持敏捷开发方法&#xff0c;同时也适用于传…...

点云-半径搜索法-Radius Search

核心作用 在于通过设定一个空间范围&#xff08;半径&#xff09;寻找点的邻域点集合&#xff0c;从而支持对局部区域的分析和操作。 因为空间半径不会随着密度变化而改变点云输出的结果&#xff0c;处理密度变化大的点云时很重要。 应用场景 稀疏点检测&#xff1a;当点云密度…...

P11290 【MX-S6-T2】「KDOI-11」飞船

题目大意&#xff1a;有i种加油站&#xff0c;最开始速度为1&#xff0c;每次加油可以使速度*v&#xff0c;每次加油有一个时间代价&#xff0c;求到达终点所需最小时间。 思路&#xff1a;不妨考虑dp&#xff0c;贪心是错误的。 对于速度而言&#xff0c;&#xff0c;所以速…...

WebGIS地图框架有哪些?

地理信息系统&#xff08;GIS&#xff09;已经成为现代应用开发中不可或缺的一部分&#xff0c;尤其在前端开发中。随着Web技术的快速发展&#xff0c;许多强大而灵活的GIS框架涌现出来&#xff0c;为开发人员提供了丰富的工具和功能&#xff0c;使他们能够创建交互式、高性能的…...

量化加速知识点(整理中。。。)

量化的基本概念 通过减少模型中计算精度&#xff0c;从而减少模型计算所需要的访存量。 参考...

BLIP-2模型的详解与思考

大模型学习笔记------BLIP-2模型的详解与思考 1、BLIP-2框架概述2、BLIP-2网络结构详解3、BLIP-2的几点思考 上一篇文章上文中讲解了 BLIP&#xff08;Bootstrapping Language-Image Pretraining&#xff09;模型的一些思考&#xff0c;本文将讲述一个BLIP的升级版 BLIP-2&am…...

2024年11月22日 十二生肖 今日运势

小运播报&#xff1a;2024年11月22日&#xff0c;星期五&#xff0c;农历十月廿二 &#xff08;甲辰年乙亥月庚寅日&#xff09;&#xff0c;法定工作日。 红榜生肖&#xff1a;马、猪、狗 需要注意&#xff1a;牛、蛇、猴 喜神方位&#xff1a;西北方 财神方位&#xff1a…...

小米C++ 面试题及参考答案上(120道面试题覆盖各种类型八股文)

进程和线程的联系和区别 进程是资源分配的基本单位&#xff0c;它拥有自己独立的地址空间、代码段、数据段和堆栈等。线程是进程中的一个执行单元&#xff0c;是 CPU 调度的基本单位。 联系方面&#xff0c;线程是进程的一部分&#xff0c;一个进程可以包含多个线程。它们都用于…...

SQL SELECT 语句:基础与进阶应用

SQL SELECT 语句&#xff1a;基础与进阶应用 SQL&#xff08;Structured Query Language&#xff09;是一种用于管理关系数据库的编程语言。在SQL中&#xff0c;SELECT语句是最常用的命令之一&#xff0c;用于从数据库表中检索数据。本文将详细介绍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 依赖注入&#xff08;Dependency Injection&#xff0c;DI&#xff09;是一种重要的设计模式&#xff0c;它在 Spring 框架中扮演着关键角色。依赖注入的核心概念是将对象所需的依赖关系由外部容器&#xff08;通常是 Spring 容器&#xff09;进…...

【C++动态规划】1411. 给 N x 3 网格图涂色的方案数|1844

本文涉及知识点 C动态规划 LeetCode1411. 给 N x 3 网格图涂色的方案数 提示 你有一个 n x 3 的网格图 grid &#xff0c;你需要用 红&#xff0c;黄&#xff0c;绿 三种颜色之一给每一个格子上色&#xff0c;且确保相邻格子颜色不同&#xff08;也就是有相同水平边或者垂直…...

外包干了3年,技术退步明显...

先说情况&#xff0c;大专毕业&#xff0c;18年通过校招进入湖南某软件公司&#xff0c;干了接近6年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落&#xff01; 而我已经在一个企业干了四年的功能…...

SpringBoot 2.x 整合 Redis

整合 1&#xff09;添加依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!-- 如果没有使用下面给出的工具类&#xff0c;那么就不需要引入 -…...

React的API✅

createContext createContext要和useContext配合使用&#xff0c;可以理解为 “React自带的redux或mobx” &#xff0c;事实上redux就是用context来实现的。但是一番操作下来我还是感觉&#xff0c;简单的context对视图的更新的细粒度把控比不上mobx&#xff0c;除非配合memo等…...

什么是全渠道客服中心?都包括哪些电商平台?

什么是全渠道客服中心&#xff1f;都包括哪些电商平台&#xff1f; 作者&#xff1a;开源呼叫中心系统 FreeIPCC&#xff0c;Github地址&#xff1a;https://github.com/lihaiya/freeipcc 全渠道客服中心是一种能够同时接入并处理来自多个渠道客户咨询和请求的综合服务平台。以…...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具

作者&#xff1a;来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗&#xff1f;了解下一期 Elasticsearch Engineer 培训的时间吧&#xff01; Elasticsearch 拥有众多新功能&#xff0c;助你为自己…...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...

uniapp中使用aixos 报错

问题&#xff1a; 在uniapp中使用aixos&#xff0c;运行后报如下错误&#xff1a; AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在 GPU 上对图像执行 均值漂移滤波&#xff08;Mean Shift Filtering&#xff09;&#xff0c;用于图像分割或平滑处理。 该函数将输入图像中的…...

均衡后的SNRSINR

本文主要摘自参考文献中的前两篇&#xff0c;相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程&#xff0c;其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt​ 根发送天线&#xff0c; n r n_r nr​ 根接收天线的 MIMO 系…...

C# 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比

在机器学习的回归分析中&#xff0c;损失函数的选择对模型性能具有决定性影响。均方误差&#xff08;MSE&#xff09;作为经典的损失函数&#xff0c;在处理干净数据时表现优异&#xff0c;但在面对包含异常值的噪声数据时&#xff0c;其对大误差的二次惩罚机制往往导致模型参数…...

MySQL JOIN 表过多的优化思路

当 MySQL 查询涉及大量表 JOIN 时&#xff0c;性能会显著下降。以下是优化思路和简易实现方法&#xff1a; 一、核心优化思路 减少 JOIN 数量 数据冗余&#xff1a;添加必要的冗余字段&#xff08;如订单表直接存储用户名&#xff09;合并表&#xff1a;将频繁关联的小表合并成…...

PHP 8.5 即将发布:管道操作符、强力调试

前不久&#xff0c;PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5&#xff01;作为 PHP 语言的又一次重要迭代&#xff0c;PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是&#xff0c;借助强大的本地开发环境 ServBay&am…...