算法复杂度分析(下):最好、最坏、平均、均摊等时间复杂度概述
细化时间复杂度分析
代码千千万,有些代码逻辑会很复杂,所以为了更细化的分析算法的复杂度,再复杂度分析方面引入了4个知识点:
1.最好情况时间复杂度(best case time complexity)。
2.最坏情况时间复杂度(worst case time complexity)。
3.平均情况时间复杂度(average case time complexity)。
4.均摊时间复杂度(amortized time complexity)。
复杂度分析
示例如下(限定条件:0<n且0<x且n和x为整数):
1 public int Function(int n, int x) 2 { 3 int sum = 0; 4 for (int i = 1; i <= n; ++i) 5 { 6 if (i == x) 7 break; 8 sum += i; 9 } 10 return sum; 11 } 12 /* 13 * 作者:Jonins 14 * 出处:http://www.cnblogs.com/jonins/ 15 */
这段代码逻辑非常简单,再此不描述。需要重点分析的是循环这一段代码,这段代码根据x值的不同,时间复杂度也有区别:
1.当x>n时,此代码的时间复杂度是O(n)。
2.当1<=x<=n时,时间复杂度是一个我们不确定的值,取决于x的值。
3.当x=1时,时间复杂度是O(1)。
这段代码在不同情况下,其时间复杂度是不一样的。所以为了描述代码在不同情况下的不同时间复杂度,我们引入了最好、最坏、平均时间复杂度。
最好情况时间复杂度
最好情况时间复杂度,表示在最理想的情况下,执行这段代码的时间复杂度。
上述示例就是当x=1的时候,循环的第一个判断就跳出,这个时候对应的时间复杂度就是最好情况时间复杂度。
最坏情况时间复杂度
最坏情况时间复杂度,表示在最糟糕的情况下,执行这段代码的时间复杂度。
上述示例就是n<x的时候,我们要把整个循环执行一遍,这个时候对应的时间复杂度就是最坏情况时间复杂度。
平均情况时间复杂度
最好和最好情况是极端情况,发生的概率并不大。为了更有效的表示平均情况下的时间复杂度,引入另一个概念:平均情况时间复杂度。
分析上面的示例代码,判断x在循环中出现的位置,有n+1种情况:1<=x<=n 和n<x。
我们将所有情况下代码执行的次数累加起来((1+2+3....+n)+n),然后再除以所有情况数量(n+1),就可以得到需要遍历次数的平均值。
平均情况复杂度为:
$ \frac{((1+2+3...+n)+n)}{(n+1)}=\frac{n(n+3)}{2(n+1)} $
推导过程:
$ \because 1+2+3...+n=n+(n-1)+(n-2)...+1 $
$ \therefore (1+2+3...+n)=\frac{n(1+n)}{2} $
$ \therefore (1+2+3...+n)+n= \frac{n(3+n)}{2} $
大O表示法,会省略系数、低阶、常量,所以平均情况时间复杂度是O(n)。
但是这个平均复杂度没有考虑各自情况的发生概率,这里的n+1个情况,它们的发生概率是不一样的,所以还需要引入各自情况发生的概率再具体分析。
x要么在1~n中,要么不在1~n中,所以它们的概率都是$\frac{1}{2}$。
同时数据在1~n中各个位置的概率都是一样的为$\frac{1}{n}$。根据概率乘法法则,x在1~n中任意位置的概率是$\frac{1}{2n}$。
因此在前面推导过程的基础上,我们把每种情况发生的概率考虑进去,那么平均情况时间复杂度的计算过程变成:
考虑概率的平均情况复杂度为:
$(1\frac{1}{2n}+2\frac{1}{2n}+3\frac{1}{2n}...+n\frac{1}{2n})+n\frac{1}{2}=\frac{3n+1}{4}$
推导过程:
$\because (1+2+3...+n)=\frac{n(1+n)}{2}$
$\therefore (1\frac{1}{2n}+2\frac{1}{2n}+3\frac{1}{2n}...+n\frac{1}{2n})=\frac{1}{2n}(1+2+3...+n)=\frac{1}{2n}*\frac{n(1+n)}{2} =\frac{1+n}{4}$
$\therefore (1\frac{1}{2n}+2\frac{1}{2n}+3\frac{1}{2n}...+n\frac{1}{2n})+n\frac{1}{2}=\frac{1+n}{4} +n\frac{1}{2}=\frac{3n+1}{4}$
这就是概率论中的加权平均值,也叫做期望值,所以平均时间复杂度全称叫:加权平均时间复杂度或者期望时间复杂度。
引入概率之后,平均复杂度变为O($\frac{3n+1}{4}$),忽略系数及常量后,最终得到加权平均时间复杂度为O(n)。
注意:
多数情况下,我们不需要区分最好、最坏、平均情况时间复杂度。只有同一块代码在不同情况下时间复杂度有量级差距,我们才会区分3种情况,为的是更有效的描述代码的时间复杂度。
均摊情况时间复杂度
均摊复杂度是一个更加高级的概念,它是一种特殊的情况,应用的场景也更加特殊和有限。
对应的分析方式称为:摊还分析或平摊分析。
示例如下(限定条件:0<=x<=n且0<=n且n,x为整数):
1 int n; 2 int Function2(int x) 3 { 4 int count = 0; 5 if (n == x) 6 { 7 for (int i = 0; i < n; i++) 8 { 9 count += i; 10 } 11 } 12 else 13 count = x; 14 return count; 15 } 16 /* 作者:Jonins 17 * 出处:http://www.cnblogs.com/jonins/ 18 */
分析上述案例的时间复杂度:
最理想情况下x!=n,只执行一次赋值即可推出,所以最好时间复杂度为O(1)。
最坏的情况下x=n,要执行一次循环累加和的操作,所以最好时间复杂度为O(n)。
平均的情况下,因为限定条件0<=x<=n,x在0~n中存在的位置可以分为n+1种情况(0到n)。
当0<=x<n时,时间复杂度为O(1)。但是x=n的时候是一个例外,它的复杂度是O(n)。
而且这n+1种情况发生的概率都是一样的,为$\frac{1}{n+1}$。所以根据加权平均的计算方法,
平均时间复杂度为:
$ (1\tfrac{1}{n+1}+1\tfrac{1}{n+1}+1\tfrac{1}{n+1}+...+1\tfrac{1}{n+1})+n\tfrac{1}{n+1} = \tfrac{2n}{n+1} $
推导过程:
$(1\tfrac{1}{n+1}+1\tfrac{1}{n+1}+1\tfrac{1}{n+1}+...+1\tfrac{1}{n+1})+n\tfrac{1}{n+1}$
$=n\tfrac{1}{n+1}+n\tfrac{1}{n+1}$
$=\tfrac{2n}{n+1}$
当省略系数及常量后,平均时间复杂度为O(1)。
摊还分析法
分析上述示例的平均复杂度分析并不需要如此复杂,无需引入概率论的知识。
因为通过分析可以看出,上述示例代码复杂度大多数为O(1),极端情况下复杂度才较高为O(n)。同时复杂度遵循一定的规律,一般为1个O(n),和n个O(1)。针对这样一种特殊场景使用更简单的分析方法:摊还分析法。
通过摊还分析法得到的时间复杂度为均摊时间复杂度。
大致思路:每一次O(n)都会跟着n次O(1),所以把耗时多的复杂度均摊到耗时低的复杂度。得到的均摊时间复杂度为O(1)。
应用场景:均摊时间复杂度和摊还分析应用场景较为特殊,对一个数据进行连续操作,大部分情况下时间复杂度都很低,只有个别情况下时间复杂度较高。而这组操作其存在前后连贯的时序关系。
这个时候我们将这一组操作放在一起分析,将高复杂度均摊到其余低复杂度上,所以一般均摊时间复杂度就等于最好情况时间复杂度。
注意:均摊时间复杂度是一种特殊的平均复杂度(特殊应用场景下使用),掌握分析方式即可。
转载于:https://www.cnblogs.com/jonins/p/9956752.html
算法复杂度分析(下):最好、最坏、平均、均摊等时间复杂度概述相关推荐
- 怎么算matlab算法复杂度,算法复杂度分析
1. 何为数据结构?何为算法? 简单来说,数据结构就是数据的存储方式,比如数组就是把数据存在一段连续的内存上,而链表则是通过指针的关联将数据存在任意可用的内存上:栈是先进后出,队列是先进先出. 而算法 ...
- 八大排序:Java实现八大排序及算法复杂度分析
目录 QUESTION:八大排序:Java实现八大排序及算法复杂度分析 ANSWER: 一:冒泡排序 1.算法分析 2.时间复杂度分析 3.代码 二:选择排序 1.算法分析 2.时间复杂度分析 3.代 ...
- 第3课:算法复杂度分析(下):最好、最坏、平均、均摊时间复杂度
目录 最好.最坏时间复杂度 平均情况时间复杂度 均摊时间复杂度 小结 最好.最坏时间复杂度 我们先看一个例子: /*例1:查找x在数组中出现的位置,如果没有找到,返回-1.n表示数组array的长度 ...
- 算法复杂度分析(下)
前一篇文章算法复杂度分析(上)讲述了复杂度的大 O 表示法和几个分析原则,这篇文章我们来讲讲另外几种复杂度,最好情况时间复杂度(best case time complexity).最坏情况时间复杂度 ...
- 算法之如何进行算法复杂度分析
一.什么是复杂度分析? 1.数据结构和算法解决是"如何让计算机更快时间.更省空间的解决问题". 2.因此需从执行时间和占用空间两个维度来评估数据结构和算法的性能. 3.分别用时间复 ...
- 网络流问题以及EK算法复杂度分析
网络流问题以及EK算法复杂度分析 一.网络流算法 通过一个例子引入网络流问题. 现有一个自来水厂要往家里通水,自来水厂用Vs表示,家用Vt表示.从自来水厂到家之间连接了很多水管,并且中途经过很多转接点 ...
- 算法复杂度分析看这一篇就够了
执行效率是算法一个非常重要的考量指标,而时间复杂度和空间复杂度则是衡量算法代码的执行效率. 为什么需要复杂度分析 通常情况下,我们可以在写完代码的情况下把程序跑一遍,通过统计.监控,就能得出算法执行的 ...
- 算法复杂度((平均,最好,最坏,均摊)时间复杂度,空间复杂度)
文章目录 前言 时间&空间复杂度 时间复杂度 1.最好情况时间复杂度(best case time complexity) 2.最坏情况时间复杂度(worst case time comple ...
- 【排序综合】直接插入排序,希尔排序,快速排序,堆排序,冒泡排序,简单选择排序的简介,实现和算法复杂度分析
目录 1. 直接插入排序 1.1 直接插入排序简介 1. 什么是直接插入排序 2. 排序思想 1.2 排序实现 1. 排序代码 2. 复杂度分析: 3. 运行结果: 1.3 学习链接 2. 希尔排序( ...
最新文章
- “Attention is All You Need 翻译
- python ascii函数二进制_python模块介绍- binascii:二进制和ASCII互转以及其他进制转换...
- 这些行业,将率先落地AI芯片 | 星前沿
- 简易记事本实现与分析(三)主界面
- 中石油训练赛 - Historical Maths(二分)
- 我认真写下9段如翔一般的代码,只为等你来品鉴
- Spring Data对Cassandra 3的支持
- 方法 手写promise_JS探索-手写Promise
- 链接生成动态二维码图片显示在页面上
- 《java入门第一季》之类面试题
- jmeter 控制偏离_Jmeter 笔记(1)-安装 基本组件
- 手机上最好用的五笔输入法_最欠揍的手机输入法,用不好失业又失恋
- XPDL与WS-BPEL的比较之一:规范发展篇
- Java基础 | 多态
- Dos界面telnet命令的基本使用
- 计算机网络中的猫,宽带猫的作用和分类【图解】
- (7)centos7 同步服务器时间
- HashMap线程安全问题详细解析
- MyCat分库分表和读写分离
- 3DMax高级建模人物骨骼蒙皮!零基础快速入门!不要错过!
热门文章
- 普通话/汉语发音口型大全
- Linux 系统服务管理器(初始化系统/init system) -- systemd 及命令 systemctl 的详细介绍
- 查询英文缩写形式(缩写词)的网站工具梳理
- 【安卓开发 】Android初级开发(五)自定义View
- c 中头文件和源文件的区别是什么
- C 常见的面试知识点(下)
- python xlrd读取文件报错_python中xlrd库如何实现文件读取?
- .net mvc actionresult 返回字符串_ASP.NET Core中的Action的返回值类型
- matlab int 积不出,matlab – 点积:*命令与循环给出不同的结果
- flowable画图教程_JeeGit企业级快速开发平台-JeeSite4 Flowable入门教程