【数据结构】Java实现数据结构的前置知识,时间复杂度空间复杂度,泛型类的讲解

news/2024/5/17 18:18:57/文章来源:https://blog.csdn.net/weixin_64182409/article/details/128068971

文章目录

  • 数据结构
  • 时间复杂度、空间复杂度
  • 包装类、装箱与拆箱
  • 泛型
    • 擦除机制

数据结构

当我们在成为一名程序员的这条道路上努力的时候,我们一定经常听到这个词数据结构。那么究竟什么是数据结构呢?数据结构顾名思义,就是数据+结构,数据就是数据,结构就是用来描述或者组织数据的,为什么会有那么多种的数据结构呢?是因为日常生活中的场景是多变的,那么我们组织数据描述数据的方式也应该是多变的,所以才会有这么多的数据结构来支持我们组织数据。现在我们还不能学习数据结构,因为有一些前置的知识我们还没有学习,那么下面我们就来了解一下这些前置知识吧!

时间复杂度、空间复杂度

使用数据结构组织数据,那么如何衡量组织的好坏呢?这里我们又要引入一个词——算法,数据结构和算法是相辅相成的,那么如何衡量算法的好坏,我们就需要考虑算法的效率问题,这时我们就好考虑算法的时间复杂度、空间复杂度

时间复杂度
简单一点说,时间复杂度就是在一个算法中代码的执行次数。专业一点来说,算法的时间复杂度是一个数学函数,定量描述了该算法的运行时间,运算时间与其中语句的执行次数成正比。

如何描述时间复杂度,时间复杂度怎么算呢?我们使用大O渐进法

大O渐进法规则
1、用常数1取代运行时间中的所有加法常数
2、在修改后的运行次数函数中,只保留最高阶项
3、如果最高阶存在并且不是1,则去除与这个项目相乘的常数。
4、执行完前面三部,就得到了大O阶

因为不可能每个算法我们都在计算机上执行一下计算一下执行时间,所以我们说的时间复杂度只是粗略的计算代码的执行时间,所以才有了大O渐进法规则,去掉了那些影响不大的杂项。光说无用,下面我们来上手计算一个时间复杂度:
首先看这样一个代码:

    public static void bubble_sort(int[] arr) {for(int i = 0; i < arr.length - 1;i++ ) {for(int j = 0;j < arr.length - i - 1;j++) {if(arr[j] > arr[j + 1]) {int tmp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = tmp;}}}}

这个代码的时间复杂度怎么算呢?我们可以将arr.length 看做n,那么最外层循环需要执行的次数就是n - 1次,内层循环每次执行的次数n -1、n - 2 ...... 1,是一个等差数列,那么要求这个算法的时间复杂度就是求他代码的执行次数,也就是要求n -1、n - 2 ...... 1这个等差数列的前n项和,之后再通过大O渐进法进行化简,所以通过计算我们可以得出:该算法的时间复杂度为O(n^2)

  public static int binarySearch(int[] arr,int num) {int left = 0;int right = arr.length - 1;while(left <= right) {int mid = (right - left)/2 + left;if(arr[mid] > num) {right = mid - 1;}else if(arr[mid] < num) {left = mid + 1;}else {return mid;}}return -1;}

上面这个算法的时间复杂度怎么算呢?我们光看代码是看不出来的,计算时间复杂度不只需要看代码还需要结合思想,我们通过读代码发现这是一个二分查找,我们需要结合他的思想找到相应的规律计算出代码的执行次数:二分查找每一次查找会舍弃一半的数据,当我们只有两个数据的时候,我们需要查找的次数为两次,第一次舍弃一半的数据,第二次找到数据。当有4个数据的时候,我们需要查找3次,第一次舍弃两个数据,第二次舍弃一个数据,最后找到数据,当有八个数据的时候,我们需要查找4次。我们把我们获取到的数据放在一个表格当中:

数据个数查找次数
22
43
84
n???

通过观察数据我们总结出了一个公式:2^(2-1) = 2、2^(3-1) = 4 、2^(4-1) = 8也就是说2^(查找次数 - 1) = 数据个数所以我们可以算出n个数据时的查找次数并且是使用大O渐进法化简后为:O(logN)

空间复杂度:
空间复杂度是对一个算法再运行过程中临时占用存储空间的大小的量度。空间复杂度算的是变量的个数,空间复杂度也跟时间复杂度类似,也用大O渐进法

