游戏中的算法:算法的时间复杂度

作为学渣出生的程序员,在面试的时候被面试官问道:什么是时间的复杂度?
我:时间复杂度就是一个方法运行的大概时间!(虽然不懂,但是这个还是知道的)
面试官:它是怎么计算的?
我:看过,但是没看懂(汗汗–!)
面试官:这都看不懂?

我还能说啥?在面试之前,专门找过相关的文章学习,但是,真的没看懂!!!
入职后,打算认真的研究以下算法的复杂度,也记录一下的成长历程!!!

同一个问题,有不同的解决方法,有的方法快,有的方法慢。算法与此相同,而一个算法质量将影响到算法乃至整个程序的效率。

一个算法的好坏主要是从时间复杂度空间复杂度来衡量的。
时间复杂度:
算法执行所消耗的时间,理论上计算不出来的,但我们知道哪个个算法中语句执行次数越多,它花费时间也就越多。一个算法中的语句执行次称为语句频度或时间频度,记为T(n)。而算法的时间复杂度也就指执行算法所需要的计算工作量。
T(n) 即为一个函数,n是一个自变量,也就以n为自变量组成的函数
n称为问题的规模,当n不断变化时,T(n)也不会变化。

时间复杂度通常用大写字母O来表示,O表示法有以下规则:
1.忽略常数项
表达式:O© = O(1) 例:O(10) = O(1)
例如:T(n)= n+50 表示一个计算运行时间的算法,当n=1024时,此表达式的常数项 对运行时间的影响仅为4.8% ( 50/n)
2.忽略常数因子
表达式:O(cT) = cO(T) = O(T) 例:O(10n) = O(n) (c为常数)
例如:T(n)=n2(1) 和 T(n) = 10n(2) 两个运行时间的算法,当(1)中的n大于10 时,(1)就会大于(2)。
3.忽略低阶相的因子
表达式:O(T1) + O(T2) = max(O(T1),O(T2)) 例:O(n)+O((n2) = O(n2)
例如:T(n) =n^2+n 是一个运行时间的算法,当n为1024时,表达式中的低阶项因子的 值已经占不到运行时间的0.1%。

为什么?看这个例子:
有时间算法: T(n)=3n2+10n+10
则时间复杂度为:
O(T(n)) = O(3n2+10n+10) = O(3n2) = O(n2)

当n = 10 时:
3n2/T(n) = 73.2%
10n/T(n) = 24.4%
10/T(n) = 2.4%

当 n=100时:
3n2/T(n) =96.7%
10n/T(n) = 3.2%
10/T(n) = <0.1%
可以看到n2占据了几乎整个运行时间。

按数量级递增,常见的时间复杂度:
常数阶:O(1) 从一个数据集中获取第一个元素
对数阶:O(log2n) 将一个数据集分成两半,然后将分开的每一半再分成两半,一次类推(以2为底n的对数)
对数:如果x^2=n ,那么2就为以x为底n的对数。也就对求幂的逆运算
线性阶:O(n) 遍历一个数据集
线性对数阶:O(nlog2n) 将一个数据集分成两半,然后将分开的没一半再分成两半,依次类推,再此过程中同时遍历每一半数据
平方阶:O(n^2) 遍历一个数据集中每个元素的同时遍历另一个数量级相同的数据集
指数阶:O(2^n) 为一个数据集生成其可能的所有子集
阶乘阶:O(n!) 为一个数据集生成其可能的所有排列组合
随着问题规模n的不断增大,上述时间复杂度不断增大,算法的执行效率越低。
如图:
在这里插入图片描述
时间复杂度怎么分析的呢?
算法所耗的时间=算法中每条语句的执行时间之和
每条语句的执行时间=语句执行的次数(频度)*语句执行一次所需的时间。
每条语句执行的时间取决与机器的指令性能,速度以及编译所产生的代码质量等等因素,所以通常假设每条语句执行一次所需要的时间为1。
最终一个算法的时间耗费为:
时间 = 所有语句的频度之和

例如:求冒泡排序的时间复杂度

function BubbleSort(list)
	for i = 1,table.getn(list) - 1 do		            
		for j = 1,table.getn(list) - 1 - i do		   	 
			if list[j] > list[j+1] then							
				list[j],list[j+1] = list[j+1],list[j]
			end
		end
	end
end

在冒泡排序算法中,总共有两个for循环,分别用1和 2 来标识,
假设,我们传入的待排数组的长度为n,那么第一层循环需要执行n-1次(其实需要执行n-1+1次,因为for语句和额外比较一次来确定是否需要继续循环)。
第二层循环执行为:
i=1,n’ = n-1,
i=2, n‘ = n-2

i = n-1-1,n’ = n-(n-1-1)
明显点,就是带入一个数,假设n = 5
那就是
5
4
3
2
1
那么明显就是等差序列了,等差序列求和公式
(首项+末项)*项数/2 = (n+1)n/2 = (n(n+1))/2
根据以上:
T(n) = (n2+n)/2
然后根据O表示法:
1.忽略常数项
2.忽略常数系数
3.忽略最低阶
那么O(T(n)) = O(n2)

扫描二维码关注公众号,回复: 10193759 查看本文章

在例如:选择排序法:

function SelectionSort(t)
	local pos = 1;
	for i=1,#t do
		pos =i;
		for j=1+i,table.getn(t) do
			if t[j] < t[pos] then
				pos = j;
			end
		end
		t[pos],t[i] = t[i],t[pos]
	end
end

首层for循环 需要执行n次,需要执行2,3,4,5,6…n也是等差序列求和,所以最坏的时间复杂度为O(n2)

空间复杂度:
空间复杂度是指算法在计算机内执行时所需储存空间的度量。计算S(n) = O(f(n))
算法执行期间所需要的存储空间包含三个部分:
1.算法程序所占的空间
2.输入的初始数据所占的存储空间
3.算法执行过程中所需要的额外空间。

发布了28 篇原创文章 · 获赞 18 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_18192161/article/details/89461127