天天看點

尾遞歸

線性表的兩種存儲結構:順序存儲存儲密度大,邏輯上相鄰元素在實體上也是相鄰的,不友善插入和查找操作。

 環形隊列:邏輯上把數組看成環形的,解決了“假溢出現象”。

 棧:編譯器管理,向低位址拓展的資料結構,是一塊連續的記憶體空間。

堆:程式員管理,向高位址拓展的資料結構,是不連續的記憶體空間。

尾遞歸:核心就是通過參數傳遞結構,達到不壓棧的目的。尾遞歸函數的特點是在回歸過程中不用做任何操作。

當編譯器檢測到一個函數調用是尾遞歸的時候,它就覆寫目前的活動記錄而不是在棧中去建立一個新的。

補充:當C程式中調用了一個函數時,棧中會配置設定一塊空間來儲存與這個調用相關的資訊,每一個調用都被當作是活躍的。棧上的那塊存儲空間稱為活躍記錄或者棧幀。

棧幀由5個區域組成:輸入參數、傳回值空間、計算表達式時用到的臨時存儲空間、函數調用時儲存的狀态資訊以及輸出參數。

當你用的函數是尾遞歸的時候,比如下面這個程式,如果你把它也存入棧幀裡面,你會發現當你回來調用的時候,它不會做什麼事情,因為它需要做的事情已經在最開始調用的時候做了。是以後面的調用函數需要的棧幀直接覆寫在上一次的調用的棧幀。

int facttail(int n, int res)
{
    if (n < 0)
        return 0;
    else if(n == 0)
        return 1;
    else if(n == 1)
        return res;
    else
        return facttail(n - 1, n *res);
}      
int fact(int n) {
    if (n < 0)
        return 0;
    else if(n == 0 || n == 1)
        return 1;
    else
        return n * fact(n - 1);
}      

繼續閱讀