分治策略:分解的是規模,比如數10億硬幣,分成4萬個人區完成,這樣,問題不會改變,改變的是問題的規模
下面是不用遞歸求階乘的方式
int fun(int n)
{
int sum=1;
for(int i=1;i<=n;i++)
{
sum=sum*(sum+1);
}
}
void main{
int n,sum;
cin>>n;
sum=fun(n);
sum=fac(n);
}
這是遞歸的算法
int fac(n)
{
if(n<=1) return 1;
else return fac(n-1)*n;
}
fun(n)的時間複雜度是O(n),空間複雜度爲O(1)是一個定值,不會隨着i的範圍變化開闢更大的內存空間。fac(n)的時間複雜度是O(n),空間複雜度爲O(n)。所以在能用循環的時候儘量少使用遞歸。雖然遞歸的代碼簡潔。
系統默認給每個程序分配的棧大小爲1M,有死循環之說,但是沒有無限遞歸之說,如果遞歸要使用很多次時,要注意超出範圍。
上圖爲一個無限遞歸的例子
下面是二分法查找的使用循環的操作
#define error -1
int binaryfindvalue(Seqlist&seq, const elemtype val)
{
int left = 0;
int right = seq.cursize-1;
int mid;
while (1)
{
if (left < right)
{
return error;
}
mid = (left + right) / 2;//如果擔心數據範圍超過int的最大範圍
//這裏的式子改爲(right -left+1)/2+left
if (val < seq.data[mid])
{
right = mid - 1;
}
else if (val > seq.data[mid])
{
left = mid + 1;
}
else return mid;
}
}
如果我們使用遞歸的做法,程序如下
int C_binaryfindvalue(Seqlist&seq, const elemtype val, int left, int right)
{
if (left < right)
{
return error;
}
int mid = (right - left + 1) / 2 + left;
if (val < seq.data[mid])
{
mid=C_binaryfindvalue(seq, left, mid - 1, val);
}
else if (val > seq.data[mid])
{
mid=C_binaryfindvalue(seq, mid+1, right, val);
}
else
{
while (mid>left&&seq.data[mid] == seq.data[mid - 1])//這樣是如果數據中存在多個重複的數,需要輸出第一位時的操作
{
mid--;
}
}return mid;
}