因为大多时候判断算法的效率还是计算时间复杂度,所以这里我们只简单提一下空间复杂度:我们来看这个代码:

 public static long factoral(int n) {return n < 2 ? n : factoral(n - 1)*n;}

他的空间复杂度是多少呢?因为每一次递归都会开辟内存空间-栈帧,每个栈帧中都用一个常量,所以空间复杂度为O(n)

包装类、装箱与拆箱

在Java中我们说一切皆对象,难道基本数据类型也是对象嘛?虽然他们不是对象,但Java中为每个基本数据类型提供了包装类。

基本数据类型包装类
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
charCharacter
booleanBoolean
   public static void main(String[] args) {int num = 1;Integer i = Integer.valueOf(num);Integer i2 = new Integer(num);int num2 = i.intValue();System.out.println(i + " " + i2+ " " + num2);}

上图就是装箱和拆箱的操作,我们发现很复杂,为了简便我们代码的编写Java为我们提供了自动装箱和自动拆箱的操作。

   public static void main(String[] args) {Integer i = 10;int num = i;}

这样也可以实现装箱和拆箱的操作。了解完装箱和拆箱我们来看一道面试题:

    public static void main(String[] args) {Integer a = 127;Integer b = 127;Integer c = 128;Integer d = 128;System.out.println(a == b);System.out.println(c == d);}

上面这行代码的输出的结果什么呢?兄弟们可能会觉得包装类是引用数据类型,所以==比较的是引用指向对象的地址,所以abcd都不相同,输出两个false结果真的是这样嘛?
在这里插入图片描述
结果和我们所推测的并不相同,这是为什么呢?在自动装箱时同样会调用Integer类的valueOf()方法,所以我们去看看源码的逻辑是怎样的
在这里插入图片描述
当我们的形参在这个IntegerCache.low IntegerCache.high之间就不会new一个新对象,而超过这个范围的数据就需要重新new一个对象。所以 Integer a = 127; Integer b = 127;并没有重新创建对象,所以a == b输出的true
在这里插入图片描述

泛型

package demo1;class Myarray {public String[] array = new String[3];public int[] array1 = new int[3];public String getArray(int pos) {return array[pos];}public void setArray(String array,int pos) {this.array[pos] = array;}public int getArray1(int pos) {return this.array1[pos];}public void setArray1(int array1,int pos) {this.array1[pos] = array1;}
}
public class Test {public static void main(String[] args) {Myarray myarray = new Myarray();myarray.setArray("abc",0);myarray.setArray1(10,0);System.out.println(myarray.getArray(0));System.out.println(myarray.getArray1(0));}
}

我们来看上面的这个代码,我们发现这样创建数组非常的麻烦,每个类型的数组都要写一份get set方法。我们可不可以写一个数组让他可以存储任意类型的数据呢?在之前我们提到了装箱和拆箱的概念,所有基本类型都又对应的包装类,而在Java中所有类的父类是Object类,我们可不可以使用Object去创建数组呢?
在这里插入图片描述
虽然我们在存储数据时编译通过了并没有报错,但是当我们去访问数据时,编译报错,原因如下图。
在这里插入图片描述
所以这样非常不好,因为如果数组中有非常多的元素,难道我需要记住所有元素的类型嘛?显然是不现实的,那如何解决问题呢?所以泛型就要出场了,泛型的主要目的:就是指定当前的容器,要持有什么类型的对象,让编译器去做检查

泛型的语法:
创建:
class 泛型类名称<类型参数列表> { }
使用:
泛型类<类型参数>变量名 = new 泛型类<类型实参>(构造方法);

我们可以对上面的代码进行修改:

package demo2;import java.util.Arrays;class Myarray<T> {public T[] array = (T[])new Object[3];public void setArray (T t,int pos) {this.array[pos] = t;}public T getArray (int pos ) {return this.array[pos];}@Overridepublic String toString() {return "Myarray{" +"array=" + Arrays.toString(array) +'}';}
}
public class Test {public static void main(String[] args) {Myarray<Integer> myarray = new Myarray<>();myarray.setArray(10,0);myarray.setArray(20,1);System.out.println(myarray);Myarray<String> myarray1 = new Myarray<>();myarray1.setArray("abc",0);myarray1.setArray("def",1);System.out.println(myarray1);}
}

这样我们就可以实现我们的需求了。

擦除机制

