数据结构——时间与空间复杂度和包装类

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

1. 算法效率

算法在编写成可执行程序后,运行时需要耗费时间资源和空间 ( 内存 ) 资源 。因此 衡量一个算法的好坏,一般 是从时间和空间两个维度来衡量的 ,即时间复杂度和空间复杂度。
时间复杂度主要衡量一个算法的运行快慢,而空间复杂度主要衡量一个算法运行所需要的额外空间

1. O的渐进表示法

O 符号( Big O notation ):是用于描述函数渐进行为的数学符号。
去掉了那些对结果影响不大的项
推导大 O 阶方法:
1 、用常数 1 取代运行时间中的所有加法常数。
2 、在修改后的运行次数函数中,只保留最高阶项。[ O(N^2+N+10) -> O(N^2) ]
3 、如果最高阶项存在且不是 1 ,则去除与这个项目相乘的常数。得到的结果就是大 O 阶   [ O(3N) -> O(N) ]

2. 时间复杂度

1. 定义

在计算机科学中, 算法的时间复杂度是一个函数 ,它定量描述了该算法的运行时间。一个算法执行所耗费的时间。
一个算法所花费的时间与其中语句的执行次数成正比例, 算法中的基本操作的执行次数,为算法 的时间复杂度。
实际中我们计算时间复杂度时,我们其实并不一定要计算精确的执行次数,而只需要 大概执行次数,那么这 里我们使用大 O 的渐进表示法。
另外有些算法的时间复杂度存在最好、平均和最坏情况:
最坏情况:任意输入规模的最大运行次数 ( 上界 )
平均情况:任意输入规模的期望运行次数
最好情况:任意输入规模的最小运行次数 ( 下界 )
例如:在一个长度为 N 数组中搜索一个数据 x
最好情况: 1 次找到
最坏情况: N 次找到
平均情况: N/2 次找到
在实际中一般情况关注的是算法的最坏运行情况,所以数组中搜索数据时间复杂度为 O(N)
递归的时间复杂度 = 递归的次数 * 每次递归执行的次数

2. 常见时间复杂度计算举例

打印数组的10个元素:  O(1)

打印数组的2N个元素:O(n)

二分查找:O(log_{2}N)

冒泡排序:O(N^2)

计算阶乘:O(N)
计算斐波那契递归( return Fib ( N - 1 ) + Fib ( N - 2 );):O(2^N)

3. 空间复杂度

1. 定义

空间复杂度也是一个数学表达式,是对一个算法在运行过程中临时占用存储空间大小的量度

空间复杂度不是程序占用了多少 bytes 的空间,因为这个也没太大意义,所以空间复杂度算的是变量的个数
空间复杂度计算规则基本跟时间复杂度类似,也使用 O 渐进表示法
注意: 函数运行时所需要的栈空间 ( 存储参数、局部变量、一些寄存器信息等 ) 在编译期间已经确定好了,因 此空间复杂度主要通过函数在运行时候显式申请的额外空间来确定。
2.  常见空间复杂度计算举例
计算阶乘:O(N)
计算斐波那契递归( return Fib ( N - 1 ) + Fib ( N - 2 );):O(N)

2. 接口

Java 集合框架 Java Collection Framework ,又被称为容器 container ,是定义在 java.util 包下的一组接口 interfaces 和其实现类 classes
其主要表现为将多个元素 element 置于一个单元中,用于对这些元素进行快速、便捷的存储 store 、检索 retrieve 、管理 manipulate ,即增删改查

1. 类和接口总览

2. 关系说明

1. 接口 extends 接口

2. 类 implements 接口

1. Collection :用来存储管理一组对象 objects ,这些对象一般被成为元素 elements
       1. Set : 元素不能重复,背后隐含着 查找 / 搜索 的语义
            1. SortedSet : 一组有序的不能重复的元素
       2. List : 线性结构
       3. Queue : 队列
       4. Deque : 双端队列

2. Map : 键值对 Key-Value-Pair ,背后隐含着查找/搜索的语义

       1. SortedMap : 一组有序的键值对

3. 包装类

Object 引用可以指向任意类型的对象,但有例外: 8 种基本数据类型不是对象
所以我们引入了包装类

1. 包装类的使用

1. 装箱

新建⼀个 Integer 类型对象,将 i 的值放⼊对象的某个属性中

  1. IntegerCache.low 和 IntegerCache.high:

    • IntegerCacheInteger类中的一个内部静态类,用于缓存一定范围内的Integer对象。

    • lowhigh分别表示缓存的最小值和最大值。默认情况下,low-128high127(具体值可能因JVM实现或配置而有所不同)。

  2. 缓存检查:

    • if (i >= IntegerCache.low && i <= IntegerCache.high):检查传入的inti是否在缓存范围 [ -128 , 127 ] 内。

    • 如果在范围内,直接从缓存中返回对应的Integer对象:IntegerCache.cache[i + (-IntegerCache.low)]

      • 缓存数组cache是一个静态数组,存储了从lowhigh的所有Integer对象。

      • i + (-IntegerCache.low)用于计算i在缓存数组中的索引。

  1. 缓存未命中:

    • 如果i不在缓存范围内,则通过new Integer(i)创建一个新的Integer对象并返回。

为什么需要缓存?

  • 对于小整数(如-128127),Java通过缓存这些常用的Integer对象,避免重复创建,从而节省内存和提高性能。

  • 这种优化是基于实践中小整数的使用频率较高

        int a = 10;
        Integer b = a;//自动装箱

        Integer c = Integer.valueOf(a);//显示装箱

        System.out.println("b = " + b);
        System.out.println("c = " + c);

2. 拆箱

Integer 对象中的值取出,放到⼀个基本数据类型中
        Integer k = new Integer(10);
        int i = k;//自动拆箱

        int j = k.intValue();//显示拆箱

        System.out.println("i = " + i);
        System.out.println("j = " + j);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值