視頻講解:https://www.bilibili.com/video/BV1Wh411S7xt/?vd_source=a935eaede74a204ec74fd041b917810c
文檔講解:https://programmercarl.com/%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E9%80%92%E5%BD%92%E9%81%8D%E5%8E%86.html#%E5%85%B6%E4%BB%96%E8%AF%AD%E8%A8%80%E7%89%88%E6%9C%AC
力扣題目:https://leetcode.cn/problems/binary-tree-preorder-traversal/
https://leetcode.cn/problems/binary-tree-inorder-traversal/
https://leetcode.cn/problems/binary-tree-postorder-traversal/
其實遍歷就像卡哥講的一樣,分為3部分:
-
確定遞歸函數的參數和返回值: 確定哪些參數是遞歸的過程中需要處理的,那么就在遞歸函數里加上這個參數, 并且還要明確每次遞歸的返回值是什么進而確定遞歸函數的返回類型。
-
確定終止條件: 寫完了遞歸算法, 運行的時候,經常會遇到棧溢出的錯誤,就是沒寫終止條件或者終止條件寫的不對,操作系統也是用一個棧的結構來保存每一層遞歸的信息,如果遞歸沒有終止,操作系統的內存棧必然就會溢出。
-
確定單層遞歸的邏輯: 確定每一層遞歸需要處理的信息。在這里也就會重復調用自己來實現遞歸的過程。
拿這三道題舉例,首先我要輸入根節點,輸出遍歷數組和返回長度
其次是判斷如果輸入的根節點為空,我就結束遍歷
最后是我需要先遍歷左子樹,在賦值,再遍歷右子樹。(中序遍歷)。確定好順序即可
前序遍歷:中左右
中序遍歷:左中右
后序遍歷:左右中
//前序遍歷:
void preOrder(struct TreeNode* root, int* ret, int* returnSize) {if(root == NULL)return;ret[(*returnSize)++] = root->val;preOrder(root->left, ret, returnSize);preOrder(root->right, ret, returnSize);
}int* preorderTraversal(struct TreeNode* root, int* returnSize){int* ret = (int*)malloc(sizeof(int) * 100);*returnSize = 0;preOrder(root, ret, returnSize);return ret;
}//中序遍歷:
void inOrder(struct TreeNode* node, int* ret, int* returnSize) {if(!node)return;inOrder(node->left, ret, returnSize);ret[(*returnSize)++] = node->val;inOrder(node->right, ret, returnSize);
}int* inorderTraversal(struct TreeNode* root, int* returnSize){int* ret = (int*)malloc(sizeof(int) * 100);*returnSize = 0;inOrder(root, ret, returnSize);return ret;
}//后序遍歷:
void postOrder(struct TreeNode* node, int* ret, int* returnSize) {if(node == NULL) return;postOrder(node->left, ret, returnSize);postOrder(node->right, ret, returnSize);ret[(*returnSize)++] = node->val;
}int* postorderTraversal(struct TreeNode* root, int* returnSize){int* ret= (int*)malloc(sizeof(int) * 100);*returnSize = 0;postOrder(root, ret, returnSize);return ret;
}