C语言之数据结构算法的时间复杂度与空间复杂度(考研笔记)

首先我们要知道,算法的时间复杂度是在算法运行之前,预估算法时间开销T(n)与问题规模n的关系(T表示time),分析一个算法的时间复杂度的时候,最重要的就是同n来表示出时间开销T。接下来我们用一个小例子来进行理解:

在《复仇者联盟4》中的一个片段,父亲对女儿说“我爱你1000遍”,女儿回答说“我爱你3000遍”那么我们来设计一个算法来实现“表白爱你n遍”


#include <stdio.h>
void loveyou(int n){//n为问题规模
	int i=1;
	while(i<=n)
	{
		i++;//每次+1
		printf("I love you %d\n",i);
	}
	printf("I love you more than %d\n");
}
int main()
{
loveyou(3000);
   return 0;
}

我们来分析一下,其中的代码分别运行来几次

 在上面的例子中,时间复杂度的公式还是相对简单的,但是对于不同的情况,公式越发复杂时,我们无法通过公式对其复杂度进行判断,接下来我们来思考:

问题1:是否可以忽略表达式中的某些部分?
问题2:如果有好几千行代码,按这种方法需要一行一行数?

通过以上问题的思考,我们得到以下结论:

在问题1中:
当n足够大时,我们可以只考虑阶数高的部分,用O(f(n))表示,O的含义是T(n)的数量级,f(n)表示执行次数,其余部分忽略,公式如下:

 接下来我们看乘法中的举例,该例子中,相加两项哪一个阶数更大呢?
需要用到以下公式:

通过以下的函数表达式还能够更直观的看出其对应关系,我们可以用“常对幂指阶”这样的口诀进行记忆

在问题2中:
1.顺序执行的代码只会影响常数项,可以忽略。
2.只需要挑循环中的一个基本操作分析它的执行次数与n的关系即可
3.当有嵌套循环时,比如内层循环执行n的2次方次,外层循环执行n次,我们只需要保留最高阶的部分即可,即只需要关注最深层循环循环了几次

接下来我们来做一下相关练习:

练习1:

#include <stdio.h>
void loveyou(int n){//n为问题规模
	int i=1;
	while(i<=n)
	{
		i=i*2;//每次翻倍
		printf("I love you %d\n",i);
	}
	printf("I love you more than %d\n");
}
int main()
{
loveyou(3000);
   return 0;
}

练习2:

#include<stdio.h>
void loveyou(int flag[], int n)
{
	for (int i = 2; i < n;i++)
	{
		if (flag[i]==n)
		{
			printf("第%d次找到",i+1);
			break;
		}
	}
}
int main() 
{
	int flag[5] = { 1,4,3,5,2 };
	loveyou(flag, 5);
	return 0;
}

 

我们将上面的代码展开分析,在定义的函数中定义了一个数组和n,在数组中,n的位置不确定,我们来查找n的位置,有三种情况,截图中已给出,在这三种情况下我们来计算时间复杂度,通过这个题目我们需要知道的是,在n不确定的情况下,我们要将其分开讨论。(代码给出的样例令n=5进行运行)

知识汇总:

 

空间复杂度考察相对较少也相对简单,这里将知识框架汇总如下:

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值