JavaDS —— 初识集合框架 + 时间/空间复杂度

目录

1. 初识集合框架

1.1 集合框架的初识

1.2 什么是数据结构?

2. 时间与空间复杂度

2.1 时间复杂度

2.2 大O的渐进表示法

2.3 常见时间复杂度计算举例

2.4 空间复杂度


1. 初识集合框架

1.1 集合框架的初识

什么叫集合?什么叫框架?什么又叫集合框架?这几个字该怎么理解?下来我们一起来看。

首先,在java中集合框架也被叫做容器(container),是在java.util包底下的一组接口和其实现类.

注意: 列举了常用的接口或者抽象类, 展示了集合之间的关系,这个每个集合类放在一起就叫做集合框架;这些集合类是Java官方已经写好的类,我们需要学习的就是这一个个类或者接口背后的结构是一个什么样的东西。所以我们要学习集合,就需要学习它们背后的数据结构。


1.2 什么是数据结构?

什么是数据结构?通俗来说就是数据+结构。

举个例子:我们平时日常生活中的数据:做核酸,停车场的车位号等等,那么我们就用数据结构组织这样一堆堆的数据.

数据结构有许多:单链表、二叉树、数组等等

数据结构多种多样的原因,就是面对不同的数据我们描述和组织数据的方式不同。

所以当我们把数据结构学明白了,就可以了解了整个常用集合框架背后的知识。

于是我们接下来就会学习到:顺序表、链表、二叉树、栈、队列、堆、哈希表、AVL树、红黑树、B树……

2. 时间与空间复杂度

如何衡量一个算法的好坏?

由于我们看代码好坏的角度不一样,也就是衡量标准不一样,我们得出的结果就不一样,还有,可能由于其他的一些原因也会导致每个人的结果是不一样的,比如说硬件(内存等等)、计算标准(时间长短)等等。

那么我们在这里就统一使用如下标准:使用时间和空间两个角度去衡量算法的好坏。

那么衡量一个算法好坏是时间重要还是空间重要呢?

实际上两者都是重要的,但是平时我们通常追求的是时间的快慢,其次才是空间,因为空间随着时代的发展内存的空间可使用空间越来越大,所以我们会尽可能的浪费一点空间来取换取我们的时间.

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

2.1 时间复杂度

定义:在计算机科学中,算法的时间复杂度是一个数学函数,用于描述算法执行所耗费的时间的快慢。

理论上我们是无法计算出一个算法所运行的时间的,因为这和硬件等各种因素是有关系的,硬件不同,执行的时间也不同。

所以我们这样分析:一个算法的时间复杂度和算法当中语句所执行的次数是成正比的,也就是说,语句越多,执行的次数就越多,所浪费的时间也是成正比的。

那么我们既然不能定量的去计算出实际上执行次数的时间,但是我们可以通过函数去描述它的时间,那这个函数就跟语句执行次数有关系,所以当我们看到代码之后我们可以看一下这个代码基本语句的执行次数有多少次。

算法中的基本操作的执行次数,为算法的时间复杂度。

有了这个概念之后我们通过以下几个例子来介绍一下:

    // 请计算一下func1基本操作执行了多少次?void func1(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++;}System.out.println(count);}

可以看出, count++执行的次数是最多的;

先看第一个嵌套的 for 循环,都是0~N,那么 count++执行了多少次?
这里有n个 i ,每个 i 都走 n 次,那么所有的 i 就一共走了n^2次,即在这个 for 循环里面就是执行了 n^2 次;
第二个for:2n次;
第三个for:10次;
最终相对比较准确的是n^2 + 2n + 10.

但是我们发现,n^2 + 2n + 10只是我们语句的一个执行次数,在程序员角度,并不是以这样一个多项的表达式作为一个复杂度的,当我们的n越来越大的时候,最终算出来的值可以忽略掉这个10,那么也就是说,当n非常非常大的时候,有些东西是可以忽略掉的,于是就有了我们这样一些规则,我们把它叫做大O的渐进表示法.

2.2 大O的渐进表示法

实际中我们计算时间复杂度时,我们其实并不需要计算精确的执行次数,而只需要大概执行次数,即使用 大O的渐进表示法计算复杂度.

大O的渐进表示法
1. 用 常数1取代运行时间中的所有加法常数;
2. 在修改后的运行次数函数中,只 保留最高阶项
3. 如果最高阶项存在且不是1,则 去除与这个项目相乘的 常数。得到的结果就是大O阶。

