数据结构——时间复杂度与空间复杂度

我们通常用时间复杂度和空间复杂度来衡量一个算法的复杂度,统称为算法的复杂度。

时间复杂度

时间复杂度实际就是一个函数,该函数计算的是执行基本操作的次数。

算法分析的分类

算法存在最好,平均,最坏情况:

1.最坏情况:任意输入规模最大运行次数(上界)。

2.平均情况:任意输入规模的期望运行次数。

3.最好情况:任意输入规模的最小运行次数,通常最好情况不会出现(下界)。

 

例如:在一个长度为N的线性表中搜索一个数x,

1.最好情况:1次比较

2.最坏情况:N次比较

3.平均情况N/2次比较

 

在实际中我们一般关注的都是算法的最坏运行情况,即输入规模为N,算法的最长运行时间。理由如下:

1.一个算法的最坏运行情况的运行时间是在任意输入下的运行时间上界。

2.对于某些算法,最坏的情况出现的较为频繁。

3.大体上看,平均情况和最坏情况一样坏

因此,一般情况下使用O渐进表示法来计算算法的时间复杂度。

 

O渐进表示法

一个算法总的执行次数是关于问题规模N的某个函数,记为f(N),N称为问题的规模。语句总的执行次数记为T(N),当N不断变化时T(N)也在变化,算法执行次数的增长速率和f(N)的增长速率相同。则有T(N)=O(f(N)),称O(f(N))为时间复杂度O的渐进表达法。

 

一般算法O(n)计算方法:

1.用常数1取代运行时间中所有的加法常数

2.在修改后的运行次数函数中,只保留最高介项。

3.如果最高阶项系数存在且不为1,则去除与这个项相乘的常数。

递归算法

时间复杂度:递归总次数*每次递归次数。

分治算法

时间复杂度:传统算法

如下二分查找递归算法的时间和空间复杂度:

数据结构——时间复杂度与空间复杂度_第1张图片

 

二分查找又称折半查找,满足数学公式:

n = 2^x即x = logn;

递归的次数和深度都是logn,每次所需的辅助空间都是常数级别的,

因此其时间复杂度为O(logn)

空间复杂度为O(logn)

 

如下二分查找分治算法的时间和空间复杂度:

循环的基本次数为logn,所以时间复杂度为O(logn).

由于辅助空间是常数级别的,所以空间复杂度为O(1).

 

如下 斐波那契的递归算法的时间和空间复杂度:

数据结构——时间复杂度与空间复杂度_第2张图片

 

循环的基本操作次数为n-1,辅助空间是n+1。所以:

时间复杂度O(2^n)

空间复杂度O(n)

 

如下 斐波那契的分治算法的时间和空间复杂度

循环的基本次数是n-1,所用的辅助空间是常数级别:

时间复杂度:O(n)

空间复杂度:O(1)

 

空间复杂度

 

函数中创建对象的个数关于问题规模函数表达式,一般情况下用O的渐进表示法表示。

忽略常数,用O(1)表示

递归算法的空间复杂度=递归深度N*每次递归所要的辅助空间。

 

如下二分查找以及斐波那契的分治算法的时间复杂度分别为:

 

如下二分查找以及斐波那契的分治算法的时间复杂度分别为:

 

int NonrecBinarySearch(char* arr,int len,int F)
{
	int left = 0;
	int right = len - 1;
	 
	while(right >= left)
	{
		int mid = (left + right)/2;
		if(arr[mid] == F)
		{
			return mid;
		}
		else if(arr[mid] > F)
		{
			right = mid - 1;
		}
		else
		{
			left = mid + 1;
		}
	}
	return -1;
}

 

 

 

 

 

 int RecBinarySearch(char* arr,int len,int F,int left,int right)
{
	while(right >= left)
	{
		int mid = (left + right)/2;
		if(arr[mid] == F)
		{
			return mid;
		}
		else if(arr[mid] > F)
			return RecBinarySearch(arr,len,F,left,mid-1);
		else
			return RecBinarySearch(arr,len,F,mid+1,right);
	}
	return - 1;
}

 

 

 

 

 

 

 

int RecBinarySearch(char* arr,int len,int F,int left,int right)
{
	while(right >= left)
	{
		int mid = (left + right)/2;
		if(arr[mid] == F)
		{
			return mid;
		}
		else if(arr[mid] > F)
			return RecBinarySearch(arr,len,F,left,mid-1);
		else
			return RecBinarySearch(arr,len,F,mid+1,right);
	}
	return - 1;
}

 

 

 




 

 

 

 

int nonrec_Fibonacci(int n)
{
   int i = 0;
   int f = 0;
   int f1 = 1;
   int f2 = 1;
   if(n <= 2)
	   return f1;
   else
   {
	   for(i = 3;i <= n;i++)
	   {   


		   f = f1 + f2;
		   f2 = f1;
		   f1 = f;
	   }
   }
   return f;
}

 

 

 

 

 

你可能感兴趣的:(C语言,数据结构)