《数据结构与算法分析》学习笔记(二)——算法分析
一、對(duì)算法分析方法的最簡(jiǎn)單的理解和使用方法
1、首先大家可能一般會(huì)被那些數(shù)學(xué)的概念搞暈,其實(shí)簡(jiǎn)單理解下來(lái),就是假設(shè)任何語(yǔ)句執(zhí)行的效率都是一樣的,所以設(shè)定每一個(gè)語(yǔ)句的執(zhí)行時(shí)間都是一個(gè)時(shí)間單位,那么只要計(jì)算這個(gè)程序到底執(zhí)行了多少語(yǔ)句,就可以算出其時(shí)間復(fù)雜度。
2、其次就是我們要明白,我們是個(gè)估算,所以可以進(jìn)行化簡(jiǎn),明顯我們可以忽略那些相對(duì)來(lái)說(shuō)低階的項(xiàng),只分洗最高階項(xiàng)。然后主要就是有這些常見(jiàn)的法則:
(1)FOR循環(huán)
一次for循環(huán)的運(yùn)行時(shí)間至多是該for循環(huán)內(nèi)語(yǔ)句的運(yùn)行時(shí)間乘以迭代次數(shù)。
(2)嵌套的FOR循環(huán)
肯定是計(jì)算最內(nèi)層循環(huán)語(yǔ)句的執(zhí)行次數(shù),然后再乘以所以循環(huán)的迭代次數(shù)。
(3)整個(gè)程序
其實(shí)找到循環(huán)迭代次數(shù)最多,嵌套最多的進(jìn)行計(jì)算就好。
3、當(dāng)然,我們計(jì)算的只是大概值,而且為了計(jì)算的簡(jiǎn)便,我們一邊進(jìn)行適當(dāng)?shù)姆糯?#xff0c;即只考慮最壞最壞的情況,算出其時(shí)間復(fù)雜度即可。
二、最大子序列
書中通過(guò)4種不同的解法來(lái)進(jìn)一步強(qiáng)化我們應(yīng)該如何計(jì)算時(shí)間復(fù)雜度,小白我也好好學(xué)習(xí)了下,在此寫下學(xué)習(xí)筆記。
題目:算出一個(gè)整數(shù)序列中最大的子序列的值。
算法一:
int MaxSubsequenceSum1(const int A[],int N)
{
int thisSum , MaxSum;
MaxSum=0;
for (int i =0; i<N; i++)
{
for (int j=i; j<N; j++)
{
thisSum=0;
for (int K =i; K<=j; K++)
{
thisSum+=A[K];
}
if(thisSum>MaxSum)
{
MaxSum=thisSum;
}
}
}
??
if(MaxSum==0)
{
int i;
for(i=0;i<N;i++)
{
if(A[i]!=0)
break;
}
if(i!=N)
{
int Max=A[0];
for(int j=0;j<N;j++)
{
if(A[j]>Max)
{
Max=A[j];
}
}
MaxSum=Max;
??
}
}
?
??
??
return MaxSum;
??
?
}
我們可以看出其最大的for循環(huán)有三重,而且最壞的可能迭代次數(shù)都是N,所以我們可以很容易的得出,此算法的時(shí)間復(fù)雜度為O(N^3),其中資源最明顯的浪費(fèi)就在重復(fù)計(jì)算了從低i到第k的子序列的值,所以算法二便是進(jìn)行了簡(jiǎn)單的修改。
算法二:
int MaxSubsequenceSum2(const int A[],int N)
{
int thisSum,MaxSum;
MaxSum=0;
for (int i=0; i<N; i++)
{
thisSum=0;
for (int j=i; j<N; j++)
{
thisSum+=A[j];
if(thisSum>MaxSum)
{
MaxSum=thisSum;
}
}
}
??
??
if(MaxSum==0)
{
int i;
for(i=0;i<N;i++)
{
if(A[i]!=0)
break;
}
if(i!=N)
{
int Max=A[0];
for(int j=0;j<N;j++)
{
if(A[j]>Max)
{
Max=A[j];
}
}
MaxSum=Max;
??
}
}
??
??
return MaxSum;
?
?
}
其實(shí)改變的地方即使采用的累加的策略而已,但卻使效率大大的提高了,所以這里也是提高算法效率的一個(gè)小小的技巧,即盡力減少不必要的計(jì)算,盡量利用現(xiàn)有的計(jì)算結(jié)果。
算法三:
int Max3(const int a,const int b,const int c)
{
int temp = (a>b)?a:b;
temp=(temp>c)?temp:c;
return temp;
}
?
?
?
int MaxSubSum(const int A[],int Left,int Right)
{
int MaxLeftSum,MaxRightSum;
int MaxLeftBorderSum,MaxRightBorderSum;
int LeftBorderSum,RightBorderSum;
??
if(Left==Right)
{
if(A[Left]>0)
return A[Left];
else
return 0;
}
??
int center=(Right+Left)/2;
??
MaxLeftSum=MaxSubSum(A, Left, center);
MaxRightSum=MaxSubSum(A, center+1, Right);
??
LeftBorderSum=MaxLeftBorderSum=0;
for(int i=center;i>=Left;i--)
{
LeftBorderSum+=A[i];
if(LeftBorderSum>MaxLeftBorderSum)
{
MaxLeftBorderSum=LeftBorderSum;
}
}
??
RightBorderSum=MaxRightBorderSum=0;
for(int i=center+1;i<=Right;i++)
{
RightBorderSum+=A[i];
if (RightBorderSum>MaxRightBorderSum)
{
MaxRightBorderSum=RightBorderSum;
}
}
??
return Max3(MaxLeftSum,MaxRightSum,MaxLeftBorderSum+MaxRightBorderSum);
??
}
?
int MaxSubsequenceSum3(const int A[],int N)
{
int MaxSum = MaxSubSum(A, 0, N-1);
??
if(MaxSum==0)
{
int i;
for(i=0;i<N;i++)
{
if(A[i]!=0)
break;
}
if(i!=N)
{
int Max=A[0];
for(int j=0;j<N;j++)
{
if(A[j]>Max)
{
Max=A[j];
}
}
MaxSum=Max;
??
}
}
?
return MaxSum;
?
}
?
這個(gè)算法使用了分治的思想,還有遞歸的思想,即把一個(gè)問(wèn)題不斷的分解成類似的規(guī)模更小的子問(wèn)題來(lái)解決,所以這里我們要求一個(gè)序列的最大子序列,其實(shí)就是求左半部分,有伴部分和中間部分的最大子序列,而求左半部分,后半部分的最大子序列顯然是將問(wèn)題的規(guī)模變小了,所以可以遞歸使用,直到剩下一個(gè)數(shù)的情況.而中間部分呢,則取左右兩邊,左邊從右往左,右邊從左往右的最大子序列。然后加起來(lái)作為中間部分的值,最后比較中間部分,左半部分,后半部分三部分的值就可以得到結(jié)果啦。
?
?
算法四:
int MaxSubsequenceSum4(const int A[],int N)
{
int thisSum,MaxSum;
thisSum = MaxSum=0;
??
for(int i=0;i<N;i++)
{
thisSum+=A[i];
if(thisSum>MaxSum)
{
MaxSum=thisSum;
}
else if(thisSum<0)
{
thisSum=0;
}
}
??
??
if(MaxSum==0)
{
int i;
for(i=0;i<N;i++)
{
if(A[i]!=0)
break;
}
if(i!=N)
{
int Max=A[0];
for(int j=0;j<N;j++)
{
if(A[j]>Max)
{
Max=A[j];
}
}
MaxSum=Max;
??
}
}
??
return MaxSum;
?
}
?
?
最后一個(gè)算法就比較牛逼啦,這個(gè)算法竟然只是N階的,大家可以想想這個(gè)算法的速度有多快,而且如果不考慮全是負(fù)數(shù)的情況的話,還可以做到隨時(shí)讀入,隨時(shí)釋放內(nèi)存的強(qiáng)大功能,在此深深膜拜一下。
?
轉(zhuǎn)載于:https://www.cnblogs.com/BlueMountain-HaggenDazs/p/3898352.html
總結(jié)
以上是生活随笔為你收集整理的《数据结构与算法分析》学习笔记(二)——算法分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Java开发微信支付实践
- 下一篇: 饥荒指令代码大全一览