注意: 在这里我们在计算大O阶的时候并不是看着代码求,而是需要结合数学思想求解。


补充概念:

最坏情况复杂度;最好情况复杂度;平均复杂度。
我们直接举例说明:在数组中找一个数字的时间复杂度最坏是O(n),最好是O(1),平均是n/2。

我们所接触到的最多的情况就是最坏情况时间复杂度。


2.3 常见时间复杂度计算举例

    // 计算func2的时间复杂度?void func2(int N) {int count = 0;for (int k = 0; k < 2 * N; k++) {count++;}    // 2nint M = 10;while ((M--) > 0) {count++;}    // 10System.out.println(count);}

func2的时间复杂度为:O(n);


    // 计算func3的时间复杂度?void func3(int N, int M) {int count = 0;for (int k = 0; k < M; k++) {count++;}    // Mfor (int k = 0; k < N; k++) {count++;}    // NSystem.out.println(count);}

func3的时间复杂度为:O(M+N);


   // 计算func4的时间复杂度?void func4(int N) {int count = 0;for (int k = 0; k < 100; k++) {count++;}    // 100System.out.println(count);}

func4的时间复杂度为:O(1);

注:100是常数,常数看作1(第一条规则)


    // 计算bubbleSort的时间复杂度?    最坏是时间复杂度?最好复杂度?void bubbleSort(int[] array) {for (int end = array.length; end > 0; end--) {    //【0,n】boolean sorted = true;for (int i = 1; i < end; i++) {    //n-1 n-2 …… 1(n在变导致i也在变)if (array[i - 1] > array[i]) {swap(array, i - 1, i);sorted = false;}}if (sorted == true) {break;}}}

注:算一下 end 的取值: [ n, n-1, n-2, ...... , n-(n-1) ]

i 的取值-> [ n-1, n-2, n-3, ... , 1, 0 ]

所以对 i 进行求和(等差数列求和),结果为:(最坏情况下if (array[i - 1] > array[i])每次都被执行)n*(n-1) / 2, 所以最坏情况下时间复杂度为O(n^2),最好情况下就是数组有序了,复杂度为O(n)。


    // 计算binarySearch的时间复杂度?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;}

注:二分查找,每次“砍”一半:N -> N/2 -> N/4...;

于是:N/2^x = 1 => x = logN(以2为底N的对数)


    // 计算阶乘递归factorial的时间复杂度?long factorial(int N) {return N < 2 ? N : factorial(N - 1) * N;}

注:递归的时间复杂度 = 递归的次数 * 每次递归执行的次数

本题中,每次递归相当于是一个三目运算符在走,所以每次递归执行的次数是常数次1,所以对于本题来说只需要找到递归的次数就是它的时间复杂度。本题递归的次数是n-1次。

factorial的时间复杂度为:O(n);


    // 计算斐波那契递归fibonacci的时间复杂度?int fibonacci(int N) {return N < 2 ? N : fibonacci(N - 1) + fibonacci(N - 2);}

注:每一次递归,都会有两次“子递归”,所以递归次数就为:

2^0 + 2^1 + 2^2 + ... + 2^(n-1) = 2^n - 1次

斐波那契递归fibonacci的时间复杂度为O(2^n)

总结:
复杂度的计算需要通过结合代码的思想来做的。不能光靠代码来给出复杂度。

2.4 空间复杂度

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

    // 计算bubbleSort的空间复杂度?完成这个算法临时空间的大小void bubbleSort(int[] array) {for (int end = array.length; end > 0; end--) {boolean sorted = true;for (int i = 1; i < end; i++) {if (array[i - 1] > array[i]) {swap(array, i - 1, i);sorted = false;}}if (sorted == true) {break;}}}

bubbleSort的空间复杂度为O(1),因为没有让临时空间出现增加的情况。

如果修改以上代码:

    // 计算bubbleSort的空间复杂度?完成这个算法临时空间的大小void bubbleSort(int[] array) {for (int end = array.length; end > 0; end--) {int tmp = new int[array.length];//->拷贝array这个数组里面的数组boolean sorted = true;for (int i = 1; i < end; i++) {if (array[i - 1] > array[i]) {Swap(array, i - 1, i);sorted = false;}}if (sorted == true) {break;}}}

复杂度就变为O(n);

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

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

相关文章

React函数组件渲染两次

