原文地址:https://rob-bell.net/2009/06/a-beginners-guide-to-big-o-notation/ 
计算机科学中,大O表示法被用来描述一个算法的性能或复杂度。大O表示法可以用来描述一个算法的最差情况,或者一个算法执行的耗时或占用空间(例如内存或磁盘占用)。 
相信许多人读过《Programming Pearls》(《编程珠玑》)或者其他计算机科学书籍时,在看到大O符号或者其他奇怪的语法符号时都会感觉到自己遇到了一堵无法翻越的高墙。那这篇文章将会带领大家对大O表示法以及对数级算法有一个最简单的认识。 
首先作为一个程序员,其次作为一个数学家,我(Rob Bell)发现透彻的理解大O表示法的最好方式就是来尝试一些代码示例。下面按照算法的增长级别,展示了一些常见的算法描述,同时针对每个算法给出了一个简单的示例。

O(1)

O(1)表示该算法的执行时间(或执行时占用空间)总是为一个常量,不论输入的数据集是大是小。

bool IsFirstElementNull(IList<string> elements)
{
return elements[0] == null;
}

O(N)

O(N)表示一个算法的性能会随着输入数据的大小变化而线性变化。下面的例子同时也表明了大O表示法其实是用来描述一个算法的最差情况的:在for循环中,一旦程序找到了输入数据中与第二个传入的string匹配时,程序就会提前退出,然而大O表示法却总是假定程序会运行到最差情况(在这个例子中,意味着大O会表示程序全部循环完成时的性能)。

bool ContainsValue(IList<string> elements, string value)
{
foreach (var element in elements)
{
if (element == value) return true;
} return false;
}

O(N^2)

O(N^2)表示一个算法的性能将会随着输入数据的增长而呈现出二次增长。最常见的算法就是对输入数据进行嵌套循环。如果嵌套层级不断深入的话,算法的性能将会变为O(N3),O(N4),以此类推。

bool ContainsDuplicates(IList<string> elements)
{
for (var outer = 0; outer < elements.Count; outer++)
{
for (var inner = 0; inner < elements.Count; inner++)
{
// Don't compare with self
if (outer == inner) continue; if (elements[outer] == elements[inner]) return true;
}
} return false;
}

O(2^N)

O(2^N)表示一个算法的性能将会随着输入数据的每次增加而增大两倍。O(2^N)的增长曲线是一条爆炸式增长曲线——开始时较为平滑,但数据增长后曲线增长非常陡峭。一个典型的O(2^N)方法就是裴波那契数列的递归计算实现。

int Fibonacci(int number)
{
if (number <= 1) return number; return Fibonacci(number - 2) + Fibonacci(number - 1);
}

对数

要说明对数情况,稍稍有点复杂,因此我将使用一个非常通用的示例: 
二分查找是一种用来在有序集合中进行查找的高效算法。二分查找从数据集的中间位置开始,然后用这个中间值和一个目标值进行比较。如果比较结果为相等,则程序返回成功。如果目标值大于中间值,程序会截取从中间值开始到最大值的那段数据集,并重复执行同样的查找方法。想死的,如果目标值小于中间值,程序将会继续在数据集中较小的那一半执行二分查找。二分查找程序会持续的将数据集对等分,以进入下一次循环,直到最终找到与目标值相等的数据后,程序就退出。 
这类算法的性能就会被描述为O(logN)。正是通过这种不断对数据进行对等分的二分查找操作,使得二分查找算法的曲线从一个峰值开始,随着输入数据集的增长而慢慢的变得平缓。用例子来说明的话,例如一个包含10个输入数据的程序需要耗时一秒完成,则一个包含100个输入数据的程序就需要耗时两秒,然后一个包含1000个输入数据的程序就耗时三秒。加倍的输入数据对这类算法的性能结果影响非常小。基于如此,类似于二分查找的对数级算法在处理大量数据集时非常高效。 
本文仅仅覆盖了关于大O表示法以及对数算法非常基本的知识概念。如果想要更深入的理解他们,可以参考维基百科: 
大O表示法:https://en.wikipedia.org/wiki/Big_O_notation 
对数:https://en.wikipedia.org/wiki/Logarithm

