视频讲解: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;
}