大O记号

  在程序中,人们经常关心的是程序运行时间。比如我们较早接触到的起泡排序,对于长度为n的序列A[0,n-1],我们比较A[i]和A[i+1]的大小,当A[i]<=A[i+1]时我们称这两个元素是顺序的,否则我们称这两个元素是逆序的,当两个元素逆序时,我们交换两个元素的位置,我们依次扫描序列A,当到达序列尾部时结束,这我们称完成了一趟扫描,由于每次至少能确定一个较大元素的位置,所以在进行了n-1趟扫描后程序结束。

下图为一个随机的数组

用冒泡排序扫描一趟后的结果为

  那么这个程序运行的时间是多少呢?显然其相关的因素很多。n的大小,序列本身的有序程度,不同的机器都有可能导致程序的执行时间不相同。这样的话问题就过于复杂,于是我们需要考虑一个理想的计算机,在这个计算机中每一个基本操作都是常数时间,这样我们就可以通过考察算法需要执行的次数来间接考察这个算法的执行时间。但是在序列有序和序列无序的情况下,元素交换的次数明显不同,从保守角度出发,我们选择最坏的结果作为T(n)。

  现在,算法的时间复杂度T(n)=最坏情况下所须执行基本操作的次数,其中n是问题的规模。在现实中,我们更愿意关注问题规模不断变大时的算法复杂度,因为规模小时通常我们处理问题的开销也比较小。为此,我们引入了大O记号。

  若存在正的常数c和函数f(n),使得当n>>2时,有T(n)<=c·f(n),则可认为f(n)是T(n)的渐进上界,记为T(n)=O(f(n))。

  

  从图像上看出,f(n)是存在的,大O记号的存在使我们用一个更简单的函数来描述T(n)的上界。在有更好的办法分析算法的时间复杂度之前,进行了一个定量与定性之间的折中。

大O记号有两个重要的性质:

1)         对任意常数c>0,有O(f(n))=O(c·f(n))

2)         对任意常数a>b>0,有O(n^a+n^b)=O(n^a)

由于性质1,我们可以在时间复杂度的上界函数中提取任意常数。

由于性质2,我们可以忽略多项式中最高次幂以外的项。

  现在,我们继续讨论文章开始的起泡排序,我们把元素的比较和交换作为基本操作,最糟糕情况下,每一轮进行n-1次比较,并进行n-1次交换,在执行了n-1轮后排序完成,则有T(n)=2(n-1)^2=n^2-4n+2。T(n)=O(4n^2-4n+2)=O(n^2)。由此我们得到了一个简单的复杂度度量方式。

时间: 2024-12-17 10:43:17

大O记号的相关文章

算法概念、大O记号

算法定义:基于特定的计算类型,旨在解决某一信息处理问题而设计的一个指令序列算法需具备以下要素 输入与输出输入(input):对所求解问题特定实例的描述 输出(output):经计算和处理之后得到的信息,即针对输入问题实例的答案 确定性和可行性:算法应可描述为由若干语义明确的基本操作组成的指令序列,且每一基本操作在对应的计算模型中均可兑现. 有穷性:任意算法都应在执行有限次基本操作之后终止并给出输出 正确性:算法所给的输出应该能够符合由问题本身在事先确定的条件 鲁棒性:例如处理算法输入的退化 重用

大 Θ记号、大 Ω记号、空间复杂度、时间复杂度

最坏情况:以大O记号形式表示的时间复杂度,给出了一个算法的最坏情况,即--对于规模为n的任意输入,算法的运行时间都不会超过O(f(n)) 最好情况 :大 Ω记号-->如果存在正的常数c和函数g(n),对任意n>>2,有T(n) > c * g(n),即认为:在n足够 大后,g(n)给出了T(n)的一个下界,记为: T(n) =Ω (g(n)) 大 Θ记号-->存在正的常数c1和c2,以及函数h(n),对任意n>>2,有 c1*h(n) < T(n) <

算法中的渐进记号

