当前位置:   article > 正文

浅识数据结构之时间复杂度

浅识数据结构之时间复杂度
P. S.:以下代码均在VS2019环境下测试,不代表所有编译器均可通过。
P. S.:测试代码均未展示头文件stdio.h的声明,使用时请自行添加。

  

前言


  在了解时间复杂度之前,先向大家科普一个大环境知识。
  当今时代的科学技术,让计算机在面对执行指令是可以以一个夸张的速度进行执行,也就是我们口中对于计算机设备的频率,下面引入一段代码:
void test01()
{
	int begin = clock();
	int x = 0;
	for (int i = 0; i < 100000000; i++)
	{
		++x;
	}
	int end = clock();
	int time = end - begin;
	printf("x = %d\n", x);
	printf("time = %d ms\n",time);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

在这里插入图片描述


  在如上代码中,我们看到即使我们需要将这个循环执行一亿次,但在计算机设备的加持下,不到一秒就出了结果,可见其执行效率之高。


一. 时间复杂度

1.1 时间复杂度的概念


  时间复杂度的定义:
  在计算机科学中,算法的时间复杂度是一个函数,它定量描述了该算法的运行时间。一个算法执行所耗费的时间,从理论上说,是不能算出来的,只有你把你的程序放在机器上跑起来,才能知道。但是我们需要每个算法都上机测试吗?是可以都上机测试,但是这很麻烦,所以才有了时间复杂度这个分析方式。一个算法所花费的时间与其中语句的执行次数成正比例,算法中的基本操作的执行次数,为算法的时间复杂度。
  更加通俗的来讲就是:找到某条基本语句与问题规模N之间的数学表达式,就是算出了该算法的时间复杂度。

1.2 时间复杂度如何计算


  我们照样以实例作为参考:
// 请计算一下Func1中++count语句总共执行了多少次?
void Func1(int N)
{
	int count = 0;
	for (int i = 0; i < N; ++i)
	{
		for (int j = 0; j < N; ++j)
		{
			++count;
		}
	}
	for (int k = 0; k < 2 * N; ++k)
	{
		++count;
	}
	int M = 10;
	while (M--)
	{
		++count;
	}
		printf("%d\n", count);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

  我们将它转化为一个数学表达式

                    F(N) = N² + 2 × N + 10

  在计算时间复杂度时我们将数学表达式中的影响最大的部分摘下来,并将复杂度写作O( N² )


  这时就会有同学问了,上面不是讲到复杂度时基本语句的执行次数的问题吗?为什么上面代码中 count 和 M的定义语句不添加到其中呢?
  在前言中我们讲到,如今的计算机设备执行速率已经十分快速,对于其中的一些细枝末节的语句执行次数我们可以忽略不计,除非他的数量大到可以占到总体的一半以上,否则不添加到计算当中,此时我们就可以引入数学中的极限思想,当上述表达式中N趋近于无穷时,看其最高阶项,其他的在最高阶面前都可忽略不计,因为它太太太小了。

1.3 时间复杂度如何表示


  大O符号(Big O notation):是用于描述函数渐进行为的数学符号。
  推导大O阶方法:

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

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

  3、如果最高阶项存在且不是1,则去除与这个项目相乘的常数。得到的结果就是大O阶。


  另外有些算法的时间复杂度存在最好、平均和最坏情况:

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

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

  最好情况:任意输入规模的最小运行次数(下界)

  例如:在一个长度为N数组中搜索一个数据x

  最好情况:1次找到

  最坏情况:N次找到

  平均情况:N/2次找到

  在实际中一般情况关注的是算法的最坏运行情况,所以数组中搜索数据时间复杂度为O(N)。




二. 常见复杂度举例

示例复杂度名称
5201314O( 1 )常数阶
3n + 4O( n )线性阶
3n^2 + 4n + 5O( n² )平方阶
3 log( 2 ) n + 4O( log n )对数阶
3n*log( 2 ) n + 4O( n*log n )nlogn阶
n^3 + n^2 + 4O( n^3 )立方阶
2^nO( 2^n )指数阶

  有意思的是,在数据结构学习中,复杂度log N一般代表的都是以 2 为底的对数,只有当底数为 2 时才可以省略,反之不可以省略,但不是二的情况很少出现,因为其实用价值并不高。


三. 结语


  十分感谢您观看我的原创文章。
  本文主要用于个人学习和知识分享,学习路漫漫,如有错误,感谢指正。
  如需引用,注明地址。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/504483
推荐阅读
相关标签
  

闽ICP备14008679号