说了这么多,泛型类究竟是如何编译的呢?我们去看一看源码:
在这里插入图片描述
我们发现在编译的过程中所有的泛型T被替换成了Object类,这种机制我们称为:擦除机制,运行时既然没有泛型的概念,那泛型究竟起了什么作用呢?

泛型的作用:
1、储存数据的时候,可以帮助我们进行自动的类型转换。
2、在读取元素时,可以帮助我们进行类型转换。
3、泛型可以将数据类型参数化,进行传递。

在这里插入图片描述
那么既然所有的T都会被替换为Object我们在创建数组时public T[] array = (T[])new Object[3];这个语句是否完美呢?我们是不是可以直接public Object[] array = new Object[3];
在这里插入图片描述
泛型其实是一个比较复杂的语法,我们现在只进行简单的了解,在之后的学习中我们还需要把他拿出来进行讲解。

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

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

相关文章

【深度学习】详解 CLIP

目录 摘要 一、引言和激励性工作 二、方法 2.1 自然语言监督 2.2 创建一个足够大的数据集 2.3 选择一种有效的预训练方法 2.4 选择和放缩一个模型 2.5 训练 三、实验 3.1 零次迁移 3.1.1 激励 Github&#xff1a;GitHub - openai/CLIP: Contrastive Language-Image …

Android 导航之Navigation 组件的介绍与使用

1、介绍&#xff1a; 在以前的应用中&#xff0c;针对多导航模块的使用&#xff0c;常见的有tabhost或者FragmentTabHost&#xff0c;但是这些在使用的过程中&#xff0c;非常臃肿&#xff0c;包括加载和管理也不如人意。在AndroidX中&#xff0c;官方引入Navigation模块&#…

Spring | IOC技术之Bean的配置与实例化

&#x1f451; 博主简介&#xff1a;    &#x1f947; Java领域新星创作者    &#x1f947; 阿里云开发者社区专家博主、星级博主、技术博主 &#x1f91d; 交流社区&#xff1a;BoBooY&#xff08;优质编程学习笔记社区&#xff09; 文章目录Bean的基础配置1、id 与 cla…

Anaconda默认安装在C:\Users\xxx\.conda\envs中

目录 问题&#xff1a; 解决&#xff1a; 更改默认安装位置 移动已安装环境 问题&#xff1a; 解决&#xff1a; 更改默认安装位置 用记事本打开 C:\Users\zqk\.condarc 在最后插入 envs_dirs: - D://anzhuang//Anaconda3//envs 如若需更改pkgs&#xff0c;插入如下代…

OTA: Optimal Transport Assignment for Object Detection 原理与代码解读

paper&#xff1a;OTA: Optimal Transport Assignment for Object Detection code&#xff1a;https://github.com/Megvii-BaseDetection/OTA 背景 标签分配&#xff08;Label Assignment&#xff09;是目标检测中重要的一环&#xff0c;经典的标签分配策略采用预定义的规则…

Caffeine 源码、架构、原理(史上最全,10W字 超级长文)

文章很长&#xff0c;而且持续更新&#xff0c;建议收藏起来&#xff0c;慢慢读&#xff01;疯狂创客圈总目录 博客园版 为您奉上珍贵的学习资源 &#xff1a; 免费赠送 :《尼恩Java面试宝典》 持续更新 史上最全 面试必备 2000页 面试必备 大厂必备 涨薪必备 免费赠送 经典…

【剧前爆米花--爪哇岛寻宝】面向对象的三大特性——封装、继承以及多态的详细剖析(中——多态)。

作者&#xff1a;困了电视剧 专栏&#xff1a;《JavaSE语法与底层详解》 文章分布&#xff1a;这是一篇关于Java面向对象三大特性——多态的文章&#xff0c;在本篇文章中我会分享多态的一些基础语法以及类在继承时代码的底层逻辑和执行顺序。 目录 多态的定义及实现条件 多态…

【程序人生】4年创作纪念日,不忘初心,继续前行

&#x1f4eb;作者简介&#xff1a;小明java问道之路&#xff0c;专注于研究 Java/ Liunx内核/ C及汇编/计算机底层原理/源码&#xff0c;就职于大型金融公司后端高级工程师&#xff0c;擅长交易领域的高安全/可用/并发/性能的架构设计与演进、系统优化与稳定性建设。 &#x1…

CleanMyMac X2022苹果电脑专业清理Mac加速器软件

