確定遞歸函數的參數和返回值:
確定哪些參數是遞歸的過程中需要處理的,那么就在遞歸函數里加上這個參數, 並且還要明確每次遞歸的返回值是什么進而確定遞歸函數的返回類型。
我認為這個是最重要的,這個想明白了,那么單層遞歸的邏輯就很自然的出來了
確定終止條件:
寫完了遞歸算法, 運行的時候,經常會遇到棧溢出的錯誤,就是沒寫終止條件或者終止條件寫的不對,操作系統也是用一個棧的結構來保存每一層遞歸的信息,如果遞歸沒有終止,操作系統的內存棧必然就會溢出。
確定單層遞歸的邏輯:
確定每一層遞歸需要處理的信息。在這里也就會重復調用自己來實現遞歸的過程。
以前序遍歷為例
- 確定遞歸函數的參數和返回值:
因為要打印出前序遍歷節點的數值,所以參數里需要傳入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;
}
};
你學廢了么?