《数据结构》详解精炼:时间复杂度(1)

2.5 时间复杂度(1)

1. 时间复杂度

例题 2.5.1 : 两个 <math xmlns="http://www.w3.org/1998/Math/MathML"> n n </math>n 阶方阵 <math xmlns="http://www.w3.org/1998/Math/MathML"> A \pmb{A} </math>AA 和 <math xmlns="http://www.w3.org/1998/Math/MathML"> B \pmb{B} </math>BB 相加 <math xmlns="http://www.w3.org/1998/Math/MathML"> C = A + B \pmb{C}=\pmb{A}+\pmb{B} </math>CC=AA+BB 的算法

c 复制代码
#define MAX 20
void matrix_add(int n, int A[MAX][MAX], int B[MAX][MAX], int C[MAX][MAX])
{
    int i, j;
    for(i=0; i<n; i++){                    //语句频度:n+1
        for(j=0; j<n; j++){                //语句频度:n(n+1)
            C[i][j] = A[i][j] + B[i][j];   //语句频度:n*n
        }
    }
}

所有语句的语句频度: <math xmlns="http://www.w3.org/1998/Math/MathML"> f ( n ) = ( n + 1 ) + [ n ( n + 1 ) ] + n 2 = 2 n 2 + 2 n + 1 f(n)=(n+1)+[n(n+1)]+n^2=2n^2+2n+1 </math>f(n)=(n+1)+[n(n+1)]+n2=2n2+2n+1 。

运行时间记作 <math xmlns="http://www.w3.org/1998/Math/MathML"> T ( n ) T(n) </math>T(n) ,当问题规模 <math xmlns="http://www.w3.org/1998/Math/MathML"> n n </math>n 增大时,算法的执行时间也会增加,根据前面知识(008节:问题规模和语句频度)可知, <math xmlns="http://www.w3.org/1998/Math/MathML"> T ( n ) T(n) </math>T(n) 与 <math xmlns="http://www.w3.org/1998/Math/MathML"> f ( n ) f(n) </math>f(n) 有相同的增长率,于是使用大 O 记号:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> T ( n ) = O ( f ( n ) ) T(n) = O(f(n)) </math>T(n)=O(f(n))

则称之为算法的渐进时间复杂度 ,简称时间复杂度(time complexity)。

根据 009 节关于大 O 记号的知识,可知例题 2.5.1 算法的时间复杂度是: <math xmlns="http://www.w3.org/1998/Math/MathML"> T ( n ) = O ( n 2 ) T(n)=O(n^2) </math>T(n)=O(n2) 。

2. 基本语句

要估算时间复杂度,必须找出所有语句的语句频度。但是,根据大 O 记号的性质可知,最关心的应该是对时间复杂度贡献最大的语句,也就是运行次数最多的语句,这样的语句称为基本语句 (或称基本操作)。

基本语句指的是算法中重复执行次数和算法的执行时间成正比的语句,它对算法运行时间的贡献最大。

一般,以算法中最深层循环内的语句作为基本语句。

在例题 2.5.1 中,第 7 行作为基本语句。基本语句的频度为 <math xmlns="http://www.w3.org/1998/Math/MathML"> n 2 n^2 </math>n2 ,于是时间复杂度为 <math xmlns="http://www.w3.org/1998/Math/MathML"> T ( n ) = O ( n 2 ) T(n)=O(n^2) </math>T(n)=O(n2) 。

因此,估算算法的时间复杂度,关键是找出基本语句的语句频度。

例题 2.5.2:分析一下算法的时间复杂度

c 复制代码
void func(int n){
    int i=0, s=0;
    while(s < n){
        i++;
        s = s + i;
    }
}

解:本题中第 4、5 两行都是基本语句,因此关注它们的语句频度。

外层循环次数 i(i=0;i++) s(s=0;s=s+i)
1 1 1
2 2 1+2
3 3 1+2+3
4 4 1+2+3+4
<math xmlns="http://www.w3.org/1998/Math/MathML"> ⋮ \vdots </math>⋮ <math xmlns="http://www.w3.org/1998/Math/MathML"> ⋮ \vdots </math>⋮ <math xmlns="http://www.w3.org/1998/Math/MathML"> ⋮ \vdots </math>⋮
r r <math xmlns="http://www.w3.org/1998/Math/MathML"> 1 + 2 + 3 + 4 + ⋯ + r 1+2+3+4+\cdots+r </math>1+2+3+4+⋯+r

因为 s < n 为真才循环,所以:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> 1 + 2 + 3 + 4 + ⋯ + r < n r ( 1 + r ) 2 < n − 1 − 8 n + 1 2 < r < − 1 + 8 n + 1 2 ∵ r > 0 ∴ 0 < r < − 1 + 8 n + 1 2 \begin{split} &1+2+3+4+\cdots+r\lt n \\&\frac{r(1+r)}{2}\lt n \\ &\frac{-1-\sqrt{8n+1}}{2}\lt r\lt\frac{-1+\sqrt{8n+1}}{2} \\&\because r\gt 0 \\&\therefore~0\lt r\lt\frac{-1+\sqrt{8n+1}}{2} \end{split} </math>1+2+3+4+⋯+r<n2r(1+r)<n2−1−8n+1 <r<2−1+8n+1 ∵r>0∴ 0<r<2−1+8n+1

由于外层循环的次数,就是第 4 行语句的执行次数,即语句频度。

故:基本语句的语句频度上界是函数: <math xmlns="http://www.w3.org/1998/Math/MathML"> − 1 + 8 n + 1 2 \frac{-1+\sqrt{8n+1}}{2} </math>2−1+8n+1

所以算法的时间复杂度是: <math xmlns="http://www.w3.org/1998/Math/MathML"> T ( n ) = O ( − 1 + 8 n + 1 2 ) = O ( n ) T(n)=O(\frac{-1+\sqrt{8n+1}}{2})=O(\sqrt{n}) </math>T(n)=O(2−1+8n+1 )=O(n )

注意:本节课后的练习题,要求都使用这里所介绍的解法求解。

本文由mdnice多平台发布

相关推荐
假装我不帅1 小时前
asp.net framework从webform开始创建mvc项目
后端·asp.net·mvc
神仙别闹1 小时前
基于ASP.NET+SQL Server实现简单小说网站(包括PC版本和移动版本)
后端·asp.net
计算机-秋大田1 小时前
基于Spring Boot的船舶监造系统的设计与实现,LW+源码+讲解
java·论文阅读·spring boot·后端·vue
货拉拉技术2 小时前
货拉拉-实时对账系统(算盘平台)
后端
掘金酱2 小时前
✍【瓜分额外奖金】11月金石计划附加挑战赛-活动命题发布
人工智能·后端
代码之光_19802 小时前
保障性住房管理:SpringBoot技术优势分析
java·spring boot·后端
ajsbxi3 小时前
苍穹外卖学习记录
java·笔记·后端·学习·nginx·spring·servlet
颜淡慕潇3 小时前
【K8S问题系列 |1 】Kubernetes 中 NodePort 类型的 Service 无法访问【已解决】
后端·云原生·容器·kubernetes·问题解决
尘浮生4 小时前
Java项目实战II基于Spring Boot的光影视频平台(开发文档+数据库+源码)
java·开发语言·数据库·spring boot·后端·maven·intellij-idea
尚学教辅学习资料4 小时前
基于SpringBoot的医药管理系统+LW示例参考
java·spring boot·后端·java毕业设计·医药管理