CleanMyMac X2023最新免费版苹果电脑专业清理软件&#xff0c;对于Mac电脑用户来说&#xff0c;Cleanmymac X是一款再熟悉不过的电脑清理软件&#xff0c;它是由苹果认证并对外承认的一款第三方清理软件&#xff0c;几乎有95%的Mac用户都会安装并使用&#xff0c;Cleanmymac X究…

从一泡尿的工夫说起

大家好&#xff0c;我是校长。今天聊点不一样的&#xff0c;昨天读书的一点深刻感悟。大家有没有想过这么一个问题&#xff1a;如果没有记录时间的工具被发明&#xff0c;没有时钟&#xff0c;我们现在的生活会怎么样&#xff1f;在那个时钟尚未出现的日子里&#xff0c;如果确…

人工智能-机器学习-深度学习-概述

文章目录一&#xff1a;人工智能需要的基础和涉及内容二&#xff1a;数学基础&#xff08;1&#xff09;线性代数&#xff08;2&#xff09;概率论&#xff08;3&#xff09;数理统计&#xff08;4&#xff09;最优化方法&#xff08;5&#xff09;信息论三&#xff1a;机器学习…

虹科活动 | SWCF 2022卫星通信与仿真测试线上研讨会倒计时,快来报名吧!

您是否在因线下论坛的地点限制而错失技术干货分享&#xff1f;您是否因时间安排而无法亲临现场与行业专家交流&#xff1f;虹科举办全新线上论坛SWCF&#xff0c;与行业专家一起为您带来最新热点话题讨论与技术干货分享&#xff01; 什么是SWCF 虹科每年将开展卫星与无线通信…

计算机毕业设计之java+ssm网络硬硬盘系统网站

项目介绍 网盘&#xff0c;又称网络U盘、网络硬盘&#xff0c;是一些网络公司推出的在线存储服务。向用户提供文件的存储、访问、备份、共享等文件管理功能&#xff0c;使用起来十分方便。不花钱的移动硬盘。用户可以把网盘看成一个放在网络上的硬盘或U盘&#xff0c;不管你是…

量子计算(十):量子计算原理

文章目录 量子计算原理 一、酉变换 二、矩阵的指数函数 三、单位矩阵 四、单量子比特逻辑门 五、泡利矩阵 六、常见逻辑门 量子计算原理 经典计算中&#xff0c;最基本的单元是比特&#xff0c;而最基本的控制模式是逻辑门&#xff0c;可以通过逻辑门的组合来达到控制电…

如何做好风险管控,杜绝项目风险突然爆发?

软件开发最怕临近交付期&#xff0c;项目风险突然爆发。那么如何做好风险管理&#xff0c;提前排除隐患&#xff1f; 1、提前规划开发风险的科学管理与控制流程 项目需建立自己的组织级别风险资产库&#xff0c;并在开发过程中&#xff0c;不断地更新和完善。并对项目风险进行科…

Java搭建宝塔部署实战毕设项目springboot车险理赔管理系统源码

大家好啊&#xff0c;我是测评君&#xff0c;欢迎来到web测评。 本期给大家带来一套Java开发的毕业设计项目springboot车险理赔管理系统源码。 技术架构 技术框架&#xff1a;SpringBoot mybatis bootstrap jquery mysql5.7运行环境&#xff1a;jdk8 nginx1.20 tomcat9 …

Spring IoC依赖注入-6

1. 依赖注入的模式和模型: Spring 提供了哪些依赖注入的模式和类型? 手动模式 - 配置或者编程的方式&#xff0c;提前安排注入规则 XML资源配置元信息Java 注解配置元信息API 配置元信息 自动模式 - 实现方提供依赖自动关联的方式&#xff0c;按照内建的注入规则 Autowiring …

VisDrone数据集之集群检测(一)

VisDrone坐标信息 VisDrone数据集格式: txt标签内容为&#xff1a;bbox_left&#xff0c;bbox_top&#xff0c;bbox_width&#xff0c;bbox_height&#xff0c;score,object_category&#xff0c;truncation&#xff0c;occlusion 类别&#xff1a; ignored regions(0), pede…

[附源码]计算机毕业设计springboot绿色生鲜

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

aws eks 日志和监控配置

资料 Kubernetes Logging powered by AWS for Fluent Bithttps://docs.amazonaws.cn/AmazonCloudWatch/latest/monitoring/Container-Insights-setup-logs-FluentBit.html如何在 Amazon EKS 中将容器日志流式传输到 CloudWatch&#xff1f;, eks日志 使用fluentbit发送日志到…