时间复杂度空间复杂度


绪论

        时间复杂度和空间复杂度是一个用来衡量其算法好坏的评判工具,具体的请继续往下观看。

时间复杂度空间复杂度_第1张图片

话不多说安全带系好,发车啦(建议电脑观看)

        附:红色,部分为重点部分;蓝颜色为需要记忆的部分(不是死记硬背哈,多敲);黑色加粗或者其余颜色为次重点;黑色为描述需要

思维导图:

要XMind思维导图的话可以私信哈

1.时间复杂度        

知识点:

时间复杂度:在计算机科学中,算法的时间复杂度是一个函数,它定量描述了该算法的运行时间。一 个算法执行所耗费的时间,从理论上说,是不能算出来的,只有你把你的程序放在机器上跑起来,才能知 道。但是我们需要每个算法都上机测试吗?是可以都上机测试,但是这很麻烦,所以才有了时间复杂度这个 分析方式。一个算法所花费的时间与其中语句的执行次数成正比例。(简单来说时间复杂度的计算,并不是计算其花费的时间,而是计算其运行时的执行次数

细节(注意点):

如何来算一个算法的时间复杂度:

我们在算时间复杂度的时候一般会用到 大O渐进表示法:

  1. 对于常数次的时间复杂度来说直接用1来表示即:O(1)
  2. 算时间复杂度时我们只取大概的量级(取到最大的量级)
  3. 对于一个N * 常数时 我们可以直接省略所乘的常数次 : O(N)(对于一个N来说乘上一个常数对数据影响并不大)
  4. 在算时间复杂度是我们一般都是直接算他的最坏情况 (因为有些时间复杂度无法直接算出,可能分最好和最坏的情况)
  5. 把log以2为底的N的对数 一般写成直接logN

练习:

例1:

void Func2(int N)
{
     int count = 0;
     for (int k = 0; k < 2 * N ; ++ k) // 2 * N == N
     {
         ++count;
     }
     int M = 10;
     while (M--)// O(1)
     {
         ++count;
     }
     printf("%d\n", count);
}

上面Fun2时间复杂度: O(N)  (  一般以这种形式来写: ...... 的时间复杂度是: O(...) )

 例2:

void Func4(int N)
{
 int count = 0;
 for (int k = 0; k < 100; ++ k)//常数次
 {
 ++count;
 }
 printf("%d\n", count);
}

//Fun4的时间复杂度:O(1)

例3:

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;
 }
 printf("%d\n", count);
}

//

因为不知道 M N 的关系 所以写成 O(M+N)

如果 M >> N  : O(M) 

反之 :O (N)

如果 M == N : O(N) / O (M)


2.空间复杂度

知识点:

空间复杂度也是一个数学表达式,是对一个算法在运行过程中临时占用存储空间大小的量度 。 空间复杂度不是程序占用了多少bytes的空间,因为这个也没太大意义,所以空间复杂度算的是变量的个数。 空间复杂度计算规则基本跟时间复杂度类似,也使用大O渐进表示法

细节:

  1. 函数运行时所需要的栈空间(存储参数、局部变量、一些寄存器信息等)在编译期间已经确定好了,因此空间复杂度主要通过函数在运行时候显式申请的额外空间来确定(即函数的参数一般不用算到该函数的空间复杂度中去
  2. 一般直接数变量个数即可,除非开辟申请了额外的空间(malloc(n * sizeof(int) )

练习:

例1:

void BubbleSort(int* a, int n)
{
 assert(a);
 for (size_t end = n; end > 0; --end)
 {
     int exchange = 0;
     for (size_t i = 1; i < end; ++i)
     {
         if (a[i-1] > a[i])
         {
             Swap(&a[i-1], &a[i]);
             exchange = 1;
         }
     }
 if (exchange == 0)
     break;
 }
}
//时间复杂度是:O(N ^ 2) : n - 1 + n - 2 + ... + 1 = n(a1+an)/2 = n ^ 2

//空间复杂度是:O(1): 总共就3个变量

例2:

long long* Fibonacci(size_t n)
{
 if(n==0)
 return NULL;
 
 long long * fibArray = (long long *)malloc((n+1) * sizeof(long long));
 fibArray[0] = 0;
 fibArray[1] = 1;
 for (int i = 2; i <= n ; ++i)
 {
 fibArray[i] = fibArray[i - 1] + fibArray [i - 2];
 }
 return fibArray;
}
//空间复杂度是:O(N) : malloc 开辟了一个新的空间 大约是N个 (这里并不关心byte)

例3:

long long Fac(size_t N)
{
 if(N == 0)
 return 1;
 
 return Fac(N-1)*N;
}
//因为递归,每个递归建立的栈帧都要创建变量,所以
//空间复杂度是: O (N)

例4:

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

其空间复杂度是:O(N)、时间复杂度是:O(2^N)
因为:

时间复杂度空间复杂度_第2张图片

 知识点:当栈帧空间归还给操作系统后,下一次开辟栈帧可能会占用同一片区域。

时间复杂度空间复杂度_第3张图片

 

本章完。预知后事如何,暂听下回分解。

持续更新大量数据结构细致内容,三连关注哈

你可能感兴趣的:(数据结构)