zoukankan      html  css  js  c++  java
  • 时间复杂度

    算法分析

      一个算法的效率一般以执行时间来衡量。度量一段程序的执行时间有以下两种方式:

      事后统计:对一段程序多次执行,统计执行时间。

      事前分析估算:对算法程序的分析,估算算法大概执行时间。当然,估算的时间并不是一个具体的值,而是一个与n(n表示问题规模)有关的函数。

      事后统计方式的缺陷很明显:一是需要等待程序执行,若程序过大,执行时间会较长。二是执行时间除了和算法有关之外,还与计算机的硬件、软件等环境因素相关,统计出来的数据不一定准确。所以一般使用事前分析估算算法的执行时间长短。

    时间复杂度

      一个语句的频度是指该语句重复执行的次数。一个算法的时间频度指的是算法中最大的语句频度,用T(n)表示。

      例如,计算从1加到n的和:

    1 public static int sum(int n) {
    2     int sum = 0;
    3     for (int i = 1; i <= n; i++) sum += i;
    4     return sum;
    5 }
    sum

      对于这段程序而言,其时间频度T(n) = n + 1(语句“i <= n”的频度最大,重复执行了n + 1次)。

    1 public static int sum(int n) {
    2     return (1 + n) * n / 2;
    3 }
    sum

      对于这段程序而言,其时间频度T(n) = 1。

      所以,两段程序的执行结果相同,但明显地第二个程序的时间频度比第一个小,其执行效率就比第一个高。

      程序规模较小还可以用时间频度衡量,而程序规模大时,一般不再以时间频度衡量,而是以时间复杂度衡量。

      时间复杂度O(f(n))与时间频度T(n)的关系为:

      

      其中,k为常数。

      此时可以记为:T(n)=O(f(n))。

      例如,算法a的时间频度T(n) = 4n3 + 3n2 + 2n,算法b的时间频度T(n) = n3 + n2,如果按时间频度衡量的话,算法b的效率更高;但是a、b的时间复杂度都是O(n3),所以算法a和b的效率相差不大。

      常见的时间复杂度类型从低到高依次是:常数阶、对数阶、线性阶、线性对数阶、k次方阶、指数阶和阶乘阶。

    常数阶

      常数阶的算法指的是时间复杂度为O(1)的算法。例如,算法程序不包含循环结构:

    1 public static int sum(int n) {
    2     return (1 + n) * n / 2;
    3 }
    sum

    对数阶

      对数阶的算法指的是时间复杂度为O(log n)的算法。例如,算法程序只有一层循环,循环变量翻倍迭代:

    1 public static int sum(int n) {
    2     int sum = 0;
    3     for (int i = 1; i < 10; i *= 2) sum += i;
    4     return sum;
    5 }
    sum

    线性阶

      线性阶的算法指的是时间复杂度为O(n)的算法。例如,算法程序只有一层循环,循环变量自增迭代:

    1 public static int sum(int n) {
    2     int sum = 0;
    3     for (int i = 1; i < 10; i ++) sum += i;
    4     return sum;
    5 }
    sum

    线性对数阶

      线性对数阶的算法指的是时间复杂度为O(n log n)的算法。例如,算法程序有两层循环,外循环的循环变量自增迭代,内循环的循环变量翻倍迭代:

    1 public static int sum(int n) {
    2     int sum = 0;
    3     for (int i = 1; i < 10; i ++) 
    4         for (int j = 1; j < 10; j *= 2) 
    5             sum += i * j;
    6     return sum;
    7 }
    sum

    k次方阶

      k次方阶的算法指的是时间复杂度为O(nk)(k > 1)的算法。例如,立方阶的算法程序有三层循环,且三层循环的循环变量都是自增迭代:

    1 public static int sum(int n) {
    2     int sum = 0;
    3     for (int i = 1; i < 10; i++) 
    4         for (int j = 1; j < 10; j++) 
    5             for (int k = 1; k < 10; k++) 
    6                 sum += i * j * k;
    7     return sum;
    8 }
    sum

    指数阶

      指数阶的算法指的是时间复杂度为O(an)(a > 1)的算法。

    阶乘阶

      阶乘阶的算法指的是时间复杂度为O(n!)的算法。

  • 相关阅读:
    linux centos下配置静态ip地址
    《Linux内核设计与实现》勘误
    关于Linux内核学习(经典)
    如何成为一个Linux内核开发者(经典)
    为红米Note 5 Pro编译Lineage OS 15.1的各种坑
    C语言调用DIRECT3D的实例代码,通过lpVtbl字段进行
    OBS插件学习入门:一个非常简单的、调节音量的filter
    从工程角度看C++观察者模式中的接口是否需要提供默认的实现
    Windows音频SDK的发展历程
    闲话__stdcall, __cdecl, __fastcall出现的历史背景以及各自解决的问题
  • 原文地址:https://www.cnblogs.com/lqkStudy/p/11567083.html
Copyright © 2011-2022 走看看