遞歸迭代的應用比較
數組求和問題
計算任意n個整數之和。
使用不同的算法求和,比較優劣。
典型算法
int Sum_Array_Claassical(int A,int n){
int sum=0;
for(int i=0;i<n;i++)
sum+=A[i];
return sum;
}
該算法複雜度:
線性遞歸
遞歸:減而治之,將大問題分解成一個小的子問題和另一個稍大的問題,一步一步自頂向下分解稍大問題,最終解決問題。
int Sum_Array_Recursion(int A[],int n){
return (n<1) ? 0 : Sum_Array_Recursion(A,n-1)+A[n-1];
}
複雜度分析:
1)遞歸跟蹤分析:檢查每個實例,累計時間。
Sum(A,n)->Sum(A,n-1)->Sum(A,n-2)->…->Sum(A,1)->Sum(A,0)
因此
2)遞推方程分析:由遞歸關係求複雜度遞推方程。
遞歸基:Sum(A,0) =>T(0)=O(1)
遞推方程:
由以上可知:T(n)=O(n)
尾遞歸(拓展)
尾遞歸實際就是線性迭代。參考CSDN上的一篇博客:淺析線性遞歸和尾遞歸
二分遞歸
實質就是將數組逐級分解到單個元素,再將單個元素返回求和累加,注意最後的return
語句的右半部分的起始序號必須加1,否則會進入死循環。
int Sum_Array_Dichotomy(int A[],int lo,in hi){
if(lo==hi) return A[lo];
int mi=(lo+hi)>>1;//右移一位相當於除2,移位的速度比除法快
//return (sum_Array_Dichotom(A,lo,mi) + sum_Array_Dichotom(A,mi,hi));
//以上語句有邏輯錯誤,遞歸進入死循環,在計算右半部分時必須要把起始序號加1.
return Sum_Array_Dichotomy(A,lo,mi)+Sum_Array_Dichotomy(A,mi+1,hi);
}
數組倒置
比較不同版本的數組倒置算法,統一接口 void reverse(int *A,int lo,int hi).
遞歸版
//核心部分
if(lo<hi){
swap(A[lo],A[hi]);
reverse(lo+1,hi+1)
}
迭代版
//迭代原始版
next;
if(lo<hi){
swap(A[lo],A[hi]);
lo++;
hi--;
goto next;
}
//迭代精簡版
while(lo<hi)
swap(A[lo++],A[hi++]);