數據結構學習筆記(緒論二)

遞歸迭代的應用比較

數組求和問題

計算任意n個整數之和。
使用不同的算法求和,比較優劣。

典型算法

int Sum_Array_Claassical(int A,int n){
    int sum=0;
    for(int i=0;i<n;i++)
        sum+=A[i];
    return sum;
}

該算法複雜度:T(n)=O(n)

線性遞歸

遞歸:減而治之,將大問題分解成一個小的子問題和另一個稍大的問題,一步一步自頂向下分解稍大問題,最終解決問題。

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)

因此 T(n)=O(n)

2)遞推方程分析:由遞歸關係求複雜度遞推方程。
遞歸基:Sum(A,0) =>T(0)=O(1)
遞推方程:
T(n)=T(n1)+O(1)=T(n2)+O(1)+O(1)=T(n3)+O(1)+O(1)+O(1)=......=O(1)+...+O(1)+O(1)+O(1)=nO(1)=O(n)

由以上可知: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);
}

T(n)=O(n)

數組倒置

比較不同版本的數組倒置算法,統一接口 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++]);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章