解决思路
递归
递归是一种在函数内部直接或间接调用自身的编程技巧,常处理树结构和分治问题。
基本思想
函数不断调用自身,并在每次调用中通过改变传入的参数逐步减小问题的规模,知道满足于某种终止条件为止。处理树结构时,递归通常涉及到访问节点的值或者执行特定的操作,然后对子节点进行递归调用。
基本流程
- 确定递归函数的参数和返回值:首先确定递归函数需要接受的参数,通常是当前节点或者子树的根节点。确定函数的返回值,可能是某种处理结果,或者是对子节点的递归调用。
- 确定终止条件:在递归函数内部,需要确定最终停止递归的条件通常是处理到了某个特定节点,或者问题规模缩小到某个阈值时的情况
- 调用递归函数:在递归函数内部,通过改变参数或者执行特定操作,调用自身来处理子问题。这通常是在满足一定条件下进行的递归调用。
- 合并结果:如果需要,可以在递归函数的各次调用中收集结果,并在返回之前进行合并或处理。
代码
// 前序遍历
// 前序遍历的顺序是:根节点 -> 左子树 -> 右子树。我们可以使用递归的方式实现前序遍历。
func preorderTraversal(root *TreeNode) []int {
var res []int
if root!=nil{
res=append(res,root.Val)
res=append(res,preorderTraversal(root.Left)...)
res=append(res,preorderTraversal(root.Right)...)
}
return res
}
// 中序遍历
// 中序遍历的顺序是:左子树 -> 根节点 -> 右子树。同样可以使用递归的方式来实现中序遍历。
func inorderTraversal(root *TreeNode) []int {
var res []int
if root!=nil{
res=append(res,inorderTraversal(root.Left)...)
res=append(res,root.Val)
res=append(res,inorderTraversal(root.Right)...)
}
return res
}
// 后序遍历
// 后序遍历的顺序是:左子树 -> 右子树 -> 根节点。同样可以使用递归的方式来实现后序遍历。
func postorderTraversal(root *TreeNode) []int {
var res []int
if root!=nil{
res=append(res,postorderTraversal(root.Left)...)
res=append(res,postorderTraversal(root.Right)...)
res=append(res,root.Val)
}
return res
}