常见排序算法导读(2)[算法与算法复杂度]

1. 什么是算法(Algorithm)?

顾名思义,算法就是计算的办法或者法则。这里的计算是广义的可以做任何事情的计算,而办法和法则意味着使用它就可以解决需要的问题。 通常人们将算法定义为一个有穷的指令集,这些指令为解决某一个特定任务规定了一个运算序列。一个算法应当具有下面的5个特性:

  1. 输入(Input):一个算法必须有零个或多个输入。
  2. 输出(Output):一个算法应有一个或多个输出,输出的量是算法计算的结果。
  3. 确定性(Definiteness):算法的每一步都应该确切地、无歧义地定义。对于每一种情况,需要执行的动作都应严格地、清晰地定义。
  4. 有穷性(Finiteness):一个算法无论在什么情况下都必须在有限个步骤内完成任务。
  5. 有效性(Effectiveness):又称可行性。算法必须能够实现,算法中描述的操作都是可以通过已经实现的基本运算执行有限次来实现。

事实上,算法的定义可以有多种,从不同的角度看,获得的定义则不同。例如:

  1. 哲学角度看:算法是解决一个问题的抽象行为序列。
  2. 技术层面看:算法是一个计算过程,它接受一些输入,并产生某些输出。
  3. 抽象层面看:算法是一个将输入转化为输出的计算步骤序列。
  4. 宏观层面看:算法是解决一个精确定义的计算问题的工具。

参考资料: 1. 维基百科对算法的解释; 2. Book : 算法之道 (邹恒明著, 机械工业出版社)

2. 评价算法优劣的标准

评价一个算法是好还是坏,主要有以下5个标准:

  1. 正确性(Correctness): 算法能够正确地执行预先规定的功能和性能要求。
  2. 可用性(Usability): 算法能够很方便地为用户所使用,比如具有良好的用户界面,完备的用户文档。
  3. 可读性(Readability): 算法应当是可读的,这是出于理解、测试和修改算法的需要。因此,算法的逻辑必须是清晰的、简单的和结构化的。
  4. 效率(Performance): 算法的效率主要指算法执行时对计算机资源的消耗,包括存储和运行时间的开销,前者叫做算法的空间代价,后者叫做算法的时间代价。 算法的效率又叫做算法的复杂度
  5. 健壮性(Robustness): 算法具有容错能力,能对异常进行处理。

以上5个标准中,算法的效率(即算法的复杂度)是评价算法优劣最重要的标准

3. 设计算法时必须考虑的因素

  1. 必须正确
  2. 步骤尽可能少
  3. 实现尽可能简单
  4. 空间占用尽可能少

其中, 2.与算法的时间复杂度密切相关,4.则与算法的空间复杂度密切相关。 下面将重点介绍什么是算法的时间复杂度和空间复杂度。

4. 算法的复杂度

算法的复杂度包括时间复杂度和空间复杂度。

4.1 时间复杂度(Time Complexity)

算法的时间复杂度是指算法需要消耗的时间资源。 一般情况下,算法中基本操作重复执行的次数是问题规模n的某个函数f(n), 算法的时间量度记作:

T(n) = O(f(n))

它表示随着问题规模n的增大,算法执行时间的增长率和f(n)的增长率相同,称做渐进时间复杂度(Asymptotic Time Complexity),简称时间复杂度

例如: 下面的代码片段的时间复杂度T(n) = O(n**2)

1 int sum = 0;
2 for (int i = 0; i < n; i++) {
3         for (int j = 0; j < n; j++) {
4                 sum += a[i][j];
5         }
6 }

4.2 空间复杂度(Space Complexity)

算法的空间复杂度是指算法需要消耗的空间资源。 与时间复杂度类似,算法在运行过程中占用的临时存储空间的大小是问题规模n的某个函数f(n), 记作:

S(n) = O(f(n))

它表示随着问题规模n的增大,算法执行存储空间消耗的增长率和f(n)的增长率相同,称做渐进空间复杂度(Asymptotic Space Complexity),简称空间复杂度

例如:一般的递归算法的空间复杂度为O(n), 因为每次递归都要存储返回的信息。

1 unsigned long long
2 factorial(unsigned int n)
3 {
4         if (n == 0)
5                 return 1;
6         else
7                 return n * factorial(n-1);      
8 }

另外,相对于时间复杂度分析来说,空间复杂度分析要容易得多。

5.  算法的复杂度分类

按照数量级递增的顺序,常见的算法复杂度有:常数级别O(1), 对数级别O(logN), 线性级别O(n), 线性对数级别O(N*logN), 平方级别O(n**2), 立方级别O(n**3), …, 指数级别O(2**N)。

o 参考资料:《Algorithms》 (Fourth Edition, By Robert Sedgewick & Kevin Wayne) 1.4 ANALYSIS OF ALGORITHMS

《常见排序算法导读(2)[算法与算法复杂度]》

扩展阅读: 对数 (注意:在算法复杂度讨论中,logN本质上是log2N而不是log10N,虽然数学里定义的是对数的底默认为10)

下面的截图来自《算法图解》一书。

《常见排序算法导读(2)[算法与算法复杂度]》

到此为止,我们已经弄明白了什么是算法,以及什么是算法的时间复杂度和空间复杂度。下一节,将介绍简单选择排序。

    原文作者:veli
    原文地址: https://www.cnblogs.com/idorax/p/6530127.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