时间复杂度的计算
大学时期数据结构关于时间复杂度的东西一直没有搞懂,今天抽出来一部分时间拿来研究,居然看懂了,可见能力也重在积累,下面分享一下自己的学习历程
例子:
(1)
for( i=1;i<=n;i++ ) for( j=1;j<=n;j++ ) n++;
(2)
for(i=1;i<=n;i++) for(j=i;j<=n;j++) s++;
(3)
for(i=1;i<=n;i++) for(j=1;j<=i;j++) s++;
(4)
i=1; while (i<=n) i=i*2;
现在我们一个一个分析
(1)外循环执行了n次内循环执行了n次所以时间复杂度是n*n(这里用乘法想必不用解释了)。
(2)代码s++经过循环第一次执行了n次,第二次执行了n-1次。。。第n次执行0次(n-n),所以加起来(n+n-1+n-2+...+1)≈(n^2)/2,所以时间复杂度为n^2(时间复杂度不考虑系数)。
(3)与2基本相同(1+2+3+...+n)≈(n^2)/2,时间复杂度也是n^2。
(4)这里先分析一下:假设n=4,执行2=1*2 -- 4=2*2 假设n=8,执行3次 假设n=16 执行4次 把数据拿出出来分析下不难发现2^执行次数 = n 所以时间复杂度是log2n(以2为底),逻辑思维稍微强一点可以直接得出公式。
下面进行实战
二分查找(用php实现,下同)
function getValue($num,$arr) { //查找数组的中间位置 $length=count($arr); $start=0; $end=$length; $middle=floor(($start+$end)/2); //循环判断 while($start>$end-1) { if($arr[middle]==$num) { return middle+1; }elseif($arr[middle]<$num) { //如果当前要查找的值比当前数组的中间值还要打,那么意味着该值在数组的后半段 //所以起始位置变成当前的middle的值,end位置不变。 $start=$middle; $middle=floor(($start+$end)/2); }else{ //反之 $end=$middle; $middle=floor(($start+$end)/2); } } return false; }
先分析下代码,先去中间的数(头+末尾)/2取整,然后再以进行比较比这个大的取右边的数集合,小的话取左边的数集,然后再以此为基础取中间的数然后再比较。第一次剩余n/2个,第二次剩余n/4 (注 4=2^2).......第n次剩余n/2^k 因为剩余的个数应该大于1 所以n/2^k>1 所以时间复杂度为log2n,(是以2为底,n的对数)。
(待完成)