鏈表元素求和的僞遞歸優化

 

鏈表元素求和的僞遞歸優化

遞歸程序優化的一種廣泛採用的技術是將遞歸程序轉換爲尾遞歸程序。所謂尾遞歸程序,是指程序僅僅在程序的最後一條語句才調用自身的程序。對於這類程序,已經開發出強有力的編譯技術來加快程序的執行速度。舉一個簡單的例子來說明將遞歸程序轉化爲尾遞歸程序的思想,該程序用於統計一個鏈表中各項元素值的和,通常的遞歸程序爲:
// Program ListSum_0
typedef struct tagList
{
         int     value;
         struct tagList *next;
}       List;
 
int EvalListSum(List *L)
{
         if (L == (List *)NULL)       return 0;
         return L->value + EvalListSum(List->next);              
}
看起來,EvalListSum是程序體中的最後一條語句,實際上不是這樣,最後一條執行語句爲執行加法操作的語句,如果將程序表示爲下面的形式將更加清晰:
// Program ListSum_1
int EvalListSum(List *L)
{
         int PartSum;
 
         if (L == (List *)NULL)       return 0;
         PartSum = EvalListSum(List->next);
         return L->value + PartSum;
}
上述程序可以改進爲尾遞歸程序,相應的函數爲:
// Program ListSum_2
int EvalListSum(List *L)
{
    return EvalListSum(L, 0);
}
 
int EvalListSum0(List *L, int PartSum)
{
         if (L == (List *)NULL)       return PartSum;
         PartSum +=L->value;
         return EvalListSum1(L->next, PartSum);
}
函數的第二個參量用於記錄部分和,函數的設計思想爲:
(1) 當表爲空時,部分和即最終結果;
(2) 若表不空,部分和需加上當前表元素的值,將它們的和作爲新的部分和來進一步調用EvalListSum0。
(3) 在函數的初始調用中,PartSum=0,爲了避免函數的調用者過多涉及函數設計的細節,可以繼續使用EvalListSum作爲原型提供給用戶使用。
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章