渲染两次是因为react默认开启了严格模式 React.StrictMode标签作用&#xff1a; 1、识别不安全的生命周期 2、关于使用过时字符串 ref API 的警告 3、关于使用废弃的 findDOMNode 方法的警告 4、检测意外的副作用 5、检测过时的 context API 注释掉React.StrictMode即为关闭严…

Vue3实现粒子动态背景

官网&#xff1a; https://particles.js.org/ npm&#xff1a; https://www.npmjs.com/package/particles.vue3 安装 pnpm add particles.vue3 pnpm add tsparticles-slim 注册 main.js import { createApp } from vue import type { App } from vue import globleApp f…

Spark---转换算子、行动算子、持久化算子

一、转换算子和行动算子 1、Transformations转换算子 1&#xff09;、概念 Transformations类算子是一类算子&#xff08;函数&#xff09;叫做转换算子&#xff0c;如map、flatMap、reduceByKey等。Transformations算子是延迟执行&#xff0c;也叫懒加载执行。 2)、Transf…

Java Stream中的API你都用过了吗?

公众号「架构成长指南」&#xff0c;专注于生产实践、云原生、分布式系统、大数据技术分享。 在本教程中&#xff0c;您将通过大量示例来学习 Java 8 Stream API。 Java 在 Java 8 中提供了一个新的附加包&#xff0c;称为 java.util.stream。该包由类、接口和枚举组成&#x…

Maven中常用命令以及idea中使用maven指南

文章目录 Maven 常用命令compiletestcleanpackageinstallMaven 指令的生命周期maven 的概念模型 idea 开发maven 项目idea 的maven 配置idea 中创建一个maven 的web 工程在pom.xml 文件添加坐标坐标的来源方式依赖范围编写servlet maven 工程运行调试 Maven 常用命令 compile …

腾讯云服务器99元一年?假的,阿里云是99元

腾讯云服务器99元一年是真的吗&#xff1f;假的&#xff0c;不用99元&#xff0c;只要88元即可购买一台2核2G3M带宽的轻量应用服务器&#xff0c;99元太多了&#xff0c;88元就够了&#xff0c;腾讯云百科活动 txybk.com/go/txy 活动打开如下图&#xff1a; 腾讯云服务器价格 腾…

C#中的var究竟是强类型还是弱类型?

前言 在C#中&#xff0c;var关键字是用来声明变量类型的&#xff0c;它是C# 3.0推出的新特征&#xff0c;它允许编译器根据初始化表达式推断变量类型&#xff0c;有点跟javascript类似&#xff0c;而javascript中的var是弱类型。它让C#变量声明更加简洁&#xff0c;但也导致了…

【Pytorch】Visualization of Fature Maps(2)

学习参考来自 使用CNN在MNIST上实现简单的攻击样本https://github.com/wmn7/ML_Practice/blob/master/2019_06_03/CNN_MNIST%E5%8F%AF%E8%A7%86%E5%8C%96.ipynb 文章目录 在 MNIST 上实现简单的攻击样本1 训练一个数字分类网络2 控制输出的概率, 看输入是什么3 让正确的图片分…

麻雀搜索优化算法MATLAB实现,SSA-BP网络

对于麻雀搜索算法的介绍&#xff0c;网上已经有不少资料了&#xff0c;这边公布SSA的matlab实现 下面展示SSA算法的核心代码以及详细注解 % 麻雀搜索算法函数定义 % 输入&#xff1a;种群大小(pop)&#xff0c;最大迭代次数(Max_iter)&#xff0c;搜索空间下界(lb)&#xff0c…

CSS实现空心的“尖角”

大家好&#xff0c;我是南宫&#xff0c;来分享一个昨天解决的问题。 我记得之前刷面试题的时候&#xff0c;CSS面试题里面赫然有一题是“如何用CSS实现三角形”&#xff0c;我觉得这个问题确实很经典&#xff0c;我上的前端培训班当初就讲过。 大概思路如下&#xff1a; 先…

想分析全国用电及煤气、液化石油气供应利用情况,这部分数据对你有帮助!

随着经济的发展和人民生活水平的提高&#xff0c;能源的需求量越来越大。其中&#xff0c;电力和煤气、液化石油气等能源的供应利用情况与我们的日常生活息息相关。 今天我们根据《中国城市统计年鉴》统计的中国地级及以上城市的煤气及液化石油气供应及利用情况的指标&#xff…