深入理解算法的时间效率衡量标准--时间复杂度

这篇具有很好参考价值的文章主要介绍了深入理解算法的时间效率衡量标准--时间复杂度。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一.什么是时间复杂度

        很多同学在程序开发和算法调优的过程中,经常会接触到时间复杂度的概念,那究竟什么是时间复杂度呢?

        在回答这个问题之前,我们先举一个例子,我们把编写一个程序的过程类比成指挥一场战役,程序开发人员就扮演着指挥者的角色,编写的代码就是被指挥的战士,那么算法就是指挥战役的"兵法"。

       在实际开发过程中,为了满足业务需求,实现业务目的的各种方法和思路就是算法,而时间复杂度是衡量算法在处理输入数据时所需的时间量级的参数。它是用来描述算法执行时间效率的指标,是衡量"兵法"好坏的重要指标。

        如果我们的业务目的是获取5个4的和,那么有两种实现思路:

                算法1:  4+4+4+4+4=20
                算法2:  4*5=20

        同样的数据,同样的目的,不同的算法,不同的方法和思路,效率就会不同,而在实际开发过程中,实现目的时所需时间越短的算法相对而言越有优势,而时间的度量标准就是时间复杂度。

二.算法的时间效率衡量

        在解释时间复杂度如何计算之前,我们来看一下算法的时间效率衡量标准,现有需求:

        如果 a+b+c=1000,且 a^2+b^2=c^2(a,b,c 为自然数),如何求出所有a、b、c可能的组合?

        解题算法一:穷举法

                将问题的所有可能的答案一一列举,然后根据条件判断此答案是否合适,合适就保留,不合适就丢弃       

#列举a,b,c的所有可能的数值
for a in range(0,1001):                   
    for b in range(0,1001):                
        for c in range(0,1001):            
#判断是否满足条件
            if a**2+b**2+c**2 and a+b+c==1000:
                print('a,b,c:%d,%d,%d' % (a,b,c))

        解题算法二:

                知道a,b,c他们三者是有一个关系的,就可以不用对c进行遍历,直接把c列成一个条件即可:

#注意这里是两层循环
for a in range(0,1001):
    for b in range(0,1001):
        c=1000-a-b
        if a**2 +b**2==c**2:
            print('a,b,c:%d,%d,%d' %(a,b,c))

        对于同一问题,我们给出了两种解决算法,在两种算法的实现中,我们对程序执行的时间
进行了测算,发现两段程序执行的时间相差悬殊(方法一3.5分钟 相比于 方法二2秒),
由此我们可以得出结论:实现算法程序的执行时间可以反应出算法的效率,即算法的优劣。
        但是如果方法一使用天河二号超级计算机来运行,方法二使用十年前的老旧计算机来运行,结果可能会有出入,因此单纯的依靠时间值来比较算法优劣并不一定是客观准确的!

        那么如何才能客观的评价一个算法的优劣呢?

        我们假定计算机执行算法每一个基本操作的时间是固定的一个时间单位,那么有多少个基本操作就代表会花费多少时间单位,由此可以忽略机器环境的影响,进而客观的反映算法的时间效率。
        时间效率:

        代码执行总时间(T)=操作步骤数量*操作步骤执行时间

深入理解算法的时间效率衡量标准--时间复杂度,数据结构,python

        T=(大整体*子整体*基本操作)*操作步骤执行时间

        我们假定计算机执行算法每一个基本操作的时间是固定的一个时间单位

        T=操作步骤总数(大整体*子整体*基本操作)

三.时间复杂度的计算

        算法一的循环次数:

for a in range(0,1001):                    #1001次
    for b in range(0,1001):                #1001次
        for c in range(0,1001):            #1001次
            if a**2+b**2+c**2 and a+b+c==1000:
                print('a,b,c:%d,%d,%d' % (a,b,c))

        算法一每次循环的步骤:

        1000==a+b+c 为 :3次(两次相加,一次判断)

        a**2+b**2=c**2 为 :5次(三次平方,一次相加,一次判断)

        print('a,b,c:%d,%d,%d' % (a,b,c)) :2次(一次字符串格式化,一次打印)

        每个循环的步骤次数为:3+5+2=10次

        代码步骤总数量:1001*1001*1001*10 次

        假定计算机执行算法每一个基本操作的时间是固定的一个时间单位
        则T = 1001*1001*1001*10

        但是算法是一种独立的存在,它是解决问题的方法和思想,算法一的优劣是不能简单的用T = 1001*1001*1001*10衡量的,需求中要求a+b+c=1000 , 这个 1000 是这个题目的计算范围 , 我们称之为问题规模

        当问题规模为1000的时候
        T = 1001 * 1001 * 1001 * 10 = 10013 * 10
        当问题规模为2000的时候
        T = 20013 * 10
        当问题规模为3000的时候
        T = 30013 * 10
        当问题规模为n的时候
        T = n3 * 10
        我们就将上面的算数,总结为一个表达式:T(n) = n3 * 10 这个表达式称为:时间复杂度
        即:时间复杂度T是关于n的函数

