数据结构与算法(C)------2.时间复杂度和空间复杂度

目录

1.算法效率

2.时间复杂度

2.1问题规模和语句频度

 2.2 时间复杂度定义

 2.3 时间复杂度计算

2.4 最好、最坏和平均时间复杂度 

3. 算法的空间复杂度

3.1 空间复杂度计算


 

1.算法效率

算法效率分析分为时间复杂度和空间复杂度。时间复杂度主要衡量一个算法的运行速度,空间复杂度主要衡量一个算法所需要的额外空间。

2.时间复杂度

2.1问题规模和语句频度

问题规模:算法求解问题输入量的多少,一般用整数n表示

语句频度:一条语句重复执行次数

        设每条语句执行一次的时间均为单位时间,则一个算法的执行时间可用算法中所有语句频度之和来度量。

【例1】求下面代码各语句频度


	int i = 0;
	int sum = 0;  
	for (i = 1; i <= n; i++)
	{
		sum = sum + i;
	}
	printf("%d\n", sum);
  1. int i = 0;            只执行1次,频度为1
  2. int sum = 0;      只执行1次,频度为1
  3. for(i = 1;i<=n;i++);     执行(n+1)次,频度为(n+1)
  4. sum = sum +i;           执行n次,频度为n
  5. printf("%d\n", sum);   执行1次,频度为1

该算法所有语句频度之和 ,是n的函数,用f(n)表示,为

f(n) = 1+1+(n+1)+n+1=2n+4

 2.2 时间复杂度定义

一般情况下,算法中基本语句重复执行的次数是问题规模n的某个函数f(n),算法的时间量度记为

T(n) = O(f(n))

它表示随着问题规模n的增大,算法执行的时间增长率和f(n)的增长率相同,称作算法的渐进时间复杂度,简称时间复杂度。

定理:若f(n) = a_{m}n^{m}+a_{m-1}n^{m-1}+...+a_{1}n+a_{0}是一个多项式,则

T(n) = O(n^{m})

 2.3 时间复杂度计算

【例2】常量阶

{x++;s=0;}

 两条语句时间频度均为1,与问题规模n无关,T(n) = O(1),称为常量阶。

【例3】线性阶

for (int i = 0; i < n; i++)
{
	x++;
	s = 0;
}

循环体内两条基本语句的频度均为f(n) = n,所以时间复杂度为T(n) = O(n),称为线性阶。

【例4】平方阶

for (int i = 0; i < n; i++)
{
	for (int j = 0; j < n; j++)
	{
		s++;
	}
}

循环体内语句频度为f(n) = n^{2},时间复杂度为T(n) = O(n^{2}),称为平方阶。

通常情况下,当有循环时,算法的时间复杂度是由最深层循环内的基本语句的频度f(n)决定的。

【例5】立方阶

for (int i = 0; i < n; i++)
{
	for (int j = 0; j < n; j++)
	{
		for(int k = 0;k<n;k++)
		{
			s++;
		}
	}
}

循环体内语句频度为f(n) = n^{3},时间复杂度为T(n) = O(n^{3}),称为立方阶。

【例6】对数阶

for (int i = 1; i < n; i = i * 2)
{
	s++;
}

设循环体内语句的基本频度为f(n),则有2^{f(n)}\leq n,则f(n) \leq log_{2}n,所以时间复杂度为T(n) = O(log_{2}n),称为对数阶。

常见的时间复杂度按数量级递增排序依次为:

O(1)   O(n)       O(nlog_{2}n)   O(log_{2}n)      O(n^{2})    O(n^{3})       O(n^{k})        O(2^{n})

2.4 最好、最坏和平均时间复杂度 

 对于某些问题的算法,语句的频度不仅与问题规模有关,还与其他因素有关。

【例7】在一维数组a中查找某一等于e的元素,并返回其位置。返回-1表示不存在。

(1)for(i = 0;i<n;i++)
(2)    if(a[i] == e) return i;
(3)return -1;

可以看出,此问题不仅与问题规模n有关,还和元素所在位置有关。

如果元素e就在数组起始位置,(2)语句频度f(n) = 1

如果元素e在数组最后位置或者不存在,(2)语句频度为f(n) = n

所以最好时间复杂度为T(n) = O(1)

最坏时间复杂度就位T(n) = O(n)

对于一个算法来说,需要考虑各种可能出现的情况以及每一种情况出现的概率。则平均时间复杂度为

 \sum (n_{i}p_{i}) 

其中n_{i}为语句频度,p_{i}为这种情况的概率。

对于刚刚这个算法来说,查找的元素出现在每个位置的概率是相同的,都是\frac{1}{n},所以平均时间复杂度为

T(n) = (1+2+...+n)/n =O(n)

3. 算法的空间复杂度

        空间复杂度是对一个算法在运行过程中临时占用存储空间大小的量度,所谓的临时占用存储空间指的就是代码中辅助变量所占用的空间,它包括为参数表中形参变量分配的存储空间和为在函数体中定义的局部变量分配的存储空间两个部分。我们用 S(n) = O(f(n))来定义,其中n为问题的规模(或大小)。

        通常来说,只要算法不涉及到动态分配的空间,以及递归、栈所需的空间,空间复杂度通常为O(1)。一个一维数组a[n],空间复杂度O(n),二维数组为O(n^{2})

原地工作:空间复杂度为O(1)

3.1 空间复杂度计算

【例8】数组逆序,将一维数组中的n个数逆序存放到原数组中。

for (int i = 0; i < n / 2; i++)
{
	t = a[i];
	a[i] = a[n - i - 1];
	a[n - i - 1] = t;
}

仅借助变量t,与问题规模n无关,空间复杂度为S(n) = O(1)

for (int i = 0; i < n; i++)
	b[i] = a[n - i - 1];
for (int i = 0; i < n; i++)
	a[i] = b[i];

 而这个算法需要借助一个大小为n的辅助数组b,空间复杂度为S(n) = O(n)

通常情况下,鉴于存储空间较大,我们都以算法的时间复杂度作为算法的优劣的衡量标准。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值