当前位置: 首页 > 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 全渠道客服中心是一种能够同时接入并处理来自多个渠道客户咨询和请求的综合服务平台。以…...

Jtti:如何知晓服务器的压力上限?具体的步骤和方法

了解服务器的压力上限(也称为性能极限或容量)是确保系统在高负载下仍能稳定运行的重要步骤。这通常通过压力测试(也称为负载测试或性能测试)来实现。以下是详细的步骤和方法来确定服务器的压力上限&#xff1a; 1. 定义测试目标和指标 在进行压力测试前&#xff0c;明确测试目标…...

贪心算法(1)

目录 柠檬水找零 题解&#xff1a; 代码&#xff1a; 将数组和减半的最少操作次数&#xff08;大根堆&#xff09; 题解&#xff1a; 代码&#xff1a; 最大数&#xff08;注意 sort 中 cmp 的写法&#xff09; 题解&#xff1a; 代码&#xff1a; 摆动序列&#xff0…...

SpringBoot,IOC,DI,分层解耦,统一响应

目录 详细参考day05 web请求 1、BS架构流程 2、RequestParam注解 完成参数名和形参的映射 3、controller接收json对象&#xff0c;使用RequestBody注解 4、PathVariable注解传递路径参数 5、ResponseBody&#xff08;return 响应数据&#xff09; RestController源码 6、统一响…...

目标驱动学习python动力

文章目录 迟迟未开始的原因打破思维里的围墙抛砖引玉爬虫 结束词 迟迟未开始的原因 其实我也是很早就知道有python&#xff0c;当时听说这个用于做测试不错&#xff0c;也就一直没有提起兴趣&#xff0c;后来人工智能火了之后&#xff0c;再次接触python&#xff0c;安装好pyth…...

力扣-Hot100-回溯【算法学习day.39】

前言 ###我做这类文档一个重要的目的还是给正在学习的大家提供方向&#xff08;例如想要掌握基础用法&#xff0c;该刷哪些题&#xff1f;&#xff09;我的解析也不会做的非常详细&#xff0c;只会提供思路和一些关键点&#xff0c;力扣上的大佬们的题解质量是非常非常高滴&am…...

小熊派Nano接入华为云

一、华为云IoTDA创建产品 创建如下服务&#xff0c;并添加对应的属性和命令。 二、小熊派接入 根据小熊派官方示例代码D6完成了小熊派接入华为云并实现属性上传命令下发。源码&#xff1a;小熊派开源社区/BearPi-HM_Nano 1. MQTT连接代码分析 这部分代码在oc_mqtt.c和oc_mq…...

【linux硬件操作系统】计算机硬件常见硬件故障处理

这里写目录标题 一、故障排错的基本原则二、硬件维护注意事项三、关于最小化和还原出厂配置四、常见故障处理及调试五、硬盘相关故障六、硬盘相关故障&#xff1a;硬盘检测问题七、硬盘相关故障&#xff1a;自检硬盘报错八、硬盘相关故障&#xff1a;硬盘亮红灯九、硬盘相关故障…...

谈学生公寓安全用电系统的涉及方案

‌学生公寓安全 学生公寓安全用电系统的设计方案主要包括以下几个方面‌&#xff1a; ‌电气线路设计‌&#xff1a; ‌合理布线‌&#xff1a;确保所有电气线路按照国家或地区的电气安全标准进行设计&#xff0c;避免线路过载和短路。‌使用阻燃材料‌&#xff1a;选用阻燃或低…...

自动语音识别(ASR)与文本转语音(TTS)技术的应用与发展

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

Go 语言数组

Go 语言数组 引言 Go 语言是一种静态类型、编译型语言&#xff0c;由 Google 开发&#xff0c;旨在提高多核处理器下的编程效率。数组作为 Go 语言中的一种基本数据结构&#xff0c;提供了存储一系列具有相同类型元素的能力。本文将深入探讨 Go 语言中数组的使用方法、特性以…...

百度不让访问危险网站怎么办/站长工具同大全站

https://blog.csdn.net/qq_16234613/article/details/79436941...

新疆交通建设管理局官方网站/优化培训课程

为什么80%的码农都做不了架构师&#xff1f;>>> 解决方案&#xff1a; 1.随便找一个你能运行的as项目 2.打开gradle-wrapper.properties&#xff0c;文件目录&#xff1a;项目/gradle/wrapper/gradle-wrapper.properties 3.复制distributionUrl这一整行的内容&…...

做网站公司-汉狮网络/百度地址如何设置门店地址

求-总步数很简单&#xff0c;在高中我们就遇到过样的问题&#xff0c;通过递推我们可以得出公式f(n)2^n-1,但是打印出来过程就不那么容易了&#xff0c;接下来我就要给大家介绍一下递归打印的方法&#xff0c;只是若n比较大的话&#xff0c;递归就不可取了。 步骤&#xff1a; …...

杨浦网站建设 网站外包/电商运营工资一般多少钱一个月

今天&#xff0c;Lyft很高兴宣布Flyte的开源&#xff0c;Flyte是一种结构化的编程和分布式处理平台&#xff0c;用于高度并发&#xff0c;可扩展和可维护的工作流。 Flyte在Lyft从事生产模型培训和数据处理已有三年多了&#xff0c;已成为价格&#xff0c;位置&#xff0c;预计…...

怎么创造一个网站/湖南竞价优化专业公司

由于本人英文水平有限&#xff0c;难免有翻译不当的地方&#xff0c;欢迎批评指正&#xff0c;如转载请注明出处。我尽我所能不说那些被认为是对产业中游戏或开发者进行批评的话&#xff0c;但是在这里我要提一些不同意见。我要讨论一些在寻路中面临的问题&#xff0c;为了证明…...

公司网站后台如何上传视频/太原seo网站管理

web应用常见的资源存方式在WEB-INF下新建lib&#xff0c;存放要使用的jar包在WEB-INF下新建jsp文件夹&#xff0c;存放jsp文件。首页除外&#xff0c;首页就放到web下。在web下&#xff0c;或WEB-INF下&#xff0c;新建css、js、image文件夹&#xff0c;存放相关文件。WEB-INF目…...