大O符号初学者指南的更多相关文章

  1. Java多线程初学者指南系列教程

    转自:http://developer.51cto.com/art/200911/162925.htm 51cto 本系列来自NokiaGuy的“真的有外星人吗”博客,系列名称为<Java多线程 ...

  2. 简明解释算法中的大O符号

    伯乐在线导读:2009年1月28日Arec Barrwin在StackOverflow上提问,“有没有关于大O符号(Big O notation)的简单解释?尽量别用那么正式的定义,用尽可能简单的数学 ...

  3. 你了解大O符号(big-O notation)么?你能给出不同数据结构的例子么?

    大O符号表示当数据结构的元素增加的时候,算法规模或者性能在最坏场景下有多好. 大O符号也可以用来描述其他行为,比如说内存消耗.因为集合实际上就是一种数据结构,我们一般用大O符号基于时间.性能.内存消耗 ...

  4. NHibernate初学者指南系列文章导航

    NHibernate初学者指南系列文章导航   前面的话 经过三个多周的时间,终于将这个系列完成了,谢谢大家的关注和支持,有很多不足之处还望大家包涵. 本系列参考的书籍为NHibernate 3 Be ...

  5. MathType如何编辑大三角形符号

    MathType中包含的符号超过1000多个,可以满足我们很多学科的使用,尤其是数学中,涉及到很多的符号,常见的就是代数.几何这两大类,当然还有集合之类的符号使用也比较多.我们在用MathType编辑 ...

  6. 【算法日记】2.算法中的大O符号

    大O符号是一种算法复杂度的相对表示方式. 1.大O表示算法的操作数,表示出算法运行的快慢 2.大O表示法指出了最糟糕情况下的运行时间,例如 简单查找的运行时间O(n),意味着在最糟糕的情况下,必须运行 ...

  7. 【系列】Java多线程初学者指南(1):线程简介

    原文地址:http://www.blogjava.net/nokiaguy/archive/2009/nokiaguy/archive/2009/03/archive/2009/03/19/26075 ...

  8. 【翻译】nginx初学者指南

    nginx初学者指南 本文翻译自nginx官方网站:http://nginx.org/en/docs/beginners_guide.html#control 该指南会对nginx做一个简要的介绍,同 ...

  9. FreeBSD上编写x86 Shellcode初学者指南

    FreeBSD上编写x86 Shellcode初学者指南 来源 https://www.4hou.com/binary/14375.html 介绍 本教程的目的是帮助你熟悉如何在FreeBSD操作系统 ...

随机推荐

  1. 数据库SQL语言从入门到精通--Part 1--SQL语言概述

    数据库从入门到精通合集(超详细,学习数据库必看) 一.SQL概述 关系数据库标准语言SQL(结构化查询语言). 结构化查询语言(Structured Query Language)简称SQL,是一种特 ...

  2. 手写实现java栈结构,并实现简易的计算器(基于后缀算法)

    一.定义 栈是一种线性表结构,栈结构中有两端,对栈的操作都是对栈的一端进行操作的,那么被操作的一端称为栈顶,另一端则为栈底.对栈的操作其实就是只有两种,分别是入栈(也称为压栈)和出栈(也称为弹栈).入 ...

  3. 【MIT6.828】centos7下使用Qemu搭建xv6运行环境

    title:[MIT6.828]centos7下使用Qemu搭建xv6运行环境 date: "2020-05-05" [MIT6.828]centos7下搭建xv6运行环境 1. ...

  4. C语言程序设计实验报告四

    C程序设计实验报告 姓 名:赖瑾 实验地点:家 实验时间:2020年4月9日 实验项目:5.3.1练习2 求数列的前n项和 5.3.2练习2 求水仙花数 5.3.4 十进制转换 5.3.5练习1 百马 ...

  5. js和jq的获取焦点失去焦点写法

  6. Java设计模式之建造者模式(Builder Pattern)

    前言 这篇文章主要向大家讲解什么是建造者模式,建造者模式的实例讲解及应用场景等知识点. 一.建造者介绍 ​ 用户可以不知道产品的构建细节直接可以创建复杂的对象,主要是分离了产品的构建和装配,这样就实现 ...

  7. EOS基础全家桶(十一)智能合约IDE-EOS_Studio

    简介 我们马上要进入智能合约的开发了,以太坊最初提供了智能合约的功能,并宣告区块链进入2.0时代,而EOS的智能合约更进一步,提供了更多的便利性和可能性.为了进一步了解智能合约,并进行开发,我们需要先 ...

  8. 08JAVA基础关键字(final、static)以及抽象类和接口

    一.关键字 1.final 修饰类 修饰变量 修饰成员方法 该类为最终类,不能被继承 该变量为常量 该成员方法不能被重写 2.static (1).生命周期 随着类的加载而加载 (2).特点 被本类所 ...

  9. Redis 6.0 多线程重磅发布!!!

    Redis 6.0在5.2号这个美好的日子里悄无声息的发布了,这次发布在IT圈犹如一颗惊雷一般,因为这是redis最大的一次改版,首次加入了多线程. 作者Antirez在RC1版本发布时在他的博客写下 ...

  10. QQ恢复解散后的群聊或删除后的好友的方法

    今天有一个群被一个管理员乱踢人,之后将群解散. 事后几分钟我在想有没有什么方法可以重新恢复的方法,之后进入了QQ的官网进行查找. 本来以为没希望了,但是奇迹发生了. 原来真的可以恢复! 恢复的详情: ...