作为程序员,我们经常努力编写尽可能高效的代码。但是我们怎么知道我们编写的代码是否高效?答案:大O分析。本文的目的是用尽可能简单的术语来解释这个概念。我将首先介绍BigO,然后举例说明您可能会遇到的七个最常见的情况。如果您已经熟悉这个概念,但是想要使用真实的Python代码进行具体的复习,请随时跳到第二部分!
1.算法—一组逻辑步骤,作用于输入以产生输出。
在本文中,我将算法与更熟悉的概念联系:函数。回想一下你编写的大多数函数的功能,它们将一个或多个参数作为输入,对这些参数执行指定的操作步骤,然后返回一个值作为输出。不要害怕这个花哨的词,您可能已经写了很多算法!从现在开始,当我说「算法」时,你可以直接把它理解为「函数」。
3.输入规模—算法需要处理的数据量。
既然我们已经了解大O表示法的作用了,那么它究竟怎么写呢?好吧,它的写法是大写的「O」,后面跟着一个括号,括号里面是一个包含「n」(即输入规模)的数学表达式。下文中有最常见的七个示例,按照运行效率从高到低排序。
现在,让我们看一下上述每种复杂度的算法对应的一些常见例子。
fromtypingimportAny,Listdeflinear_search(list_:List[Any],target_value:Any)->int:"""对输入列表执行线性搜索以找到目标值。返回列表中目标值的索引,如果未找到则返回-1。"""#遍历列表中的每一项,检查其是否为目标值forindex,iteminenumerate(list_):ifitem==target_value:returnindex#如果在列表中未找到目标值,则返回一个标记值return-1显然,随着输入列表大小的增加,由于需要检查列表中的每个项目,最坏情况下找到目标所需的循环迭代次数的增长与输入列表的大小增长成正比。
列举对数线性复杂度算法的示例会比之前难一些。顾名思义,它们同时包含对数和线性部分。其中最常见的示例是排序算法。有一个算法叫「归并排序」,它用迭代手法将数组分成一小块一小块,对每小块进行拆分、排序,然后再按顺序重新将各个小块合并在一起。通过图像可以更容易看明白,因此我将省略代码的实现。