数据结构与算法——5.空间复杂度分析

文章详细阐述了Java中不同数据类型和结构的内存占用,包括基本数据类型、对象、数组等,并通过实例分析了两种反转数组元素算法的空间复杂度,指出在Java中考虑空间复杂度的重要性,尤其是在资源有限的环境中。
摘要由CSDN通过智能技术生成

这篇文章让我们来讨论一下空间复杂度

目录

1.概述

2.java中常见内存占用

2.1基本数据类型内存占用情况

2.2计算机访问内存的方式

2.3引用大小

2.4对象大小

2.5一般内存占用

2.6数组占用地址大小

3.算法的空间复杂度

4.小结


1.概述

计算机的软硬件都经历了一个比较漫长的演变史,作为为运算提供环境的内存,更是如此,从早些时候的512k,经历了1M,2M,4M...等,发展到现套的8G,甚至16G和32G,所以早期,算法在运行过程中对内存的占用情况也是一个经常需要考虑的问题。我么可以用算法的空间复杂度来描述算法对内存的占用。

2.java中常见内存占用

2.1基本数据类型内存占用情况

2.2计算机访问内存的方式

 计算机访问内存是一字节一字节的,即一次访问一字节:

2.3引用大小

一个引用(机器地址)需要8个字节表示

例如:Date date = new Date(); 则这个date变量就需要用8个字节来表示

2.4对象大小

创建一个对象,比如new Date(),除了Date对象内部存储的数据(例如年月日等信息)占用的内存,该对象本身也有内存开销,每个对象的自身开销是16个字节,用来保存对象的头信息。

2.5一般内存占用

一般内存的使用,如果不够8个字节,都会被自动补充为8字节:

例:public class A{

                public int a = 1;

        }

分析:

通过new A()创建一个对象的内存占用如下:

  1. 整型成员变量占用4个字节;
  2. 对象本身占用16个字节

那么创建这个对象总共需要20个字节,但由于不是8的整数倍,所以自动填充至24个字节(实质是int a 时就直接占用8个字节了)

2.6数组占用地址大小

java中数组被被限定为对象,他们一般都会因为记录长度而需要额外的内存,一个原始数据类型的数组一般需要24字节的头信息(16个自己的对象开销,4字节用于保存长度以及4个填充字节)再加上保存值所需的内存


3.算法的空间复杂度

了解了java的内存最基本的机制,就能够有效帮助我们估计大量程序的内存使用情况。

算法的空间复杂度计算公式记作:S(n)=O(f(n));其中n为输入规模,f(n)为语句关于n所占存储空间的函数。

案例:对指定的数组元素进行反转,并返回反转的内容。

解法一:

public static int[] reverse1(int[] arr){
        int n = arr.length;//申请4个字节
        int temp;申请4个字节
        for (int start = 0,end=n-1; start <= end; start++,end--) {
            temp=arr[start];
            arr[start]=arr[end];
            arr[end]=temp;
        }
        return arr;
    }

解法二:

public static int[] reverse2(int[] arr){
        int n = arr.length;//申请4个字节
        int[] temp = new int[n];//申请4*n个字节+数组自身头信息开销24个字节
        for (int i = n-1; i >=0 ; i--) {
            temp[n-1-i]=arr[i];
        }
        return temp;
    }

忽略判断条件占用的内存,我们得出的内存占用情况如下:

算法一:

        不管传入的数组大小为多少,始终额外申请4+4=8个字节

算法二:

        4+4n+24=4n+28

根据大O推导法则,算法一的空间复杂度为O(1),算法二的空间复杂度为O(n),所以从空间占用的角度讲,算法一要优于算法二。由于java中有内存垃圾回收机制,并且jvm对程序的内存占用也有优化(例如即时编译),我们无法精确的评估一个java程序的内存占用情况,但是了解了java的基本内存占用,使我们可以对java程序的内存占用情况进行估算。
由于现在的计算机设备内存一般都比较大,基本上个人计算机都是4G起步,大的可以达到32G,所以内存占用一般情况下并不是我们算法的瓶颈,普通情况下直接说复杂度,默认为算法的时间复杂度。
但是,如果你做的程序是嵌入式开发,尤其是一些传感器设备上的内置程序,由于这些设备的内存很小,一般为几kb,这个时候对算法的空间复杂度就有要求了,但是一般做java开发的,基本上都是服务器开发,一般不存在这样的问题。

4.小结

这篇文章就简要的讲述了一下算法的空间复杂度,其实不是很重要,一些小知识点知道就行,重要的还是时间复杂度。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

L纸鸢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值