• 空间复杂度


    目录

    概念: 

    实例1:

    实例2:

    实例3:递归

    实例4:二维数组

    实例5:

    实例6:斐波那契额数列 



     

    概念: 

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

    空间复杂度不是程序占用了多少bytes的空间,因为这个也没太大意义,所以空间复杂度算的是变量的个数。

    空间复杂度计算规则基本跟实践复杂度类似,也使用大O渐进表示法。

    • 且对于空间复杂度而言,再实践中其实不看重空间复杂度,看重时间复杂度,主要因为我们现在看重的是效率问题 ,所以我们再写代码的时候主要是运用空间来换取时间。
    • 不过空间复杂度其实也会溢出的,现在大部分见到代码中,他们的空间复杂度均是再O(1)和O(N)之间。

    注意:空间复杂度本质上是计算临时存储空间的变量个数,临时开辟空间的个数,调用函数内部临时开辟的。

    且空间复杂度计算的是运行内存的多少。

     大O渐渐表示法:

    时间复杂度-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/2301_76445610/article/details/133961910?spm=1001.2014.3001.5501

    实例1:

    1. void BubbleSort(int* a, int n)
    2. {
    3. assert(a);
    4. for (size_t end = n; end > 0; --end)
    5. {
    6. int exchange = 0;
    7. for (size_t i = 1; i < end; ++i)
    8. {
    9. if (a[i - 1] > a[i])
    10. {
    11. Swap(&a[i - 1], &a[i]);
    12. exchange = 1;
    13. }
    14. }
    15. if (exchange == 0)
    16. break;
    17. }
    18. }

    实例1中,并未有使用临时变量进行空间的存储和开辟,运用的内存空间是函数中传递调用的,所以这里的空间复杂度是O(1)

    实例2:

    1. long long* Fibonacci(size_t n)
    2. {
    3. if (n == 0)
    4. return NULL;
    5. long long* fibArray = (long long*)malloc((n + 1) * sizeof(long long));
    6. fibArray[0] = 0;
    7. fibArray[1] = 1;
    8. for (int i = 2; i <= n; ++i)
    9. {
    10. fibArray[i] = fibArray[i - 1] + fibArray[i - 2];
    11. }
    12. return fibArray;
    13. }

    实例2中,使用了临时变量fibArry进行存储了n+1个long long  类型的空间,所以这里的时间复杂度是O(N)

    实例3:递归

    1. long long Fac(size_t N)
    2. {
    3. if(N == 0)
    4. return 1;
    5. return Fac(N-1)*N;
    6. }

    和时间复杂度一样,再递归中空间复杂度是累加的,在这里我们调用递归了N次,而也开辟了N个不同的空间,所以这里的空间复杂度是O(N)

    实例4:二维数组

    1. int** fun(int n) {
    2. int ** s = (int **)malloc(n * sizeof(int *));
    3. while(n--)
    4. s[n] = (int *)malloc(n * sizeof(int));
    5. return s;
    6. }

    根据malloc函数开辟空间以此来建立二维数组,在代码中,我们先开辟了行的空间,一个开辟了N个,而再每一个行的空间内部,又开辟了N个列的空间,于是总共开辟的空间便是N^2

    所以这里的空间复杂度是O(N^2) 

    实例5:

    问:如果一个函数的内部中只定义了一个二维数组a[3][6],请问这个函数的空间复杂度是多少?

    答:函数内部数组的大小是固定的,不论函数运行多少次,所需空间都是固定大小的,因此空间复杂度为O(1)

    实例6:斐波那契额数列

    实例6:斐波那契额数列 

    1. long long Fib(size_t N)
    2. {
    3. if(N < 3)
    4. return 1;
    5. return Fib(N-1) + Fib(N-2);
    6. }

     再时间复杂度我们讲过,时间是累加的,而空间不同,空间不但可以是累加的,也可以进行重复利用,这与栈帧的销毁和重复利用,以及斐波那契额数列的特性有关。

    在斐波那契额数列的递归中,它是如上图所示,先完成一条分支,然后再接着完成下一条分支,直到全部完成,而在这里的过程中,它所开辟的空间是会被重复利用的,并不会直接创建一个新的空间, 这也符合了函数栈帧的性质。

    因为空间的利用,所以这里的累加的空间,也就仅仅是开辟了N个空间,所以这里的时间复杂度是O(N)

    注意,只有空间可以进行利用,而时间只能进行累加!

  • 相关阅读:
    工作笔记.
    【从0到1设计一个网关】性能优化---Netty线程数配置与JVM参数配置
    聊聊jedis连接池参数配置
    如何优雅的创建线程
    微信小程序实现蓝牙开门前后端项目(一)
    kettle学习--基础--01--介绍
    重写与重载and抽象类与接口!!!!
    A记录 CNAME记录是什么 | DNS 查询的过程 | DNS 根服务器是什么 | 配置域名 CNAME 原理
    企业应用级自动化运维的建设思路
    Spring 面试题(注解、数据访问、AOP、MVC)
  • 原文地址:https://blog.csdn.net/2301_76445610/article/details/134081749