时间复杂度和空间复杂度的计算

时间复杂度
1. 一般情况下,算法的基本操作重复执行的次数是模块n的某一个函数f(n),因此,算法的时间复杂度记做:T(n)=O(f(n))
分析:随着模块n的增大,算法执行的时间的增长率和 f(n) 的增长率成正比,所以 f(n) 越小,算法的时间复杂度越低,算法的效率越高。
2. 在计算时间复杂度的时候,先找出算法的基本操作,然后根据相应的各语句确定它的执行次数,再找出 T(n) 的同数量级(它的同数量级有以下:1,log(2)n,n,n log(2)n ,n的平方,n的三次方,2的n次方,n!),找出后,f(n) = 该数量级,若 T(n)/f(n) 求极限可得到一常数c,则时间复杂度T(n) = O(f(n))

例:算法:
则有 T(n) = n 的平方+n的三次方,根据上面括号里的同数量级,我们可以确定 n的三次方 为T(n)的同数量级
则有 f(n) = n的三次方,然后根据 T(n)/f(n) 求极限可得到常数c
则该算法的时间复杂度:T(n) = O(n^3) 注:n^3即是n的3次方。
3.for循环中容易计算的方法是:看看有几重for循环,只有一重则时间复杂度为O(n),二重则为O(n^2),依此类推,如果有二分则为O(logn),二分例如快速幂、二分查找,如果一个for循环套一个二分,那么时间复杂度则为O(nlogn)。
递归算法的时间复杂度:递归总次数*每次递归数

空间复杂度
类似于时间复杂度的讨论,一个算法的空间复杂度(SpaceComplexity)S(n)定义为该算法所耗费的存储空间,它也是问题规模n的函数。
一个算法的空间复杂度只考虑在运行过程中为局部变量分配的存储空间的大小,它包括为参数表中形参变量分配的存储空间和为在函数体中定义的局部变量分配的存储空间两个部分。若一个算法为递归算法,其空间复杂度为递归所使用的堆栈空间的大小,它等于一次调用所分配的临时存储空间的大小乘以被调用的次数(即为递归调用的次数加1,这个1表示开始进行的一次非递归调用)。
递归的空间复杂度:每次递归所开空间*深度

时间与空间复杂度的联系

对于一个算法,其时间复杂度和空间复杂度往往是相互影响的。当追求一个较好的时间复杂度时,可能会使空间复杂度的性能变差,即可能导致占用较多的存储空间;反之,当追求一个较好的空间复杂度时,可能会使时间复杂度的性能变差,即可能导致占用较长的运行时间。

1:实现二分查找算法的递归及非递归。(分析时间复杂度及空间复杂度) 


#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>


//非递归
//时间复杂度 O(log2 N)  空间复杂度O(1)
int binaryfind1(int a[], int key, int n)
{
	assert(n);
	int start = 0;
	int end = n ;
	while (start <= end)
	{
		int mid = start + ((end - start) >> 1);
		if (key < a[mid])
			end = mid - 1;
		else if (key>a[mid])
			start = mid + 1;
		else
			return a[mid];
	}
	return NULL;
}


//递归
//时间复杂度:O(log2 N)空间复杂度:O(log2N )

int binaryfind2(int a[], int start, int end, int key)
{
	if (start <= end)
	{
		int mid = (start + end)>>1;
		if (key == a[mid])
			return mid;
		else if (key<a[mid])
			return binaryfind2(a, start, mid - 1, key);
		else if (key>a[mid])
			return binaryfind2(a, mid + 1, end, key);
	}
	else
		return -1;
}


int main()
{
	int a[] = { 2,3,4,5,6,7 };
	//printf("%d\n",binaryfind1 (a, 2, sizeof(a) / sizeof(a[0])));
	printf("%d\n", binaryfind2(a,2,7,5));
   system("pause");
	return 0;
}
2:实现斐波那契数列的递归及非递归。(分析时间复杂度及空间复杂度)



#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

//递归算法
//(1)要想求解F(n),必须先计算F(n-1)和F(n-2),计算F(n-1)和F(n-2),又必须先计算F(n-3)和F(n-4).....以此类推,直至必须先计算F(1)和F(0),然后逆推得到F(n-1)和F(n-2)的结果,从而得到F(n)要计算很多重复的值,在时间上造成了很大的浪费,算法的时间复杂度随着N的增大呈现指数增长,时间的复杂度为O(2^n),即2的n次方。
(2)空间复杂度为O(n)

int fib1(int n)
{
	while (n < 2)
		return n;
	while (n >= 2)
		return fib1(n - 1) + fib1(n - 2);
}


//非递归
//(1)从n(>2)开始计算,用F(n-1)和F(n-2)两个数相加求出结果,这样就避免了大量的重复计算,它的效率比递归算法快得多,算法的时间复杂度与n成正比,即算法的时间复杂度为O(n).
(2)空间复杂度为O(1)

long long fib2(int n)
{
	int i = 0, f1 = 0, f2 = 1, f3 = 0;
	if (n < 2)
		return n;
	if (n >= 2)
	for (long long i = 2; i <= n; i++)
	{
		f3 = f1 + f2;
		f1 = f2;
		f2 = f3;
	}
	return f3;
}

int main()
{
	printf("%d\n",fib1(6));
	//printf("%d\n", fib2(6));
	system("pause");
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值