• 大O表示法总结


    大O符号用于计算机科学来描述算法的性能或复杂性。Big O特别描述了最坏的情况,可以用算法来描述所需的执行时间或使用的空间(例如在内存或磁盘上)。

    任何读过Programming Pearls(编程珠玑)或任何其他计算机科学书籍并且没有数学基础的人,当他们到达提及O(N log N)或其他看似疯狂的语法的章节时,都会遇到困难。希望这篇文章能够帮助你理解Big O和Logarithms的基本知识。

    作为程序员第一和数学家第二(或者第三或第四),我发现理解Big 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://rob-bell.net/2009/06/a-beginners-guide-to-big-o-notation/

  • 相关阅读:
    linux uniq 命令实用手册
    linux sort 命令实用手册
    linux awk 命令实用手册
    如何高效使用vim
    15个有趣好玩的linux shell 命令
    一篇文章带你编写10种语言HelloWorld
    如何用hugo 搭建博客
    c++中的exit()
    枚举数据类型C++
    常见的字符测试函数
  • 原文地址:https://www.cnblogs.com/YangGC/p/8726886.html
Copyright © 2020-2023  润新知