四.时间复杂度的计算规则

时间复杂度的计算规则为:

        1.基本操作:时间复杂度为O(1)

        2.顺序结构:时间复杂度按加法进行计算

        3.循环结构:时间复杂度按乘法进行计算

        4.分支结构:时间复杂度取最大值

        5.判断一个算法的效率时,往往只需要关注操作数量的最高次项,其它次要项和常数项可以忽略

        6.在没有特殊说明时,我们所分析的算法的时间复杂度都是指最坏时间复杂度

基本操作:

        例1:sum=100+200        时间复杂度为O(1)

        例2:sum=200^2 + 1000^2        这里出现了200^2, 那么它的时间复杂度为 O(n2) 吗?答案为否,因为这里执行次数是恒定的, 不会随着问题规模的变化有任何改变, 复杂度是O(1),与问题规模的大小无关, 执行次数恒定的算法, 我们称之为具有O(1)的时间复杂度

顺序结构:

        例3:

        第一步: a = 100
        第二步: b = 200
        第三步: c = a + b
        顺序结构,时间复杂度按加法进行计算
        第一步时间复杂度:O(1)
        第二步时间复杂度:O(1)
        第三步时间复杂度:O(1)

         因为是顺序结构,所以例3的时间复杂度为O(1)+O(1)+O(1)=3O(1),由于计算时间复杂度时要去掉前面的系数,所以例3的时间复杂度为O(1)     

循环结构:

        例4:

        for i in range(0,n):  print(i)

        这里执行次数随着n的变化而变化,所以时间复杂度是O(n)

        例5:

for j in range(0,2):
    for i in range(0,n):
        print(i)

        例子中执行次数是2n次,所以时间复杂度是O(2n)吗?答案为否,因为我们在判断一个算法的效率时,只关注操作数量的最高次项,其他次要项和常数项都可以忽略,所以例5中的时间复杂度为:O(n)

分支结构:

        例5:

        if 分支的时间复杂度为O(n)

        else 分支的时间复杂度为O(n^2)

        由于时间复杂度取最大值,所以上述代码的时间复杂度为O(n^2)

        例6:

        第一步: 时间复杂度:O(n)
        第二步: 时间复杂度:O(n)
        第三步: 时间复杂度:O(n2)
        第四步: 时间复杂度:O(n3)

        顺序结构相加:

        例6的时间复杂度为:T(n) = n + n + n^2 + n^3 = 2n + n^2 + n^3 = O(n^3)

所以计算时间复杂度的方法为:

        ①基本操作
        时间复杂度为O(1)
        ②顺序结构
        时间复杂度按加法进行计算
        ③循环结构
        时间复杂度按乘法进行计算

        ④分支结构
        时间复杂度取最大值
        ⑤判断一个算法的效率时,往往只需要关注操作数量的最高次项,其它次要项和常数项可以忽略
        ⑥在没有特殊说明时,我们所分析的算法的时间复杂度都是指最坏时间复杂度

五.最优最坏时间复杂度

分析算法时,存在几种可能的考虑:
算法完成工作最少需要多少基本操作,即最优时间复杂度
算法完成工作最多需要多少基本操作,即最坏时间复杂度
算法完成工作平均需要多少基本操作,即平均时间复杂度

最优最坏时间复杂度:

假如我们有一个列表 , 我们要通过一个算法从这个列表中找到10
最坏时间复杂度
my_list = [ 1 , 5 , 6 , 4 , 3 , 2 , 7 , 8 , 9 , 10 ]
最优时间复杂度
my_list = [ 10 , 5 , 6 , 4 , 3 , 2 , 7 , 8 , 9 , 1 ]

最优时间复杂度: 反映的只是最乐观最理想的情况,没有参考价值。
最坏时间复杂度: 算法的一种保证,表明算法在此种程度的基本操作中一定能完成工作

因此,我们主要关注算法的最坏情况,亦即最坏时间复杂度

六.常见时间复杂度

常见的时间复杂度有:

执行次数函数举例 非正式术语
42 O(1)    常数阶
2n+3 O(n) 线性阶
3n^2+2n+1 O(n^2)    平方阶
深入理解算法的时间效率衡量标准--时间复杂度,数据结构,python O(logn) 对数阶
6n^3+2n^2+3n+4 O(n^3) 立方阶

需要注意的是,O(logn)最典型的例子是二分查找算法,

这是因为二分查找是一种基于分治思想的算法,它将待查找的有序数组逐步分成两半,然后判断目标值位于数组的哪一部分,并继续在相应的部分中进行查找。通过每次查找都将问题规模缩小一半,它的时间复杂度可以表达为对数函数。

具体而言,执行每一轮二分查找操作时,都会将问题规模减半,因此可以将待查找的元素个数n表示为2的幂,即n=2^k。而每次查找操作都将问题规模减半,所以经过k次查找最终可以找到目标元素。

