【数据结构】集合框架、时间复杂度和空间复杂度

0 前言

  1. 数据结构:本身是与语言无关的抽象概念;在代码中,组织大量的数据,高效得进行增删改查。

  2. 是 现实问题中,实物的抽象表示。

  3. 抽象:现实中的实物,信息是非常多的。
    写代码的时候,往往只需要提取中其中自己关心的部分,其他的大部分信息都忽略了。

比如:一个真实的大学生,包含的属性/信息非常多。

根据问题需求的不同,只需要提取其中的关键信息即可:

(1)发奖学金:姓名,班级,成绩 (2)组织王者荣耀比赛:姓名,班级,段位 (3)举办单身派对:姓名,性别,是否单身

  1. 集合类:数据结构在Java中的具体表现形式。

Java 标准库中,提供了一些类,供程序员直接使用;
其中有些类(集合类),就是前人已经实现好了的数据结构;
直接使用这些集合类,方便管理很多的数据。

一、集合框架

在这里插入图片描述

Java中的集合类,就是 抽象的数据结构,对应的具体实现 。

  • 顺序表 ——> ArrayList
  • 链表 ——> LinkedList
  • 栈 ——> Stack
  • 队列 ——> Queue
  • 二叉树 ——> TreeSet / TreeMap
  • 哈希表 ——> HashSet / HashMap
  • 优先级队列 / 堆 ——> PriorityQueue

二、衡量算法的标准

数据结构:需要管理很多数据,高效方便得进行增删改查。

高效:
(1)时间上的高效:算得块
(2)空间上的高效:消耗的空间少

这两者,只和一段代码本身的实现方式有关,和机器硬件性能水平无关。

三、时间复杂度

3.1 时间复杂度的概念

  1. 算法的时间复杂度是⼀个数学函数,它定量描述了该算法的运行时间。
  2. 算法中的基本操作的执行次数,为算法的时间复杂度。

3.2 大O的渐进表示法:时间复杂度

  1. 作用:用来评价某个代码 / 某个数据结构 / 某个操作的效率。

  2. 实例:

在这里插入图片描述

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

  1. 时间复杂度 实例1:

在这里插入图片描述
2. 时间复杂度 实例2:

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

无法判断M、N的差距是大还是非常接近,所以此代码的时间复杂度为 O(M+N)

  1. 时间复杂度 实例3:

在这里插入图片描述
【总结】

  1. O(1)只能说明执行次数和问题规模无关。
    O(1)和 O(1)之间,实际的执行时间,可能会差别很大;可能有的O(1)确实很快,有的O(1)也很慢。
  2. 时间复杂度,衡量的是 问题规模和时间的趋势变化。
    给两个代码,一个时间复杂度为O(1),另一个位O(N),O(N)一定比O(1)慢吗?
    不一定,因为时间复杂度衡量的是问题规模与时间之间的变化趋势,不能决定时间的快慢。
  1. 时间复杂度 实例4:

在这里插入图片描述
5. 时间复杂度 实例5:
在这里插入图片描述

类似于上述每次区间砍半的情况,时间复杂度就是O(log N)
O(N)增长趋势比O(log N)快。

  1. 时间复杂度 实例6:
// 计算阶乘递归factorial的时间复杂度?
long factorial(int N) {
return N < 2 ? N : factorial(N-1) * N;
}
  • 虽然没有循环,但是有递归(所有的递归,理论上都能转换成循环)。
  • 假设N为1,执行次数为1;N为2,执行次数为2;N为3,执行次数为3。
  • 所以时间复杂度为O(N)
  1. 时间复杂度 实例7:
    在这里插入图片描述

【总结】在谈到时间复杂度的时候,涉及到三种时间复杂度:

  • 最好的情况下:数组本身就是有序的,只要冒泡一次就可以完成排序,时间复杂度为O(N)
  • 平均情况下:数组本身为一般有序,一半无序
  • 最差情况下(考虑最多的情况):数组本身非常无序,需要完成所有的冒泡操作,时间复杂度为O(N^2)

四、空间复杂度

4.1 空间复杂度概念

衡量的是代码运行中消耗掉的临时空间是多少。

举例:

给一个数组,长度为N(这里要占据N份空间,非临时空间),在后续代码中,并没有创建任何的临时空间(变量);空间复杂度,就是常数级空间复杂度O(1)。

4.2 大O的渐进表示法: 空间复杂度

1、 实例1:冒泡排序的空间复杂度

O(1),因为它只需要固定的三份空间(创建end、sotred、i,开辟空间)。

在这里插入图片描述
2. 实例:循环版本 斐波那契数列的空间复杂度
在这里插入图片描述
其中此代码的空间复杂度 要看 临时空间new long[ ] 与 n 之间的关系:

在这里插入图片描述

  1. 实例3:递归版本的 斐波那契数列 空间复杂度

在这里插入图片描述
在这里插入图片描述

【总结】

空间复杂度判断要点
当前代码 谁是临时空间,以及这个临时空间随着N的变化是如何增长的。
如果N怎么变,临时空间都是固定的,空间复杂度为O(1);
如果临时空间跟N是线性增长,空间复杂度为O(N);
如果是指数增长,则为O(N^2)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值