[数据结构]时间复杂度和空间复杂度

本文详细解析了算法效率中的时间复杂度与空间复杂度概念,通过实例演示如何运用大O表示法计算多重循环、二分查找、递归函数的时间复杂度,并介绍了常数变量和递归函数的空间复杂度计算。从冒泡排序到递归阶乘,助你理解算法效率评估的关键技巧。
摘要由CSDN通过智能技术生成

目录

​编辑

 

💊1.算法效率 

💊2.时间复杂度

💊2.1定义:指的是算法中基本操作的执行次数;

💊2.2.1大O的渐进表示法推导方法(三步)

(2)常数次的简单循环:

(3)二重循环(进阶):

(4)二分查找:

(5)递归函数的时间复杂度的计算:

💊3.空间复杂度:

💊3.1有常数变量:

💊3.2 递归函数:


💊1.算法效率 

算法效率分为时间复杂度空间复杂度。

💊2.时间复杂度

💊2.1定义:指的是算法中基本操作的执行次数

         本质上来说是一个函数;

💊2.2.1大O的渐进表示法推导方法(三步)

1,用常数1取代运行时间中的所有加法常数。

2,在修改后的运行次数函数中,只保留最高阶项。

3,如果大O阶项存在且不是1,则去除与这个项目相乘的常数。得到的结果就是大O阶。

下面举一些计算时间复杂度的例子

(1)简单多重循环;

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

分析 :由于上面程序包含一个循环嵌套N * N,一个单循环 2 * N,和while循环M;

所以上面程序的时间复杂度函数可表示为F(N) = N * N + 2 * N + M;

根据大O的渐进表示法则表示为O()

void Func2(int N)
{

      int count = 0;
      for(int k = 0; k < 2 * N; k++)
      {
         count++;
      }
       int M = 10;
      while(M--)
      {
           ++count;
      }
      printf("%d", count);
}

分析 :上面的程序包含一个for循环(2 * N)和while循环(M);

所以上面程序的时间复杂度函数可表示为 :F(N) = 2 * N + M;

用大O的渐进法表示为O(N);(后面的M因为是常数根据大O渐进法所以直接省略)

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);
}
    

分析 :上面的程序包含两个for循环;

所以上面程序的时间复杂度函数可表示为:F(N) = M + N;

用大O的渐进法表示为O(N + M);

(2)常数次的简单循环:

void Func4(int N)
{    
    int count = 0;
    for(int k = 0; k < 100; k++)
    {
        count++;
    }
     printf("%d", count);
}

分析 :只有一个常数次的循环;

用大O的渐进法表示为O(1);

(3)二重循环(进阶):

冒泡排序:

void BubbleSort(int *a, int n)
{
   assert(a);
   for(int i = n; i > 0; i--)
   {
       int t = 0;
       for(int j - 1; j < n; j++)
       {
          if(a[j - 1] > a[j])
          {
            Swap(&a[j - 1], &a[j]);
            t = 1;
          }
       }
       if(t == 0)
        break;
    }
}

分析 : 根据冒泡排序的原理可知每次循环的次数都减一, 第一次循环的次数为(N - 1);

所以循环次数为 (N - 1) + (N - 2) + ......+ 2 + 1;

根据大O的渐进法可得该程序的时间复杂度为O();

(4)二分查找:

int BinarySearch(int * a, int n, int x)
{
    assert(a);
    int begin = 0;
    int end  = n;
    while(begin < end)
    {
        int mid = begin + ((end - begin) >> 1);
        if(a[mid] < x)
           begin  = mid + 1;
        else if (a[mid] > x)
           end = mid;
        else
           return mid;
     }
     return -1;
} 

分析 :假设数组中有N个根据二分查找的原理可知每次查找范围减半;所以循环的次数X = 该程序的时间复杂度用大O的渐进法表示为O()

(5)递归函数的时间复杂度的计算:

对于递归函数给出计算时间复杂度的公式:递归次数 * 每次递归函数的次数

 1 , 递归计算阶乘

long long Factorial(int N)
{
   return N < 2 ? N: Factorial(N - 1) * N;
}

分析:由于每次递归调用一次函数总共调用N次;

所以该程序的时间复杂度为: O( N);    

2,递归计算斐波那契数列:

long long Fibonacci(int N)
{
   return N < 2 ? N : Fibonacci(N - 1) + Fibonacci(N - 2);
}

分析

 故该程序的时间复杂度表示为O(2^(N - 1));

💊3.空间复杂度:

计算的规则是:计算大概定义的变量的个数;

💊3.1有常数变量:

​
void BubbleSort(int *a, int n)
{
   assert(a);
   for(int i = n; i > 0; i--)
   {
       int t = 0;
       for(int j - 1; j < n; j++)
       {
          if(a[j - 1] > a[j])
          {
            Swap(&a[j - 1], &a[j]);
            t = 1;
          }
       }
       if(t == 0)
        break;
    }
}

​

分析 :以上程序有常数个变量;

则该程序的空间复杂度为O(1)

💊3.2 递归函数:

递归函数空间复杂度的计算方法:递归的栈帧深度因为递归函数要建立函数栈帧需要消耗空间

long long Factorial(int N)
{
   return N < 2 ? N: Factorial(N - 1) * N;
}

分析 :由于该程序在递归的过程中递归的栈帧深度为N;

所以该算法的空间复杂度为O(N);


如果以上内容帮到你,请点赞收藏吧;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

SummerM.

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

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

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

打赏作者

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

抵扣说明:

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

余额充值