递归算法中的时间复杂度分析

2023-11-19

对于一种算法的时间复杂度分析还是特别重要的,在一些非递归算法中,我们仅仅看运算次数最多的那一行代码可能执行多少次就可以,实际就是看在循环中变量的变化,但是对于递归算法中该怎么分析呢?下面介绍几种递归函数中的算法时间复杂度分析的方法

0.递推法

这种方法是最简单的,也是最容易理解的一种方法,对于一个递归函数,我们可以利用他的递归方程,将其递推到常量的情况下,这样子就很容易求解他的时间复杂度了,可以看一下下面的递归方程
T ( n ) = { 1 n = 1 T ( n − 1 ) + 1 n > 0 T(n) = \left\{\begin{matrix} 1 \qquad n=1\\ T(n-1)+1 \qquad n>0 \end{matrix}\right. T(n)={1n=1T(n1)+1n>0
我们可以递归成
T ( n ) = T ( n − 1 ) + 1 = T ( n − 2 ) + 2 = T ( n − 3 ) + 3 = . . . = T ( 1 ) + n − 1 T(n)= T(n-1)+1 = T(n-2) +2 = T(n-3)+3=...=T(1)+ n-1 T(n)=T(n1)+1=T(n2)+2=T(n3)+3=...=T(1)+n1
这样很容易就可以看出来这个上面这个递归算法的时间复杂度是O(n)

这种方法思路比较简单,但是使用的时候会特别复杂,上面举的例子是一种比较简单的情况,要是比较复杂的情况这种就会很麻烦。

1.Master定理

master定理又称为主定理,这是一种快速的得出递归函数的时间复杂度

下面看一下,主定理的内容:

对于任意的递归函数,我们都一可以写出他的递归定义,下面我们给出递归定义的一般形式:
T ( n ) = { O ( 1 ) n = n 0 a T ( n b ) + f ( n ) n > n 0 T(n) = \left\{\begin{matrix} O(1) \qquad n=n0\\ aT(\frac{n}{b})+f(n) \qquad n>n0 \end{matrix}\right. T(n)={O(1)n=n0aT(bn)+f(n)n>n0
这里要是a>=1,b>1,并且f(n)是正函数

使用主定理方法,就是比较两个公式阶的比较 n log ⁡ b a n^{\log_{b}{a} } nlogba f ( n ) f(n) f(n),已求出T(n)的时间复杂度。

规则1:如果 f ( n ) = O ( n log ⁡ b a − ε ) f(n) = O(n^{\log_{b}{a-\varepsilon } } ) f(n)=O(nlogbaε) 其中 ε \varepsilon ε >0 为常数,也就是说 f ( n ) < O ( n log ⁡ b a ) f(n) < O(n^{\log_{b}{a} } ) f(n)<O(nlogba) ,则 T ( n ) = O ( n log ⁡ b a ) T(n) = O(n^{\log_{b}{a} } ) T(n)=O(nlogba)

规则2:如果 f ( n ) = Θ ( n log ⁡ b a ) f(n) = \Theta (n^{\log_{b}{a} } ) f(n)=Θ(nlogba) ,则 T ( n ) = O ( n log ⁡ b a log ⁡ n ) T(n) = O(n^{\log_{b}{a} } \log_{}{n} ) T(n)=O(nlogbalogn)

规则3:如果 f ( n ) = Ω ( n log ⁡ b a + ε ) f(n) = \Omega (n^{\log_{b}{a+\varepsilon } } ) f(n)=Ω(nlogba+ε) 其中 ε \varepsilon ε >0 为常数,也就是说 f ( n ) > O ( n log ⁡ b a ) f(n) > O(n^{\log_{b}{a } } ) f(n)>O(nlogba) 且存在n0,当n>n0时, a f ( n b ) ≤ c f ( n ) af(\frac{n}{b} )\le cf(n) af(bn)cf(n) 成立,c<1为常数,则 T ( n ) = O ( f ( n ) ) T(n) = O(f(n) ) T(n)=O(f(n))

以上就是主定理的内容,我们可以根据其规则直接快速的来判断递归函数的时间复杂度。

下面举个栗子看一看主定理的使用:

例一:

下面这个是一个时间复杂度的递归定义:
T ( n ) = { 1 n = 1 4 T ( n 2 ) + 1 n > 1 T(n) = \left\{\begin{matrix} 1 \qquad n=1\\ 4T(\frac{n}{2})+1 \qquad n>1 \end{matrix}\right. T(n)={1n=14T(2n)+1n>1
根据在主定理规则,我们先写出 n log ⁡ b a n^{\log_{b}{a} } nlogba f ( n ) f(n) f(n) n log ⁡ b a n^{\log_{b}{a} } nlogba = n log ⁡ 2 4 n^{\log_{2}{4} } nlog24 = n 2 n^{2} n2 f ( n ) = 1 f(n) = 1 f(n)=1 。很明显这里对于阶数的比较

n log ⁡ b a > f ( n ) n^{\log_{b}{a} } > f(n) nlogba>f(n),所以根据主定理规则, T ( n ) = O ( n log ⁡ b a ) T(n) = O(n^{\log_{b}{a} } ) T(n)=O(nlogba) ,即 T ( n ) = O ( n 2 ) T(n) = O(n^{2} ) T(n)=O(n2)

例二:

下面这个是一个时间复杂度的递归定义:
T ( n ) = { 1 n = 1 2 T ( n 2 ) + n n > 1 T(n) = \left\{\begin{matrix} 1 \qquad n=1\\ 2T(\frac{n}{2})+n \qquad n>1 \end{matrix}\right. T(n)={1n=12T(2n)+nn>1
根据在主定理规则,我们先写出 n log ⁡ b a n^{\log_{b}{a} } nlogba f ( n ) f(n) f(n) n log ⁡ b a n^{\log_{b}{a} } nlogba = n log ⁡ 2 2 n^{\log_{2}{2} } nlog22 = n n n f ( n ) = n f(n) =n f(n)=n 。很明显这里对于阶数的比较

n log ⁡ b a = f ( n ) n^{\log_{b}{a} } = f(n) nlogba=f(n),所以根据主定理规则, T ( n ) = O ( n log ⁡ b a log ⁡ n ) ) T(n) = O(n^{\log_{b}{a} } \log_{}{n} )) T(n)=O(nlogbalogn)) ,即 T ( n ) = O ( n log ⁡ n ) T(n) = O(n\log_{}{n} ) T(n)=O(nlogn)

例三:

下面这个是一个时间复杂度的递归定义:
T ( n ) = { 1 n = 1 4 T ( n 2 ) + n 3 n > 1 T(n) = \left\{\begin{matrix} 1 \qquad n=1\\ 4T(\frac{n}{2})+n^{3} \qquad n>1 \end{matrix}\right. T(n)={1n=14T(2n)+n3n>1
根据在主定理规则,我们先写出 n log ⁡ b a n^{\log_{b}{a} } nlogba f ( n ) f(n) f(n) n log ⁡ b a n^{\log_{b}{a} } nlogba = n log ⁡ 2 4 n^{\log_{2}{4} } nlog24 = n 2 n^{2} n2 f ( n ) = n 3 f(n) =n^{3} f(n)=n3 。很明显这里对于阶数的比较

n log ⁡ b a < f ( n ) n^{\log_{b}{a} } < f(n) nlogba<f(n),有 4 f ( n 2 ) ≤ c f ( n ) 4f(\frac{n}{2} )\le cf(n) 4f(2n)cf(n) ,是否存在c使得这个式子成立, 4 f ( n 2 ) = 4 ( n 2 ) 3 < c n 3 4f(\frac{n}{2} )=4(\frac{n}{2})^{3} < cn^{3} 4f(2n)=4(2n)3<cn3,很显然 1 2 < c < 1 \frac{1}{2} < c <1 21<c<1,这里的所以根据主定理规则, T ( n ) = O ( f ( n ) ) T(n) = O(f(n)) T(n)=O(f(n)),即
T ( n ) = O ( n 3 ) T(n) = O(n^{3} ) T(n)=O(n3)
这就是上面三种情况,我们也很容易的发现,在第三种规则的时候多了一个判定的条件,如果这个条件不满足那么就不能使用主定理这个方法了。看下面的一个例子:

下面这个是一个时间复杂度的递归定义:
T ( n ) = { 1 n = 1 2 T ( n 2 ) + n log ⁡ n n > 1 T(n) = \left\{\begin{matrix} 1 \qquad n=1\\ 2T(\frac{n}{2})+n\log_{}{n} \qquad n>1 \end{matrix}\right. T(n)={1n=12T(2n)+nlognn>1
根据主定理的规则,我们同样先写出他的 n log ⁡ b a n^{\log_{b}{a} } nlogba f ( n ) f(n) f(n) n log ⁡ b a n^{\log_{b}{a} } nlogba = n log ⁡ 2 2 n^{\log_{2}{2} } nlog22 = n n n f ( n ) = n log ⁡ n f(n) =n\log_{}{n} f(n)=nlogn ,显然 n log ⁡ b a < f ( n ) n^{\log_{b}{a} } < f(n) nlogba<f(n) 这就符合规则三,但是我们还要判断一下是否存在一个 ε \varepsilon ε 使得 f ( n ) = Ω ( n log ⁡ b a + ε ) f(n) = \Omega (n^{\log_{b}{a+\varepsilon } } ) f(n)=Ω(nlogba+ε) 成立,显然是不存在 ε \varepsilon ε的,所以该题目不适应主定理。

2.递归树

递归树的这种解法,其实跟递推的方法其实很相似,就是根据树的形式来确定时间的复杂度。我们之间来看个例子:

下面这个是一个时间复杂度的递归定义:
T ( n ) = { 1 n = 1 2 T ( n 2 ) + n n > 1 T(n) = \left\{\begin{matrix} 1 \qquad n=1\\ 2T(\frac{n}{2})+n \qquad n>1 \end{matrix}\right. T(n)={1n=12T(2n)+nn>1
我们可以很容易的画出他的递归树来,以他的f(n)为根,并以他的递归方程形式,分成孩子结点
在这里插入图片描述

我们通过观察这个递归树可以发现,每一层消耗的时间都是n,那么只要知道这课递归树的高度,我们就可以大致的判断出这个递归算法的时间复杂度,实际就是求出这颗树中结点的个数。很容易的可以看出来,这棵树是一颗满二叉树,那么他的高度应该为 log ⁡ 2 n \log_{2}{n} log2n,这就很容易判断出这个递归算法的时间复杂度为 O ( n log ⁡ n ) O(n \log_{}{n} ) O(nlogn)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

递归算法中的时间复杂度分析 的相关文章

随机推荐

  • 13 openEuler用户组管理

    文章目录 13 1 创建用户组 13 1 1 groupadd命令 13 1 2 用户组信息文件 13 1 3 创建用户组实例 13 2 修改用户组 13 2 1 修改GID 13 2 2 修改用户组名 13 3 删除用户组 13 4 将用
  • DSS部署-11、Spark on Yarn部署

    文章目录 第七部分 Spark on Yarn部署 相关配置 操作记录如下 spark sql e show databases 第七部分 Spark on Yarn部署 相关配置 tar xf spark 2 3 2 bin hadoop
  • 数学表达式: 从恐惧到单挑 (7. min 与 argmin)

    7 min 与 argmin min 和 argmin 在机器学习中常用 max 和 argmax 同理 7 1 min min 是 minimal 的缩写 用于获得集合中的最小值 如 min 3 1
  • 螺旋矩阵,python实现

    螺旋矩阵问题 给定一个n阶正方形矩阵 生成一个包含 1 到 n2 所有元素 且元素按顺时针顺序螺旋排列的正方形矩阵 力扣原题 这个问题不涉及什么算法问题 考察的就是个人对于代码的掌控和抽象 螺旋矩阵长的是这个样子 处理这个问题就得提到二分法
  • 各操作系统下安装docker

    1 查看服务器软硬件信息 1 1 判断操作系统类型 操作系统 基于发行版 统信UOS Debian 银河麒麟 StartOS Debian openEuler CentOS 优麒麟 Ubuntu Kylin Ubuntu 中标麒麟 Kyli
  • Java算法题:两数之和

    LeetCode原题 给你一个下标从 1 开始的整数数组 numbers 该数组已按 非递减顺序排列 请你从数组中找出满足相加之和等于目标数 target 的两个数 示例 1 输入 numbers 2 7 11 15 target 9 输出
  • STM32F103VG使用RTT实现发送DMX512调光数据

    DMX512调光协议和DALI一样属于数字调光协议 一个完整的DMX512数据包格式 1break 1mab 1startcode 512个调光数据 DMX512发送是基于485串口的基础上实现的特殊的数据协议 使用RTT需要把串口打开并且
  • 大话数据结构:线性表(顺序存储结构)

    线性表 零个或多个数据元素的有限序列 直接前驱元素 直接后继元素 线性表的长度 线性表元素的个数n 线性表的抽象数据类型 ADT线性表 list Data 线性表的数据对象集合为 a1 a2 an 每个元素的类型均为Datatype 其中
  • 微软服务器的主要功能,数据库服务器主要功能

    数据库服务器主要功能 内容精选 换一换 HANA全称High performanceAnalyticAppliance是由SAP开发的基于内存的面向行 列存储的关系型数据库管理系统 其作为数据库服务器的主要功能是根据应用程序的要求存储和检索
  • jdk17下载

    官网下载 https download oracle com java 17 latest jdk 17 windows x64 bin zip
  • 也想做一个绝地求生版的汽车控制移动,进来瞧瞧?(干货满满)

    控制车子移动 效果图附上 1 首先4个车轮复制一遍为车轮2备用 2 给车轮2全部添加wheel collider 只剩下车轮碰撞器和transform组件 3 给原版4个车轮添加脚本wheel 变量共有 面板赋值 依次添加车轮2里面的车轮c
  • c#图解教程和c#高级编程电子书链接

    链接 https pan baidu com s 1y TM08JvyBh8kQ0v7uT5hg 提取码 b0cq
  • Python的多维空数组赋值

    Python里面的list tuple默认都是一维的 创建二维数组或者多维数组也是比较简单 可以这样 list1 1 2 list1 append 3 4 可以这样 list2 1 2 3 4 还可以这样 list3 1 2 list3 i
  • android界面监控,防劫持

    1 首先要对自己应用的activity建立一个白名单 2 权限
  • http协议从客户端提交数据给服务器并返回数据

    老罗视频学习 本例从客户端提交数据给服务器 服务器接收到数据之后 看是否匹配 匹配返回字符串 login is success 失败返回 login is error 一 客户端 初始化url地址 private static String
  • Git如何比较不同分支的差异

    前两天 良许在做集成的时候碰到了一件闹心事 事情是这样的 良许的一位同事不小心把一个错误的 dev 分支 merge 到了 master 分支上 导致了良许编译不通过 于是 我们需要将版本回退到 merge 之前的状态 如果是下面这个状态
  • 电子设计竞赛(三)-SPWM与PID

    1 SPWM波调制技术 逆变电路的控制方式主要是采用SPWM 正弦脉宽调制技术 IR2104控制开关管的通断来实现正弦调制 SPWM的基本思路是将一个正弦波按等宽间距分成N等份 对于每一个波形以一个等面积的脉冲来对应 使脉冲的中点与相应正弦
  • python3 hashlib库sha256、pbkdf2_hmac、blake2b基本用法

    hashlib sha256 import hashlib x hashlib sha256 x update b asd print x 1 x hexdigest x hashlib sha256 x update asd encode
  • 数据下载网站整理

    数据十分重要 如何找到理想的数据显得更重要了 这里记录自己经过网上查询到的数据 进行整理 如果侵权 请联系我删除 再次感谢网友大佬们提供的资料 1 中国气象站点数据 下载地址 https www resdc cn data aspx DAT
  • 递归算法中的时间复杂度分析

    对于一种算法的时间复杂度分析还是特别重要的 在一些非递归算法中 我们仅仅看运算次数最多的那一行代码可能执行多少次就可以 实际就是看在循环中变量的变化 但是对于递归算法中该怎么分析呢 下面介绍几种递归函数中的算法时间复杂度分析的方法 0 递推