Collection与数据结构 数据结构预备知识(一) :集合框架与时间空间复杂度

1.集合框架

1.1 什么是集合框架

Java集合框架,又被称为容器,是定义在java.util包下的一组接口和接口实现的一些.其主要的表现就是把一些数据放入这些容器中,对数据进行便捷的存储,检索,管理.集合框架底层实现原理其实就是各种数据结构的实现方法,所以在以后的学习中,我们会采用首先掌握这些集合底层的数据结构是如何实现的,学会用代码自己实现,最后我们在来掌握这些集合类的具体方法等内容.下面是集合框架的总览:
在这里插入图片描述
集合类在面试和笔试中也非常常见,所以这部分内容相当重要.

2. 如何学好数据结构和集合类

  1. 数据结构中涉及到的代码非常多,90%全是代码,所以死磕代码,磕成这样就可以了
    在这里插入图片描述
  2. 多画图,数据结构非常抽象,有些题不画图根本解不出来.
    在这里插入图片描述
  3. 学完基础知识之后,多刷题,在以后的笔试时候经常考到数据结构,包括在面试的时候,面试官很可能让你手撕数据结构.剑指offer和leetcode还有牛客网均可.
    在这里插入图片描述

leetcode链接
牛客网链接

3. 时间复杂度和空间复杂度

时间复杂度和空间复杂度,经常用来衡量一个算法的好坏.第一种是时间效率,第二种是空间效率。时间效率被称为时间复杂度,而空间效率被称作空间复杂度。 时间复杂度主要衡量的是一个算法的运行速度,而空间复杂度主要衡量一个算法所需要的额外空间,在计算机发展的早期,计算机的存储容量很小。所以对空间复杂度很是在乎。但是经过计算机行业的迅速发展,计算机的存储容量已经达到了很高的程度。所以我们如今已经不需要再特别关注一个算法的空间复杂度。

3.1 时间复杂度

3.1.1 时间复杂度的定义

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

3.1.2 大O的渐进表示法

计算下面的基本操作执行了几次