k 表示二分查找的迭代次数,可以通过求解2^k=n得到。这意味着 k = log2(n)。因此,二分查找的时间复杂度为 O(log n)。

需要注意的是,在二分查找算法的应用场景中,通常假设输入是一个有序数组。如果输入不是有序的,那么首先需要先对数组排序,这会增加额外的时间复杂度。

下一个博客,我们来聊一聊目前主流的算法有哪些。

        

        文章来源地址https://www.toymoban.com/news/detail-756873.html

        

        

        

到了这里,关于深入理解算法的时间效率衡量标准--时间复杂度的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【数据结构】算法效率揭秘:时间与空间复杂度的较量

    在计算机科学中,时间复杂度和空间复杂度是衡量算法性能的两个重要指标。它们分别表示算法在执行过程中所需的时间和空间资源。了解这两个概念有助于我们评估和比较不同算法的优劣,从而选择更合适的算法解决问题~ 欢迎关注个人主页:逸狼 创造不易,可以点点赞吗

    2024年04月28日
    浏览(41)
  • 深入理解数据结构第二弹——二叉树(2)——堆排序及其时间复杂度

    看这篇前请先把我上一篇了解一下:深入理解数据结构第一弹——二叉树(1)——堆-CSDN博客 前言: 相信很多学习数据结构的人,都会遇到一种情况,就是明明最一开始学习就学习了时间复杂度,但是在后期自己写的程序或者是做到哪个需要判断时间复杂度的题时,仍然判

    2024年04月09日
    浏览(45)
  • 如何提高代码效率——时间复杂度与空间复杂度——【C语言】

    当我们面对一个问题时,会有许多种解题思路。我们现在的计算机技术已经达到非常先进的地步,所以当我们用不同的方法对待问题时,时间差异不会很明显,内存差异我们一般在平常小问题时感受不到,所以我们不会去纠结程序的优化过程。 但是在以后的生活中,程序内容

    2024年02月14日
    浏览(42)
  • 【图解数据结构】深入剖析时间复杂度与空间复杂度的奥秘

    🌈个人主页: 聆风吟 🔥系列专栏: 图解数据结构、算法模板 🔖少年有梦不应止于心动,更要付诸行动。      算法是解决特定问题求解步骤的描述,在计算机中表现为指令的有限序列,并且每条指令表示一个或多个操作 。     算法具有五个基本特性:输入、输

    2024年01月19日
    浏览(55)
  • 算法的时间复杂度和空间复杂度

    目录 本章重点 一 时间复杂度 2.1 时间复杂度的概念 2.2 大O的渐进表示法 2.3 常见的时间复杂度的计算 二 空间复杂度 三 常见复杂度对比 四 复杂度的oj练习 4.1 消失的数字 4.2 旋转数字 每一天都是人生限定,每一天都值得100%努力 (1)算法效率(2)时间复杂度(3)空间复

    2024年02月01日
    浏览(51)
  • 算法之【时间复杂度】与【空间复杂度】

    目录 一、算法 1、算法定义 2、两种算法的比较 3、算法的特性 4、算法设计的要求 二、算法的复杂度 1、时间复杂度 1.1定义 1.2大O的渐近表示法 1.3推导大O阶方法 1.4最坏情况与平均情况 1.5常见的时间复杂度计算示例 🍂常数阶: 🍂线性阶:  🍂对数阶: 🍂平方阶: 2、空间

    2024年02月05日
    浏览(62)
  • 【算法基础】时间复杂度和空间复杂度

    1 算法的评价 2 算法复杂度 2.1 时间复杂度(Time Complexity) 2.1.1 如何计算时间复杂度: 2.1.2 常见的时间复杂度类别与示例 2.2 空间复杂度 2.2.1 如何计算空间复杂度 2.2.2 常见的空间复杂度与示例 3 时间复杂度和空间复杂度计算示例 例子1:计算数组中所有元素的和。 例子2:快

    2024年02月08日
    浏览(58)
  • 算法的时间复杂度与空间复杂度

    1.算法效率 2.时间复杂度 3.空间复杂度 4.复杂度oj题目 1.算法效率 1.1 如何衡量一个算法的好坏 一辆车的好坏我们可以从价格,油耗...... 方面来衡量,但衡量一个算法的好坏我们该从哪一个方面入手呢?比如斐波那契数列: 斐波那契数列的递归实现方式非常简洁,但简洁一定

    2024年02月15日
    浏览(85)
  • 八大排序算法(含时间复杂度、空间复杂度、算法稳定性)

    下列算法默认都是对数组进行升序 1.1、算法思想 插入排序是一种简单直观的排序算法,它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。 插入排序的具体步骤如下: 从第一个元素开始,该元素可以认为已经被排序;

    2024年02月08日
    浏览(47)
  • 算法学习22:时间复杂度 和 空间复杂度

    提示:以下是本篇文章正文内容: 😍😍😍文章链接👍👍👍 提示:这里对文章进行总结: 💕💕💕

    2024年04月22日
    浏览(99)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包