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;
	else
		return 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).

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C语言中常用的文件操作

本文将介绍常用的关于文件操作函数&#xff0c;如fopen,fclose,fread,fwrite,feek,ftell,rewind以及feof和ferror等文件操作操作函数&#xff0c;还介绍一些用于所有输入输出流的函数如fgetc,fputc,fgets,fputs,fprintf,fscanf等函数&#xff0c;还介绍了sscanf,sprintf函数,fe…

【C++初阶】之类和对象(中)

【C初阶】之类和对象&#xff08;中&#xff09; ✍ 类的六个默认成员函数✍ 构造函数&#x1f3c4; 为什么需要构造函数&#x1f3c4; 默认构造函数&#x1f3c4; 为什么编译器能自动调用默认构造函数&#x1f3c4; 自己写的构造函数&#x1f3c4; 构造函数的特性 ✍ 拷贝构造…

原型链-(前端面试 2024 版)

来讲一讲原型链 原型链只存在于函数之中 四个规则 1、引用类型&#xff0c;都具有对象特性&#xff0c;即可自由扩展属性。 2、引用类型&#xff0c;都有一个隐式原型 __proto__ 属性&#xff0c;属性值是一个普通的对象。 3、引用类型&#xff0c;隐式原型 __proto__ 的属…

Java官网64位下载:获取高效、安全的Java平台

Java官网64位下载&#xff1a;获取高效、安全的Java平台 Java是一种广泛应用于软件开发和跨平台应用程序的编程语言。无论是开发桌面应用程序、移动应用程序还是大型企业级系统&#xff0c;Java都是一种可靠且强大的选择。为了确保你获取到高效、安全的Java平台&#xff0c;本文…

supervision CV视觉可视化辅助工具

参考&#xff1a; https://supervision.roboflow.com/latest/ https://github.com/roboflow/supervision/tree/develop/examples 版本&#xff1a; pip install -U supervisionultralytics-8.1.35 &#xff08;大于8.1才行&#xff0c;不然可能会有错误AttributeError: ‘Res…

第5章.零、单例与小样本提示词的编写之道

零提示、单个提示和小样本提示是用于从ChatGPT中生成文本的技术。在数据匮乏或任务全新、定义模糊之时&#xff0c;我们用微妙的提示&#xff0c;让ChatGPT从无到有&#xff0c;生成文本。 面对任务&#xff0c;空无一例&#xff1a;模型凭借对任务的广泛理解&#xff0c;独辟…

贝锐蒲公英虚拟DMZ:工业设备异地组网,解决网段冲突难题

虚拟DMZ 产品/技术的原理传统DMZ&#xff1a; DMZ中文名称为“隔离区”&#xff0c;也称“非军事化区”&#xff1b;它是为解决安装防火墙后外部网络不能访问内部网络服务器的问题。网关DMZ功能开启后&#xff0c; 将内网的一台服务器完全暴露在外网&#xff08;内网某个IP绑…

在CentOS7上部署Nginx并测试指南

Nginx部署测试 Nginx简介 Nginx是俄罗斯人Igor Sysoev编写的一款高性能的HTTP和反向代理服务器。 Nginx选择了epoll和kqueue作为网络I/O模型&#xff0c;在高连接并发的情况下&#xff0c;内存、CPU等系统资源消耗非常低&#xff0c;运行稳定。 正向代理与反向代理 正向代…

Swift 周报 第四十八期

文章目录 前言新闻和社区苹果突然不造车了&#xff0c;雷军&#xff1a;非常震惊&#xff01;分析师&#xff1a;马斯克或是最大赢家你会爱上的开发者活动 提案通过的提案正在审查的提案 Swift论坛推荐博文话题讨论关于我们 前言 本期是 Swift 编辑组自主整理周报的第四十八期…

【MySQL】16.事务管理(重点) -- 2

1. 事务隔离级别 如何理解隔离性1 MySQL服务可能会同时被多个客户端进程(线程)访问&#xff0c;访问的方式以事务方式进行一个事务可能由多条SQL构成&#xff0c;也就意味着&#xff0c;任何一个事务&#xff0c;都有执行前&#xff0c;执行中&#xff0c;执行后的阶段。而所…

基于Echarts的超市销售可视化分析系统(数据+程序+论文)