前言 在学习计算机算法时,知道插入排序的时间复杂度是O(n2),那O记号到底是什么意思呢?本文主要介绍几个算法分析时用到的记号. 大O记号 定义:O(g(n)) = { f(n) : 存在正常数c和n0 ,使对所有的n >= n0,都有 0 <= f(n) <= cg(n) }.大O记号给出函数的渐进上界. , 则可以表示为 f(n) = O(n2).证明: 要使得 0 <= f(n) <= cg(n) 存在c = 9/2 ,n0 = 1,使得对所有的n >= n0都有

大O表示法的理解

一. 背景 在现实生活中,解决一个问题可以有多种方法,其中有好的方法,也有较为一般的方法.评判标准虽有不同,但总体思想是:用最小的代价获得最多的收益. 这里所说代价并不仅指金钱开销,有时也包括时间,所耗费资源等. 计算机程序也是为了解决问题而编写的.同理可知,程序有好的,也有一般的,评判标准主要有两方面:时间与空间. 人们都希望事情解决的越快越好,所以程序解决问题花费的时间一定要少.计算机资源是有限的,所以程序也要尽可能的少消耗资源. 不过很多时候不能两全其美,此时应该抓主要矛盾.在编程时,很多

数据结构与算法:算法分析

目录 实验研究 常用函数 渐近分析  一.实验研究(Experimental studies) 1.运行时间测量 时钟时间 time.time() CPU时间 time.clock() 基准时间 timeit.timeit() 在执行算法的时候,我们可以通过改变输入规模的大小和记录花费的时间来研究运行时间. 在python中使用time模块的time函数来记录算法的运行时间: from time import time start_time=time() run algorithm end_ti

[MOOC笔记]第一章 绪论(数据结构)

1.  计算 学习DSA的目的是实现有效的和高效的计算,同时在资源消耗的方面做到足够的低廉. 计算 = 信息处理:借助某些工具,遵照一定规则,以明确而机械的形式进行. 计算模型 = 计算机 = 信息处理工具 算法:在特定的计算模型下,旨在解决特定问题的指令序列. 算法的要素: 输入 待处理的信息(问题) 输出 经处理的信息(答案) 正确性 的确可以解决指定的问题 确定性 任一算法都可以描述为一个由基本操作组成的序列 可行性 每一基本操作都可实现,且在常数时间内完成 有穷性 对于任何输入,经有穷次

初来乍到的新人而已

我是个新人,博客新人,也是编程的新人,我比较喜欢研究一些新奇的东西,数学的东西,我数学也确实不是很怎么样,但我觉得数学是个很神奇的东西,所以科学的基础,真正的计算机研究者必须懂数学(不然就是一个只会编码的码农,很苦逼的板砖者),开这个博客的目的是想与有共同爱好的人一起交流,最近想研究一下Donald E. Knuth大师的做品具体数学>,不过估计有太多的看不懂的地方,我也想把它写出来与大家讨论交流..... 我先把它的目录写出来: 第1章 递归问题1.1 河内塔1.2 平面上的直线1.3 若瑟夫

各种排序时间空间复杂度稳定性分析

下面是常见排序算法的速度比较:(从慢到快) 1.冒泡排序O(N^2) 2.简单选择排序O(N^2) 3.直接插入排序O(N^2) 4.折半插入排序O(N^2) 5.希尔排序,近似为O(N^1.25)     (尚无定论,但可以确定是N~N^2之间的多项式时间复杂度) 6.堆排序O(NlogN) 7.归并排序O(NlogN) 8.快速排序O(NlogN) 一般来说是快排最快的.但是也有例外! 6,7都是性能稳定的算法,这个复杂度就是它们的最坏时间复杂度,而快排的复杂度只是平均时间复杂度.快排的最差

基础 2016.4.16

1.大O记号(big‐O notation) 性质: 常系数可忽略:O(f(n)) = O(c × f(n)) 低次项可忽略:O(n^a + n^b) = O(n^a), a > b > 0 常数(constant function) 2 = 2010 = 2010*2010 = 20102010 = O(1) 这类算法的效率最高 对数 O(logn):lnn | lgn | log100n | log2010n 常底数无所谓 ? 常数 a, b > 0,lna / lnb = loga