算法复杂度的今生今世

导读:本篇文章讲解 算法复杂度的今生今世,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

1. 算法复杂度的今生今世

1.1 什么是算法

算法是一个抽象的概念。可以理解为:一组输入数据经过正确、确定、可行的有限步运算后得到的输出结果,中间的正确、确定、可行的有限步运算就是我们所说的算法。
在这里插入图片描述
需要注意的是,正确性、确定性、可行性和有穷性由数学问题的性质决定的,而不是程序的特点。举一个例子,hailstone序列:
在这里插入图片描述
根据定义,你可能直接写出程序:
在这里插入图片描述
但是,这样你从源头上就错了,先不考虑程序,针对于这个问题,你能确保给定任意一个数,其序列的长度是有限的?也就是是否对于任意n,都有 |Hailstone(n)| < ∞,然而,这个问题到现在都还被解决,是一个不确定问题,不符合有穷性,所以其不是一个算法。自然的,对于上面的程序也不是一个算法程序。
所以,平时在写算法程序时遇到死循环或者栈溢出时,可能不是程序的问题,可能是该问题本质上就不能用一个算法解决。

结论:

  1. 算法的正确性、确定性、可行性和有穷性是数学问题的性质决定的,而不是程序决定的。即 程序 != 算法

但是,由于我们平时关注更多的是程序方面的算法实现,所以,后续说算法指算法程序。

1.2 如何衡量算法的好坏

衡量算法好坏:先满足时间复杂度最低,再去考虑空间复杂度最低。

但是,需要注意:算法的最优解并不意味着实际情况的最优解。 比如:

  1. 当计量非常大时,应该将时间复杂度最优,将空间复杂度降低,以空间换时间。
  2. 当计量不是很大时,应该找 时间复杂度 与 空间复杂度的平衡。尽可能双双压低。
  3. 如果空间不充足的情况下,可以考虑时间换空间。

例子:
在这里插入图片描述

1.2.1 时间复杂度

  1. 时间复杂度的3个标记:
    1. O( ):用来定义最坏的趋势。求解步骤:
      1. 得到计算公式后求极限
      2. 忽略常数和系数
    2. Ω( ):用来定义最好的趋势。求解步骤:
      1. 得到计算公式后求极限
      2. 忽略常数和系数
    3. θ( ):用来定义平均的趋势。求解步骤: θ取夹在 Ω 与 O 中间的数。比如:Ω(1) < θ < O(n),则有θ(n^0.5) 或 θ(n^0.3) 等等

    注意:通常使用O来衡量算法的复杂度,而不是θ

  2. ① 当两个算法的O不相等时,O小的效率更高。
    ② 当两个算法的O相等时,理论上需要看基本操作的常数时间,常数时间小的效率高。但是,在实际开发中可以将两个算法分别其运行很多次,并直接比较运行时间。

1.2.2 空间复杂度

空间复杂度:指实现一个功能的所需要的额外空间。额外空间指除 输入参数的空间 和 返回值的空间 以外还需要的空间。

比如,实现对数组的复制,空间复杂度为:O(1)。
在这里插入图片描述

1.3 增长速度

1.3.1 O(1)

在这里插入图片描述

结论:含循环或者分支或递归也可能为O(1)

1.3.2 O(logn)

在这里插入图片描述

1.3.3 O(n)

1.3.4 O(n * log n)

1.3.5 O(n^c) 其中:c>2

在这里插入图片描述

1.3.6 O(c^n) 其中:c>2

在这里插入图片描述

1.3.7 O(n!)

1.4 算法分析

在这里插入图片描述

1.4.1 级数

在这里插入图片描述

1.4.2 循环

在这里插入图片描述
在这里插入图片描述

1.4.3 正确性的验证

正确性由不变性和单调性确定,所有的算法都可以用这种方式来衡量算法的正确性。
在这里插入图片描述

1.5 几个常用算法分析

1.5.1 迭代

在这里插入图片描述

1.5.2 减而治之

在这里插入图片描述

注意:减而治之的时间复杂度是递归调用次数 * 函数的复杂度(忽略递归式子)

1.5.3 分而治之

在这里插入图片描述

结论:分而治之的复杂度 = 最后一层实例的个数 * 函数的复杂度(忽略递归式)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/84631.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!