本论文旨在研究Python技术和ECharts可视化技术在超市销售数据分析系统中的应用。本系统通过对超市销售数据进行分析和可视化展示&#xff0c;帮助决策层更好地了解销售情况和趋势&#xff0c;进而做出更有针对性的决策。本系统主要包括数据处理、数据可视化和系统测试三个模块。…

基于随机森林与LSTM神经网络的住宅用电比较分析及预测 代码+论文 完整毕设

摘要 本文旨在探讨基于随机森林&#xff08;Random Forest&#xff09;与长短期记忆神经网络&#xff08;Long Short-Term Memory, LSTM&#xff09;的住宅用电比较分析及预测方法。随机森林是一种集成学习方法&#xff0c;通过构建多个决策树进行预测&#xff0c;具有较强的鲁…

FL Studio21.2.3.4004音乐制作及里程碑及功能介绍

**FL Studio 21.2.3.4004&#xff1a;音乐制作的新里程碑** 随着数字音乐制作技术的不断发展&#xff0c;音乐制作软件也在不断迭代升级。今天&#xff0c;我们将聚焦于一款广受欢迎的音乐制作软件——FL Studio 21.2.3.4004&#xff0c;探讨它如何成为音乐制作领域的新里程碑…

【技巧】如何设置和解除PDF的“打开密码”?

在工作中&#xff0c;我们经常会接触到PDF文件&#xff0c;对于重要的文件&#xff0c;往往还会设置密码保护&#xff0c;那PDF的“打开密码”如何设置和解除呢&#xff1f;下面小编分享两种方法&#xff0c;一起来看看吧&#xff01; 方法一&#xff1a;使用PDF编辑器 大部分…

基于连续深度编解码器网络的医学图像鲁棒边界分割

基于连续深度编解码器网络的医学图像鲁棒边界分割 摘要引言相关工作方法-----III. PROPOSED METHOD Robust_Boundary_Segmentation_in_Medical_Images_Using_a_Consecutive_Deep_Encoder-Decoder_Network 摘要 图像分割通常用于定位目标和边界。它在许多临床应用中是必不可少的…

一步一步搭建,功能最全的权限管理系统之动态路由菜单

一、前言 这是一篇搭建权限管理系统的系列文章。 随着网络的发展&#xff0c;信息安全对应任何企业来说都越发的重要&#xff0c;而本系列文章将和大家一起一步一步搭建一个全新的权限管理系统。 说明&#xff1a;由于搭建一个全新的项目过于繁琐&#xff0c;所有作者将挑选核心…

1320亿参数,性能超LLaMA2、Grok-1!开源大模型DBRX

3月28日&#xff0c;著名数据和AI平台Databricks在官网正式开源大模型——DBRX。 DBRX是一个专家混合模型&#xff08;MoE&#xff09;有1320亿参数&#xff0c;能生成文本/代码、数学推理等&#xff0c;有基础和微调两种模型。 根据DBRX在MMLU、HumanEval和 GSM8K公布的测试…

蓝牙双模音频模块支持串口AT指令控制介绍

目录 一、BT401蓝牙音频模块简介 蓝牙音频模块支持串口AT指令控制介绍&#xff0c;这里推荐BT401蓝牙模块&#xff0c;功能简介如下&#xff1a; BT401模块是一款支持蓝牙、U盘、TF卡播放的5合1的解决方案。模组的亮点在支持无损音乐的播放&#xff0c;以及简单明了的串口控制…

婴儿专用洗衣机哪个牌子好?四大爆款婴儿洗衣机合集安利

婴儿的衣物需要特别的护理&#xff0c;因为婴儿的皮肤非常娇嫩&#xff0c;需要一个无菌&#xff0c;没有刺激性的洗涤环境&#xff0c;于是婴儿洗衣机应运而生。如果你非常注重婴儿衣物的卫生问题&#xff0c;那么婴儿洗衣机则是非常理想的选择。毕竟&#xff0c;在婴儿吃奶或…

文件上传失败原因分析与解决

图片文件上传失败 问题描述&#xff1a;在前端开发时&#xff0c;需要通过表单元素上传图片或其他文本&#xff0c;但是上传不成功&#xff0c;后端接口也没问题 html <!--onChange用来绑定数据 handleUpload用来提交数据--><form onSubmit{handleUpload}><…