`
wx1568520008
  • 浏览: 20438 次
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

关于时间复杂度分析

 
阅读更多

我们假设计算机运行一行基础代码需要执行一次运算。

int aFunc(void) {
    printf("Hello, World!\n");      //  需要执行 1 次
    return 0;       // 需要执行 1 次
}

那么上面这个方法需要执行 2 次运算

int aFunc(int n) {
    for(int i = 0; i<n; i++) {         // 需要执行 (n + 1) 次
        printf("Hello, World!\n");      // 需要执行 n 次
    }
    return 0;       // 需要执行 1 次
}

这个方法需要 (n + 1 + n + 1) = 2n + 2 次运算。

我们把 算法需要执行的运算次数 用 输入大小n 的函数 表示,即 T(n) 。
此时为了 估算算法需要的运行时间 和 简化算法分析,我们引入时间复杂度的概念。

定义:存在常数 c 和函数 f(N),使得当 N >= c 时 T(N) <= f(N),表示为 T(n) = O(f(n)) 。
如图:

91c7bef9bcaeec9043fc387117923414046.jpg

 

    当 N >= 2 的时候,f(n) = n^2 总是大于 T(n) = n + 2 的,于是我们说 f(n) 的增长速度是大于或者等于 T(n) 的,也说 f(n) 是 T(n) 的上界,可以表示为 T(n) = O(f(n))。因为f(n) 的增长速度是大于或者等于 T(n) 的,即T(n) = O(f(n)),所以我们可以用 f(n) 的增长速度来度量 T(n) 的增长速度,所以我们说这个算法的时间复杂度是 O(f(n))。

    算法的时间复杂度,是用来度量算法的运行时间,记作: T(n) = O(f(n))。它表示随着 输入大小n 的增大,算法执行需要的时间的增长速度可以用 f(n) 来描述。

    显然如果 T(n) = n^2,那么 T(n) = O(n^2),T(n) = O(n^3),T(n) = O(n^4) 都是成立的,但是因为第一个 f(n) 的增长速度与 T(n) 是最接近的,所以第一个是最好的选择,所以我们说这个算法的复杂度是 O(n^2) 。

       那么当我们拿到算法的执行次数函数 T(n) 之后怎么得到算法的时间复杂度呢?

  1. 我们知道常数项对函数的增长速度影响并不大,所以当 T(n) = c,c 为一个常数的时候,我们说这个算法的时间复杂度为 O(1);如果 T(n) 不等于一个常数项时,直接将常数项省略。
比如
第一个 Hello, World 的例子中 T(n) = 2,所以我们说那个函数(算法)的时间复杂度为 O(1)。
T(n) = n + 29,此时时间复杂度为 O(n)。

 

    2.我们知道高次项对于函数的增长速度的影响是最大的。n^3 的增长速度是远超 n^2 的,同时 n^2 的增长速度是远超 n 的。 同时因为要求的精度不高,所以我们直接忽略低此项。

比如
T(n) = n^3 + n^2 + 29,此时时间复杂度为 O(n^3)。

 

    3.因为函数的阶数对函数的增长速度的影响是最显著的,所以我们忽略与最高阶相乘的常数。

 

比如
T(n) = 3n^3,此时时间复杂度为 O(n^3)。

    综合起来:如果一个算法的执行次数是 T(n),那么只保留最高次项,同时忽略最高项的系数后得到函数 f(n),此时算法的时间复杂度就是 O(f(n))。为了方便描述,下文称此为 大O推导法。

    由此可见,由执行次数 T(n) 得到时间复杂度并不困难,很多时候困难的是从算法通过分析和数学运算得到 T(n)。对此,提供下列四个便利的法则,这些法则都是可以简单推导出来的,总结出来以便提高效率。

  1. 对于一个循环,假设循环体的时间复杂度为 O(n),循环次数为 m,则这个
    循环的时间复杂度为 O(n×m)。
void aFunc(int n) {
    for(int i = 0; i < n; i++) {         // 循环次数为 n
        printf("Hello, World!\n");      // 循环体时间复杂度为 O(1)
    }
}

此时时间复杂度为 O(n × 1),即 O(n)。

 

    2.对于多个循环,假设循环体的时间复杂度为 O(n),各个循环的循环次数分别是a, b, c...,则这个循环的时间复杂度为 O(n×a×b×c...)。分析的时候应该由里向外分析这些循环。

void aFunc(int n) {
    for(int i = 0; i < n; i++) {         // 循环次数为 n
        for(int j = 0; j < n; j++) {       // 循环次数为 n
            printf("Hello, World!\n");      // 循环体时间复杂度为 O(1)
        }
    }
}

此时时间复杂度为 O(n × n × 1),即 O(n^2)。

 

    3.对于顺序执行的语句或者算法,总的时间复杂度等于其中最大的时间复杂度。

 

void aFunc(int n) {
    // 第一部分时间复杂度为 O(n^2)
    for(int i = 0; i < n; i++) {
        for(int j = 0; j < n; j++) {
            printf("Hello, World!\n");
        }
    }
    // 第二部分时间复杂度为 O(n)
    for(int j = 0; j < n; j++) {
        printf("Hello, World!\n");
    }
}

此时时间复杂度为 max(O(n^2), O(n)),即 O(n^2)。

 

        4.对于条件判断语句,总的时间复杂度等于其中 时间复杂度最大的路径 的时间复杂度

void aFunc(int n) {
    if (n >= 0) {
        // 第一条路径时间复杂度为 O(n^2)
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < n; j++) {
                printf("输入数据大于等于零\n");
            }
        }
    } else {
        // 第二条路径时间复杂度为 O(n)
        for(int j = 0; j < n; j++) {
            printf("输入数据小于零\n");
        }
    }
}

    此时时间复杂度为 max(O(n^2), O(n)),即 O(n^2)。


小结:

        时间复杂度分析的基本策略是:从内向外分析,从最深层开始分析。如果遇到函数调用,要深入函数进行分析。


 

 

转载于:https://my.oschina.net/u/4167465/blog/3081906

分享到:
评论

相关推荐

    算法时间复杂度分析基础 (论文)

    "算法时间复杂度分析基础" 本文论述了算法时间复杂度分析的基础内容,涵盖了时间复杂度的定义、数学意义、分析示例等方面的知识点。 时间复杂度是指算法执行时间随输入规模增长而增长的量级,是评价算法优劣的重要...

    关于递归算法时间复杂度分析的探讨.pdf

    关于递归算法时间复杂度分析的探讨,是一个深入理解算法效率和优化的关键议题。递归,作为解决问题的一种强大工具,其本质是将复杂问题分解为更简单的子问题,通过求解这些子问题来达到最终解决方案的目的。然而,...

    多种排序算法比较及时间复杂度分析

    C/C++排序算法 计时 时间复杂度分析

    内部排序算法复杂度分析

    各种内部排序算法的时间复杂度分析结果只给出了算法执行时间的阶,或大概执行时间。试通过随机的数据比较各算法的关键字比较次数和关键字移动次数,以取得直观感受。

    算法的时间复杂度分析.pdf

    ### 算法的时间复杂度分析 #### 一、引言与基本概念 算法的时间复杂度是衡量一个算法效率的关键指标之一。它反映了随着输入数据规模的增长,算法所需执行时间的增长速度。通常情况下,时间复杂度越低的算法,在...

    排序算法的时间复杂度分析

    本项目通过对选择排序法进行时间复杂度分析,来探讨其性能特点。 选择排序是一种基础的排序算法,它的基本思想是在未排序的序列中找到最小(或最大)元素,存放到排序序列的起始位置,然后再从剩余未排序元素中继续...

    深度解析:数据结构算法时间复杂度分析指南

    在计算机科学中,算法的...本文详细介绍了时间复杂度分析的重要性和方法,通过具体示例展示了如何对不同数据结构和算法进行时间复杂度分析。希望这能帮助读者更好地理解时间复杂度的概念,提高算法分析和设计的能力。

    算法的时间复杂度分析

    ### 算法的时间复杂度分析 #### 一、算法分析的基本理论 ##### 1.1 评价算法好坏的标准 在计算机科学中,算法是指解决问题的一系列步骤或指令集。评估算法的好坏不仅要看它是否能正确解决问题,还需要考虑算法的...

    排序算法时间复杂度的分析java语言描述

    在计算机科学中,排序算法是数据处理的重要组成部分,它们用于将一组无序的数据按照特定的顺序排列。在Java编程语言中,实现...然而,了解基本排序算法的原理和时间复杂度分析对于优化代码和解决特定问题仍然至关重要。

    不同方案求解最大公约数及时间复杂度分析

    不同方案求解最大公约数及时间复杂度分析 本文总结了四种不同的方案来求解最大公约数:暴力枚举法、欧几里得算法、更相减损法和Stein算法,并对它们的时间复杂度进行了分析。 暴力枚举法 暴力枚举法是一种简单的...

    第02课丨02时间复杂度和空间复杂度分析.mp4

    对时间复杂度和空间复杂度进行超级详细的讲解

    复杂度分析(下):浅析最好、最坏、平均、均摊时间复杂度.pdf

    在进行程序的时间复杂度分析时,我们通常会考虑几种不同场景下的复杂度,以期更准确地评估一个算法的实际运行时间。以下是对最好、最坏、平均、均摊时间复杂度的详细分析和解释。 首先,时间复杂度是算法运行时间与...

    算法的设计与分析——时间复杂度.docx

    算法设计与分析——时间复杂度 算法设计与分析是计算机科学中的一门重要课程,旨在研究和分析算法的设计、实现和优化。时间复杂度是算法设计与分析的核心概念之一,指的是算法执行所需的时间成本。了解时间复杂度...

    算法时间复杂度

    根据给定文件的信息,我们可以详细地探讨“算法时间复杂度”的相关知识点。时间复杂度是衡量算法运行时间随输入规模增长而变化的...掌握好时间复杂度的分析方法,能够帮助我们更好地理解和优化算法,从而提高软件性能。

    快速排序与归并排序的时间复杂度分析

    快速排序的时间复杂度在最好情况下为O(n log n),最坏情况下为O(n^2),平均情况也是O(n log n)。由于在每一轮划分中,元素的移动次数可能小于比较次数,所以快速排序通常被认为是实际应用中效率较高的排序算法。但其...

    遗传禁忌搜索算法收敛性和时间复杂度分析

    本文阐述了遗传禁忌搜索算法的混合策略,从理论上对该算法的收敛性进行了证明,对时间复杂度进行了分析。应用马尔科夫链模型证明了遗传禁忌搜索算法是以概率1收敛到全局最优解的,并应用求解随机算法时间复杂度的方法,...

    算法复杂度分析基础课件

    算法复杂度分析是评估算法效率的重要工具,主要涉及时间复杂度和空间复杂度两个方面。这门基础课程旨在教授如何分析算法在处理大规模数据时所需的资源,帮助开发者优化程序性能。 一、算法复杂度的概念 1. 时间...

    根号n段归并排序算法时间复杂度分析过程

    根号n段归并排序算法是一种优化过的归并排序策略,它的主要目标是减少比较和交换操作的次数,从而在处理大数据集时提高效率。...理解其工作原理和时间复杂度分析有助于我们在实际应用中选择合适的排序算法。

    时间复杂度分析AlgorithmFloyd.pptx

    时间复杂度分析AlgorithmFloyd.pptx

    数据结构预算法——时间复杂度分析实例课件 数据结构预算法.pdf

    数据结构预算法——时间复杂度分析实例课件 在计算机科学中,时间复杂度是衡量算法性能的重要指标之一。时间复杂度是指算法执行的时间与问题规模之间的关系。通常,我们使用大O符号来表示时间复杂度。下面,我们将...

Global site tag (gtag.js) - Google Analytics