• 【C语言数据结构】空间复杂度和时间复杂度(详细分析)


    目录

    1. 数据结构介绍

    2.算法介绍

    3.时间复杂度,(空间复杂度


    1.数据结构介绍

    首先我们讲解一下什么是数据结构(从今天开始,博主要开始学习数据结构啦,以后再学习算法会给大家分享更多深入浅出的干货!)

     这个听起来就很高大上的名字,其实是计算机存储和组成数据的方式,他是一些数据元素的组合,这些元素之间相互存在着一些一种或者多种的联系

    我们学习数据结构是为了更好的了解计算机工作的原理,实现更好的人机交流

    2.算法

    和数学公式一样,其实算法就是对于某一类计算机问题的   总结好的  特定实现思路

    比如说我现在做到一个题目,需要用到排序

    这时候我们就想到一些排序的方法,这些方法就相当于算法,当然算法不是这么简单的,也有很多很有技巧的,这里只是为了举例子

    所以算法就是对于某一种特定问题(比如排序)的具体实现形式(堆排,快排,冒泡..)

    3.时间复杂度

    首先解释什么是复杂度

    对于两个算法(比如冒泡和堆排),应用到实际问题里谁更好呢?难道我说第一个更好就一定是对的吗

    当然有一个衡量标准:复杂度

    复杂度分为两种:时间,空间

    但是主要说的还是时间复杂度

    因为

    时间复杂度:一个关于时间的函数,用来描述一个程序结束之后,某一部分被调用的次数,用俩衡量算法的效率

    空间复杂度:程序运行需要额外开辟的空间的大小

    而我们知道,随着时间的推移,现在的电脑内存已经很大了,空间复杂度已经不作为特别重要的参考依据,并且计算空间复杂度本身也不是特别复杂

    3.1时间复杂度

    1. void Func1(int N)
    2. {
    3. int count = 0;
    4. for (int i = 0; i < N; ++i)
    5. {
    6. for (int j = 0; j < N; ++j)
    7. {
    8. ++count;
    9. }
    10. }
    11. for (int k = 0; k < 2 * N; ++k)
    12. {
    13. ++count;
    14. }
    15. int M = 10;
    16. while (M--)
    17. {
    18. ++count;
    19. }
    20. printf("%d\n", count);
    21. }

    现在是这样的过程,所以总共的次数应该是加起来

    但是真的有这么麻烦吗

    我们来看一段代码

    1. #include
    2. #include
    3. int main()
    4. {
    5. int begin=clock();
    6. int count = 0;
    7. for (size_t i = 0; i < 1000; i++)
    8. {
    9. count++;
    10. }
    11. int end = clock();
    12. printf("%d毫秒\n", end - begin);
    13. return 0;
    14. }

     这个代码调用一个的函数来实现整个程序运行时间的计算

     其实如果我们把数字再改的更大

     

     5毫秒真的是很短的时间,也就是在循环中,常数次的循环其实时间上来讲和一次没很大区别

    这里我们用到一个大O渐进的方法来表示时间复杂度

    常数次的调用定义为O(1)

    大O渐进:

    常数次都当成1次

    系数不影响阶   可以忽略(O(2*N)=O(N))

    抓大头  O(N^2+2*N+10)=O(N^2)

    需要注意的是,以后我们计算时间复杂度的题目可能都不会给出代码,因为最重要的是思想,训练的就是给一个函数我立马就能想起来他用的什么方法实现的!!!!!

     来看他的时间复杂度

     这个时候我们就蒙了,这个字符到底出现在哪里我是不知道的

    所以我们提出

    最好情况:一次找到

    最坏情况:(假设字符串长度为n)n次找到

    平均情况:N/2

    但是我们思考一下就知道,只有最坏情况才是真正有意义的 

    所以定义:在这种很蒙的情况,最坏情况对应的时间复杂度就是我们要找的时间复杂度

    对于上面strchr函数的时间复杂度就是O(N)

    再看一个

    1. void Func2(int N)
    2. {
    3. int count = 0;
    4. for (int k = 0; k < 2 * N; ++k)
    5. {
    6. ++count;
    7. }
    8. int M = 10;
    9. while (M--)
    10. {
    11. ++count;
    12. }
    13. printf("%d\n", count);
    14. }

     根据大O渐进的方法,最后的时间复杂度就是O(N)

    冒泡排序的时间复杂度是多少呢

    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. }

    所以一个数字需要的次数分别是N ,N-1,N-2,...........,2

    等差数列

    就是O(N^2)

     递归的时间复杂度呢

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

     注意我们在这里不能以为往下递和往上推各有N次一共就是2*N

    在递归函数的时间复杂度里,我们定义每次递归调用的函数次数累加就是最后的结果

    3.2 空间复杂度

    其实就是在程序里 定义的变量,或者新开辟空间的大小

    还是符合大O渐进的规则

    常数个还是令为O(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. }

    现在问冒泡排序里面的空间复杂度是多少呢

    一看肯定是常数个所以O(1)

     

    再来看斐波那契的空间复杂度

    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. }

     其实只要有这个N+1,我们就知道别的常数个可以都不看了

    O(N)

    再看一个递归

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

    一共创建了N+1个栈帧所以空间复杂度是O(N)

    本文到此结束啦,相信你一定收获满满

     

  • 相关阅读:
    好用的Android软件汇总
    抖音视频批量采集软件|视频评论下载工具
    如何用代码画出一幅好看的画
    volatile原理及happens-before规则
    Abnova丨BSG 单克隆抗体中英文说明
    正点原子嵌入式linux驱动开发——TF-A使用
    PostgresSQL - 生成uuid
    Day93.SpringBoot: 配置、使用、原理
    Spring Boot集成阿里云视频点播服务的过程记录
    MYSQL 存储java.sql.Timestamp类型的数据时,mysql存储时间和java获取到的时间相差8小时
  • 原文地址:https://blog.csdn.net/weixin_71138261/article/details/127474684