1. 程式人生 > 實用技巧 >遞迴三要素

遞迴三要素

確定遞迴函式的引數和返回值:

確定哪些引數是遞迴的過程中需要處理的,那麼就在遞迴函式里加上這個引數, 並且還要明確每次遞迴的返回值是什麼進而確定遞迴函式的返回型別。
我認為這個是最重要的,這個想明白了,那麼單層遞迴的邏輯就很自然的出來了

確定終止條件:

寫完了遞迴演算法, 執行的時候,經常會遇到棧溢位的錯誤,就是沒寫終止條件或者終止條件寫的不對,作業系統也是用一個棧的結構來儲存每一層遞迴的資訊,如果遞迴沒有終止,作業系統的記憶體棧必然就會溢位。

確定單層遞迴的邏輯:

確定每一層遞迴需要處理的資訊。在這裡也就會重複呼叫自己來實現遞迴的過程。

以前序遍歷為例

  • 確定遞迴函式的引數和返回值:
    因為要打印出前序遍歷節點的數值,所以引數裡需要傳入vector用於放置節點的數值,除了這一點就不需要在處理什麼資料了也不需要有返回值,所以遞迴函式返回型別就是void,程式碼如下:
void traversal(TreeNode* cur, vector<int>& vec)
  • 確定終止條件:
    在遞迴的過程中,如何算是遞迴結束了呢,當然是當前遍歷的節點是空了,那麼本層遞迴就要要結束了,所以如果當前遍歷的這個節點是空,就直接return,程式碼如下:
if (cur == NULL) return;
  • 確定單層遞迴的邏輯
    前序遍歷是中左右的循序,所以在單層遞迴的邏輯,是要先取中節點的數值,程式碼如下:
vec.push_back(cur->val);    // 中
traversal(cur->left, vec);  // 左
traversal(cur->right, vec); // 右

單層遞迴的邏輯就是按照中左右的順序來處理的,這樣二叉樹的前序遍歷,基本就寫完了,在看一下完整程式碼:

class Solution {
public:
    void traversal(TreeNode* cur, vector<int>& vec) {
        if (cur == NULL) return;
        vec.push_back(cur->val);    // 中
        traversal(cur->left, vec);  // 左
        traversal(cur->right, vec); // 右
    }
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> result;
        traversal(root, result);
        return result;
    }
};

你學廢了麼?