暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

数据结构:第四节-复杂度分析(上)

Cpp入门到精通 2024-04-28
70

点击蓝字

山月

关注我们

第四节 复杂度分析(上)


上一节我们讲到了影响算法效率的一些因素,算法效率是指算法解决问题所需的时间和空间资源消耗,通常通过分析算法的时间复杂度空间复杂度来评估。


首先我们来介绍两种评估算法性能的方法,分别是"事前分析"和"事后统计",用于分析和度量算法在不同输入规模下的执行效率和资源消耗。


事前分析:

事前分析是在设计和实现算法之前对算法性能进行估计和预测的过程。它的优点是能够在算法设计阶段进行预测和估计,为算法设计提供理论依据。但是对于复杂的算法和实际情况可能存在偏差,无法完全预测所有情况下的算法表现。


事后统计:

事后统计是在算法实现完成后,通过实际运行和测量来评估算法的执行性能和效率。它的优点是能提供真实的、实际的算法性能数据,能够直接反映算法在特定环境下的表现。缺点是它需要实际执行算法,耗费时间和资源;可能无法覆盖所有输入情况。

在实际应用中,事前分析和事后统计通常结合使用,共同评估算法的性能和效率。综合利用两种方法可以全面地评估算法,并优化算法设计和实现,以满足不同场景下的性能要求和需求。

接下来我们具体阐述一下时间复杂度的分析方法:

时间复杂度是用来衡量算法执行时间随着输入规模增长而变化的量度,是评估算法效率的重要指标之一。


1.基本操作计数法

通过分析算法中基本操作(比如赋值操作、比较操作、循环次数等)的执行次数来推导时间复杂度。

对于循环结构,计算循环执行的次数与输入规模之间的关系,确定循环的执行次数;对于递归算法,通过递归关系式推导递归调用次数,进而分析时间复杂度。

我们举两个例子来更好理解:

第一个例子:假设有一个函数 sum,用于计算从1到n的所有整数的和。

    int sum(int n) {
        int sum = 0// 初始化和为0
    for (int i = 1; i <= n; ++i) {
    sum = sum + i; // 执行赋值操作和加法操作
        }
    return sum; // 返回计算结果
    }

    在这个函数中,我们可以定义以下基本操作

    一个赋值操作 sum = sum + i;,用于累加计算结果。

    一个加法操作 sum + i,用于求和。

    一个比较操作 i <= n,用于判断循环条件。


    我们可以统计每个基本操作的执行次数

    赋值操作 sum = sum + i; 执行了 n 次(i 从 1 到 n)。

    加法操作 sum + i 执行了 n 次(i 从 1 到 n)。

    比较操作 i <= n 执行了 n 次(i 从 1 到 n)。


    根据基本操作的计数,我们可以得出以下时间复杂度的估计:

    赋值操作和加法操作每次循环都执行,总共执行了 n 次。

    比较操作每次循环也执行,总共执行了 n 次。

    因此,整个算法的基本操作总数约为 3n 次(n 次赋值操作 + n 次加法操作 + n 次比较操作)。在大 O 表示法中,我们通常忽略常数系数,因此该算法的时间复杂度为 O(n)。


    第二个例子:假设有两个 n × n 的矩阵 A 和 B,我们想计算它们的乘积 C = A × B。

      for (int i = 0; i < n; ++i) {
      for (int j = 0; j < n; ++j) {
      for (int k = 0; k < n; ++k) {
      C[i][j] += A[i][k] * B[k][j]; // 执行乘法和累加操作
      }
      }
      }

      在矩阵相乘的过程中,我们可以定义以下基本操作

      一个乘法操作 A[i][k] * B[k][j],用于计算矩阵元素的乘积。

      多个加法操作 C[i][j] = C[i][j] + A[i][k] * B[k][j],用于累加结果。


      我们需要计算矩阵乘法中基本操作的执行次数

      对于每个元素 C[i][j],需要进行 n 次乘法操作和 n-1 次加法操作(因为第一个元素赋值不需要加法)。

      因此,总共有 n^2 个元素,每个元素执行了 n 次乘法和 n-1 次加法。


      根据基本操作的计数,我们可以估算矩阵相乘的时间复杂度:

      每个元素执行 n 次乘法和 n-1 次加法操作。

      因此,总的基本操作次数约为 n^2 * (n + (n - 1)) = n^2 * (2n - 1)。

      在大 O 表示法中,我们通常关注最高阶的项,因此矩阵相乘的时间复杂度为 O(n^3)。

      2.大 O 记号法

      使用大 O 记号(O)来表示算法的时间复杂度,描述算法执行时间与输入规模之间的关系。大 O 记号表示算法的渐进上界,表示算法的最坏情况时间复杂度。

      常见的时间复杂度包括 O(1)、O(log n)、O(n)、O(n^2)、O(2^n) 等,用于衡量算法在不同输入规模下的执行效率。

      3.最坏情况分析

      时间复杂度通常采用最坏情况下的执行时间来分析,即算法在输入规模最大、效率最低的情况下所需的时间,分析算法在最坏情况下的执行路径和操作次数,推导出时间复杂度的上界。

      4.平均情况分析

      有些情况下,需要分析算法在平均情况下的执行时间,对于涉及随机性多种输入情况的算法,可以通过概率论和数学期望等方法来分析平均时间复杂度。

      5.最优情况分析

      时间复杂度也可以用来描述算法在最优情况下的执行时间,但最优情况下的时间复杂度通常不具有实际意义,因为它并不能反映算法在大多数情况下的性能。

      这节我们主要介绍基本操作计数法,下节我们继续介绍其他分析方法,感谢观看!欢迎各位的点赞与关注!您的点赞和关注是我学习更新的动力!如有问题,可下方留言!



      往期推荐

      C++基础知识

      C++进阶知识

      C++STL知识

      • end • 

      欢我们的内容就点“在看”分享给小伙伴哦



      文章转载自Cpp入门到精通,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

      评论