排序算法的时间复杂度_算法的时间复杂度

14bcbea3e37504de32fdc508359c516a.png

一、 算法的时间复杂度

1、如何评估算法的性能

数据结构和算法,本质上是解决现实存在的问题,即如何让解决指定问题的代码运行得更快?一个算法如果能在所要求的 资源限制(resource constraint)内将问题解决好,则称这个算法是有效率的(effient)。

限制可分为空间限制和时间限制

如何衡量算法的执行时间? 可以使用如下的代码测试:

void calcDuration(){ 
    long begin = System.currentTimeMillis(); 
    function(n); // 测试function的执行时间
    long end = System.currentTimeMillis();
}

我们可以通过end-begin来计算出function()的执行时间。这类“事后统计”的方法用来评估算法执行效率是正确的,但是它也有它的局限性:

  1. 受不同机器配置的影响,结果差异不同,甚至同一段算法,在不同机器上跑出来的结果差异很大。
  2. 算法的测试结果受输入的规模影响很大,也就是说,输入不同规模的数据,结果差别非常大。

能不能事先“算”出算法的执行效率呢?这就引出了以下两个概念:时间复杂度,空间复杂度。

2、 大O表示法

看下面的简单代码:

void foo(){
    for(int i =0;i<n;i++){//执行了n次
        System.out.println("Hello world");//执行了n次
    }
    System.out.println("function over");//执行了1次
}

在上述例子中,第1行的代码总共执行了n次,第2行的代码总共执行n次,第4行代码会执行1次。(这里假设计算机处理语句代价都为c)

假设算法总执行时间为T(n),其中n为问题的规模, 那么上述代码的总执行时间就是: T(n)=(2n+1)*c

可以看出,T(n)与代码的总执行次数总是成正比的,即与(2n+1)成正比. 我们将代码执行次数用f(n)来表示,即: f(n)=2n+1

有了执行次数后, 用大0 (英语:Big O notation)来表示算法的复杂度, 即:

T(n) =0(f(n))

针对上述代码的时间复杂度: T(n) =0(2n + 1) = 0(n)

在表示时间复杂度的时候, 大0并不是表示代码真正的执行时间, 而是表示代码执行时间随着数据规模增长的变化趋势. 一般具有以下特点:

  1. 不保留系数
  2. 只保留最高阶的项(随着数据规模n的增长, 低阶项对结果的影响越来越小, 可以省去. 常数可以看成0阶)

可以把大O符号想象成一个过滤性的漏斗,过滤那些系数以及低阶的项。

23ef876a4ac0a4af0897edb5c280364d.png

时间复杂度又分: 最优时间复杂度, 平均时间复杂度, 最坏时间复杂度. 一般平均复杂度更有指导意义.

二、排序算法的复杂度

1、冒泡算法时间复杂度计算

以冒泡算法为例, 我们算下冒泡算法的复杂度:

def bubbleSort(arr: Array[Int]): Unit = {
    for (i <- 0 until arr.length - 1) { // 
        for (j <- 0 until arr.length - 1 - i)   // 
            if (arr(j) > arr(j + 1)) { 
                swap(arr, j, j + 1)
            }
        }

    }   
}

最优(最初有序)情况: 每次都不需要交换, 则只需次数

ff34c44f305fdf873f1eb3d33ad260f7.png
排序算法的复杂度

三、其他排序算法时间复杂度

d45071a3a0eb9498f3244dd88ebae3b7.png
其他排序算法时间复杂度

0a2c3bf58385c451d764af4e353bbe8c.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值