[数据结构]时间复杂度-如何计算时间复杂度

如何计算时间复杂度


概念

什么是时间复杂度

时间复杂度用于描述一个算法的运行时间消耗。刷题也会有部分题要求写出一些进阶解法

时间频度T(n)

一个算法执行所耗费的时间,从理论上是不能算出来的,必须上机运行测试才能知道。但我们不可能也没有必要对每个算法都上机测试,只需知道哪个算法花费的时间多少就可以了。一个算法花费的时间与算法中语句的执行次数成正比例,哪个算法中语句执行次数多,它花费时间就多。一个算法中的语句执行次数称为语句频度或时间频度。记为T(n)。

时间复杂度

时间频度T(n)中,n称为问题的规模,当n不断变化时,时间频度T(n)也会不断变化。一般情况下,算法中基本操作重复执行的次数是问题规模n的某个函数,用T(n)表示,若有某个辅助函数f(n),使得当n趋近于无穷大时,T(n)/f(n)的极限值为不等于零的常数,则称f(n)是T(n)的同数量级函数,记作T(n)=O(f(n)),它称为算法的渐进时间复杂度,简称时间复杂度。

大O表示法

用O( )来体现算法时间复杂度的记法,我们称之为大O表示法。
推导大O阶,我们可以按照如下的规则来进行推导,得到的结果就是大O表示法:
1.用常数1来取代运行时间中所有加法常数。
2.修改后的运行次数函数中,只保留最高阶项
3.如果最高阶项存在且不是1,则去除与这个项相乘的常数。

步骤

First:

  1. 找到执行次数最多的语句
  2. 语句执行语句的数量级
  3. 用O表示结果

计算时间复杂度的3个出发点,掌握这三个出发点,那么一向搞不懂的时间复杂度就可以迎刃而解啦。

Second:

  1. 用常数1取代运行时间中的所有加法常数
  2. 在修改后的运行次数函数中,只保留最高阶项
  3. 如果最高阶项存在且不是1,那么我们就去除于这个项相乘的常数。比如3n2我们取n2

举例

这里使用Java编写程序来举例子

例1

内容就是打印8条语句,问这个程序的时间复杂度是多少?

public class Test {
	public static void main(String[] args) {
		System.out.println("111");
		System.out.println("111");
		System.out.println("111");
		System.out.println("111");
		System.out.println("111");
		System.out.println("111");
		System.out.println("111");
		System.out.println("111");
	}
}

O(8)?
按照时间复杂度的概念“T(n)是关于问题规模为n的函数”,这里跟问题规模没有关系,用我们的第4项,时间复杂度为O(1)

例2

(线性阶)

public class Test {
	public static void main(String[] args) {
		int sum = 0;
		for(int i=1;i<=100;i++) {
			sum = sum + i;
		}
	}
}

时间复杂度为O(n)

例3

(平方阶)

public class Test {
	public static void main(String[] args) {
		int sum = 0;
		for(int i=1;i<=100;i++) {
			for(int j=1;j<=100;j++)
				sum = sum + i;
		}
	}
}

外层i的循环执行一次,内层j的循环就要执行100次,所以外层执行100次,那么总的就需要执行100*100次,那么n次呢?就是n的平方次了。所以时间复杂度为:O(n^2)

例4

(平方阶)

public class TS {
	public static void main(String[] args) {
		int sum = 0;
		for(int i=1;i<=100;i++) {
			for(int j=i;j<=100;j++)
				sum = sum + i;
		}
	}
}

当i=1的时候执行n次,当n=2的时候执行(n-1)次,......
一直这样子下去就可以构造出一个等差数列:n+(n-1)+(n-2)+......+2+1
根据等差数列的求和公式:image
或者image
求和易得:n+n(n-1)/2整理一下就是n(n+1)/2然后我们将其展开可以得到n^2/2+n/2。
根据我们的步骤走,保留最高次项,去掉相乘的常数就可以得到时间复杂度为:O(n^2)

例4

(对数阶)

public class Test {
	public static void main(String[] args) {
		int i=1;
		int n= 100;
		while(i<n) {
			i = i*2;
		}
}

2^x = n,所以时间复杂度为O(log2n)

常见时间复杂度量级

常数阶O(1)
线性阶O(n)
对数阶O(logN)
线性对数阶O(nlogN)
平方阶O(n2)
立方阶O(n3)
K次方阶O(nk)
指数阶(2n)

时间复杂度所耗费的时间从小到大依次是:

O(1 )< O(logn) < O(n) < O(n*logn) < O(n^2) < O(n^3) < O(2^n) < O(n!) < O(n^n)


本文遵循CC 4.0 BY-SA版权协议,部分内容来源于网络

posted @ 2022-08-22 13:59  小天呜啦啦  阅读(73)  评论(0)    收藏  举报