从大一学编程起,就对算法很是敬畏,大二开的算法课,老师也只是照着书念念,当时也是刚对编程入门吧,基本语法和程序组织结构才刚刚清楚那种,所以除了基本几样查找算法,其他的基本没学~~~学渣不仅学的晚,还学的慢。也不得不吐槽下,祖国母亲的应试教育真是.....高中弄的也是没得时间来捣鼓电脑,更别谈接触编程了=、=,基本每周就一次玩电脑的机会,干嘛?打dota啊!
吐糟完毕,我还是希望以后孩子们能早点接触编程,早点好啊。好多概率和原理真的是要时间来发酵,长期积累的知识多了,就会有顿悟的那一天,那一天越早越好....
从概念开始,语句频度:是指该语句重复执行的次数。一个算法的时间耗费就是该算法中所有语句频度的和。
语句频度 (1)for (i = 0; i < n; i++){ n+1 (2) for(j = 0; j < n; j++){ n(n + 1) (3) a++; n*n (4) for(k = 0; k < n; k++){ n*n*(n + 1) (5) c++; n*n*n } } }
[分析]:语句(1)中 i 从0到n,i = n时才终止执行,所以一共执行过n+1次,同时它下面的循环体执行了n次。
语句(2)本身循环n+1次,同时作为语句(1)的循环体也执行了n次。
语句(3)作为前两个语句的循环体,易知执行了n*n次。
语句(4)同理,本身多出k = n那次,一共执行了n*n*(n+1)次。
语句(5)三个循环体下面,执行了n*n*n次。
所以频度之和:f(n) = (n+1) + n(n+1) + n*n + n*n*(n+1) + n*n*n。
算法的时间复杂度
T(n) = O(f(n))
对于算法分析,关心的是算法中语句总的执行次数f(n),分析f(n)随n的变化情况并确定T(n)的数量级。O表示数量级。上面的例子中,T(n)与n的立方数量级相同,O(n立方)是该算法的渐近时间复杂度。
也就是,对于时间复杂度,我们不必算出一个准确的值,我们只要确定它的最高数量级,就能估算出这个算法的好坏。当然,对于T(n1)=100*n*n,T(n2)=50*n*n*n,n=20是个临界点。所以根据算法的可读性,健壮性,时间复杂的高低,问题规模大小来综合权衡,选出合适的算法才是正解。
写不动了。。tag下~
算法的空间复杂度
这个比较简单,例如将数组倒序存储的两种算法。
/* */ for(int i=0; i< n; i++){ b[i] = a[n-i-1]; } for(int i=0; i<n; i++){ a[i] = b[i]; }
这个算法用到一个辅助数组b[ ],空间复杂度为O(n)
/* */ for(int i=0; i< n/2; i++){ t = a[i]; a[i] = a[n-i-1]; a[n-i-1] = t; }
这个算法只用到一个变量t,空间复杂度为O(1)