void func1(int N){
int count = 0;
for (int i = 0; i < N ; i++) {for (int j = 0; j < N ; j++) {//执行n^2次count++;}
}
for (int k = 0; k < 2 * N ; k++) {//执行2n次count++;
}
int M = 10;
while ((M--) > 0) {//执行10次count++;
}System.out.println(count);
}

由上述代码可知,F(N) = N^2+2N+10 ,但是在我们在实际计算时间复杂度的时候,我们并不一定要计算精确的次数,而只需要大概执行的次数,那么我们就用大O渐进法来表示.

3.1.3 推导大O的方法

  1. 用常数1取代运行时间中所有的加法常数
  2. 在修改后的运行次数函数中,只保留最高阶项
  3. 如果最高项存在且系数不为1,则把最高项的系数改为1即可

通过上面的分析,我们会发现,大O渐进法去除了那些对结果影响不大的项,简洁明了的表示出了执行次数.
另外有些算法的时间复杂度存在最好,平均和最坏的情况.
最坏情况:任意输入规模的最大运行次数(上界)
平均情况:任意输入规模的期望运行次数
最好情况:任意输入规模的最小运行次数(下界)
例如:在一个长度为N数组中搜索一个数据x
最好情况:1次找到
最坏情况:N次找到
平均情况:N/2次找到
在实际情况中,我们在衡量时间复杂度的时候,一般都说的是最坏的情况,所以上述数组搜索的时间复杂度是O(N).

3.1.4 常见时间复杂度举例

[实例1]

void func2(int N) {int count = 0;for (int k = 0; k < 2 * N ; k++) {//执行2N次count++;}int M = 10;while ((M--) > 0) {//执行10次count++;}System.out.println(count);
}
//F(N) = 2N+10,通过大O的渐进表示法的化简,我们得到了时间复杂度为O(N).

[实例2]

void func3(int N, int M) {int count = 0;for (int k = 0; k < M; k++) {//执行M次count++;}for (int k = 0; k < N ; k++) {//执行N次count++;}System.out.println(count);
}
//F(N)=M+N,根据化简后得到时间复杂度O(N+M). 

[实例3]

void func4(int N) {int count = 0;for (int k = 0; k < 100; k++) {//执行100次count++;}System.out.println(count);
}
//F(N)为常数,所以直接把常数改为1,不存在最高次项,所以时间复杂度为O(1).

[实例4] (冒泡排序)

void bubbleSort(int[] array) {
for (int end = array.length; end > 0; end--) {//执行N次boolean sorted = true;for (int i = 1; i < end; i++) {//执行N-1次if (array[i - 1] > array[i]) {Swap(array, i - 1, i);sorted = false;}}if (sorted == true) {break;}}
}
//F(N) = N*(N-1),化简后为O(N^2).

看完上述实例之后,有的同学就会问了,好像时间复杂度只看for语句的循环条件就可以了,其实这种说法不准确,我们要结合代码的具体逻辑来分析.下面我们举一个例子来推翻这种不准确的说法.
[实例5] (二分查找法)

int binarySearch(int[] array, int value) {int begin = 0;int end = array.length - 1;while (begin <= end) {int mid = begin + ((end-begin) / 2);if (array[mid] < value)begin = mid + 1;else if (array[mid] > value)end = mid - 1;elsereturn mid;}return -1;
}

我们下面通过画图来说明问题
在这里插入图片描述
从上述分析我们可以知道,时间复杂度不可以只单单看for或while的循环条件,我们还是需要明白其中的逻辑来分析.上面我们就是通过画图来分析,也印证了数据结构的学习需要"多画图".
[实例6] (阶乘递归)

long factorial(int N) {return N < 2 ? N : factorial(N-1) * N;
}

递归的时间复杂度 = 递归的次数*每次递归后执行的次数
阶乘从N开始,返回N*(N-1),令返回的值为x,之后算x*(N-2),以此类推…算到最后,一共算了N-1次,时间复杂度就是O(N).
[实例7] (斐波那契数列)

int fibonacci(int N) {return N < 2 ? N : fibonacci(N-1)+fibonacci(N-2);
}

这里的斐波那契数列的递归有点类似于二叉树,关于二叉树的问题,我们后边讨论.
在这里插入图片描述
由上图和递归时间复杂度的运算法则,我们可以算出时间复杂度为O(2^n).

3.2 空间复杂度

3.2.1 空间复杂度的概念

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

3.2.2 空间度复杂度举例

[实例1]

void bubbleSort(int[] array) {for (int end = array.length; end > 0; end--) {boolean sorted = true;//sorted为额外申请的空间for (int i = 1; i < end; i++) {if (array[i - 1] > array[i]) {Swap(array, i - 1, i);//进行交换的时候,temp为额外申请的空间sorted = false;}}if (sorted == true) {break;}}
}

上述代码我们可知,额外申请的空间为2,所以空间复杂度为O(1).

[实例2]

int[] fibonacci(int n) {long[] fibArray = new long[n + 1];//在这里开辟了一个新的数组,空间和n有关fibArray[0] = 0;fibArray[1] = 1;for (int i = 2; i <= n ; i++) {fibArray[i] = fibArray[i - 1] + fibArray [i - 2];}return fibArray;
}

额外申请的空间为N+1个,所以空间复杂度为O(N).

[实例3]

long factorial(int N) {return N < 2 ? N : factorial(N-1)*N;
}

在这里插入图片描述
每次递归都在栈中创建了一个栈帧,每个栈帧都占用的是常数个额外空间,所以时间复杂度为O(N).

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

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

相关文章

QT(3/22)

1>使用手动连接&#xff0c;将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在自定义的槽函数中调用关闭函数&#xff0c;将登录按钮使用qt5版本的连接到自定义的槽函数中&#xff0c;在槽函数中判断ui界面上输入的账号是否为"admin"&#…

StarRocks 助力金融营销数字化进化之路

作者&#xff1a;平安银行 数据资产中心数据及 AI 平台团队负责人 廖晓格 平安银行五位一体&#xff0c;做零售金融的领先银行&#xff0c;五位一体是由开放银行、AI 银行、远程银行、线下银行、综合化银行协同构建的数据化、智能化的零售客户经营模式&#xff0c;这套模式以数…

【Hadoop大数据技术】——Hadoop高可用集群(学习笔记)

&#x1f4d6; 前言&#xff1a;Hadoop设计之初&#xff0c;在架构设计和应用性能方面存在很多不如人意的地方&#xff0c;如HDFS和YARN集群的主节点只能有一个&#xff0c;如果主节点宕机无法使用&#xff0c;那么将导致HDFS或YARN集群无法使用&#xff0c;针对上述问题&#…

值得参考的golang语言开发规范:Uber Go 语言编码规范,一些优秀的技巧可以提升代码的质量、避免代码缺陷和bug漏洞

值得参考的golang语言开发规范&#xff1a;Uber Go 语言编码规范&#xff0c;一些优秀的技巧可以提升代码的质量、避免代码缺陷和bug漏洞。 Uber Go 语言编码规范 Uber 是一家美国硅谷的科技公司&#xff0c;也是 Go 语言的早期 adopter。其开源了很多 golang 项目&#xff0c;…

UE5 LiveLink 自动连接数据源,以及打包后不能收到udp消息的解决办法

为什么要自动连接数据源&#xff0c;因为方便打包后接收数据&#xff0c;这里我是写在了Game Instance,也可以写在其他地方&#xff0c;自行替换成Beginplay和Endplay 关于编辑器模式下能收到udp消息&#xff0c;打包后不能收到消息的问题有两点需要排查&#xff0c;启动打包后…

Jmeter脚本优化——CSV数据驱动文件

使用 CSV 数据文件设置实现参数化注册 1&#xff09; 本地创建 csv 文件&#xff0c;并准备要使用的数据&#xff0c;这里要参数化的是注册的用户名和邮箱。所以在 csv 文件中输入多组用户名和邮箱。 2&#xff09; 通过测试计划或者线程组的右键添加->配置元件->CSV…

亚信安慧AntDB解析:数据库技术的新里程碑

AntDB简化了开发运维&#xff0c;更提高了数据库的易用性。AntDB是一种创新的数据库管理系统&#xff0c;其设计理念旨在让用户能够更便捷地进行数据库操作&#xff0c;减少繁琐的配置和管理工作&#xff0c;提升工作效率。 通过AntDB&#xff0c;用户可以快速部署和管理数据库…

Py之scikit-learn-extra:scikit-learn-extra的简介、安装、案例应用之详细攻略

Py之scikit-learn-extra&#xff1a;scikit-learn-extra的简介、安装、案例应用之详细攻略 目录 scikit-learn-extra的简介 scikit-learn-extra的安装 scikit-learn-extra的案例应用 1、使用 scikit-learn-extra 中的 IsolationForest 模型进行异常检测 scikit-learn-extra…

探索网络深处:爬虫技术的奥秘

目录 引言1. 网络的庞大性与信息的丰富性2. 爬虫在收集和分析网络信息方面的重要作用 一、 什么是爬虫&#xff1f;二、爬虫的应用领域三、爬虫的工作流程四、爬虫技术所面临的挑战与解决方案五、爬虫技术设计的伦理与法律问题文末推荐 引言 网络是一个庞大而丰富的宇宙&#…

ChatGPT已成澳洲“懒学生”们最爱,各大学加强检查人工智能辅助作弊行为!

据报道&#xff0c;越来越多的学生开始使用人工智能来写作业&#xff0c;但各所大学也在加倍努力&#xff0c;想方设法将他们一网打尽。 ▲图片来源于网络 悉尼大学透露&#xff0c;2023年有330份作业是用人工智能完成的&#xff0c;而新南威尔士大学最近也表示&#xff0c;他…

【yolo算法水果新鲜程度检测】

Yolo&#xff08;You Only Look Once&#xff09;系列算法是一类流行的一阶段实时目标检测模型&#xff0c;在水果检测领域有着广泛的应用。因其高效性和实时性而受到青睐&#xff0c;可用于识别和定位图像中不同种类的水果以及水果的新鲜度。 YOLOv3 已被用于水果商品的检测分…

Java基础-正则表达式

文章目录 1.基本介绍2.正则底层实现1.matcher.find()完成的任务2.matcher.group(0)分析1.源代码2.解释&#xff08;不分组&#xff09;3.解释&#xff08;分组&#xff09; 3.总结 3.正则表达式语法1.基本介绍2.元字符的转义符号1.基本介绍2.代码实例 3.字符匹配符1.基本介绍2.…

HTML_CSS学习:表格、表单、框架标签

一、表格_跨行与跨列 1.相关代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>表格_跨行与跨列</title> </head> <body><table border"1" cellspacing"0&qu…

学员分享丨学习华为认证,为什么建议报班学习

我一直对计算机科学有着浓厚的兴趣&#xff0c;但在我遇见誉天教育之前&#xff0c;我只是独自摸索&#xff0c;没有明确的方向和方法。然而&#xff0c;在誉天教育&#xff0c;我找到了一个真正为学生着想的地方。这里有一支专业且热情的教师队伍&#xff0c;他们不仅在课堂上…

毕业设计:日志记录编写(3/17起更新中)

目录 3/171.配置阿里云python加速镜像&#xff1a;2. 安装python3.9版本3. 爬虫技术选择4. 数据抓取和整理5. 难点和挑战 3/241.数据库建表信息2.后续进度安排3. 数据处理和分析 3/17 当前周期目标&#xff1a;构建基本的python环境&#xff1a;运行爬虫程序 1.配置阿里云pytho…

【Postman】工具使用介绍

一、postman工具介绍 1.什么是postman postman是谷歌开发的一款网页调试和接口测试工具&#xff0c;能够发送任何请求类型的http请求&#xff0c;支持GET/POST/PUT/DELETE等方法。postman简单易用&#xff0c;可以直接填写URL&#xff0c;header&#xff0c;body就可以发送一…

训练自己的声音模型,效果超级逼真,最牛的开源声音克隆项目 GPT-SoVITS

GPT-SoVITS 是一个开源的声音克隆项目&#xff0c;可以训练自己的声音模型。 效果非常好&#xff0c;使用超级简单。 如果你有声音克隆的需求&#xff0c;必须要试试这个项目。 不说废话&#xff0c;直接看怎么训练自己的声音模型。 1. 安装 我的是Windows系统&#xff0c…

Linux中的常用基础操作

ls 列出当前目录下的子目录和文件 ls -a 列出当前目录下的所有内容&#xff08;包括以.开头的隐藏文件&#xff09; ls [目录名] 列出指定目录下的子目录和文件 ls -l 或 ll 以列表的形式列出当前目录下子目录和文件的详细信息 pwd 显示当前所在目录的路径 ctrll 清屏 cd…

c 语言 三元搜索 - 迭代与递归(Ternary Search)

计算机系统使用不同的方法来查找特定数据。有多种搜索算法&#xff0c;每种算法更适合特定情况。例如&#xff0c;二分搜索将信息分为两部分&#xff0c;而三元搜索则执行相同的操作&#xff0c;但分为三个相等的部分。值得注意的是&#xff0c;三元搜索仅对排序数据有效。在本…

SOC 子模块---中断控制器

中断控制器对soc 中的各个外设进行中断管理&#xff0c;进行优先权排队&#xff0c;并送出IQR信号给CPU&#xff1b; 中断控制器在整个系统中的结构&#xff1a; IRQ<n>来源于不同的中断源&#xff0c;比如&#xff1a;I2C,SPI等&#xff0c;INTC收集这些中断&#xff0…