LeetCode - 145. Binary Tree Postorder Traversal
在数据结构与算法的世界里,二叉树作为一种重要且基础的树形结构,有着广泛的应用场景。而二叉树的遍历是处理二叉树相关问题的基础操作,其中后根遍历(也称为后序遍历)更是有着独特的逻辑和应用价值。本文将深入探讨二叉树后根遍历问题,并通过 JavaScript 和 Python 两种编程语言的代码实现,为你揭开其背后的奥秘。
1. 二叉树后根遍历问题概述
1.1 问题描述
给定一棵二叉树的根节点,需要按照后根遍历的顺序输出二叉树中所有节点的值。后根遍历的规则是:先访问左子树,再访问右子树,最后访问根节点。通过这种遍历方式,可以完整地获取二叉树中节点的特定顺序信息,在诸如计算二叉树节点数量、获取叶子节点等问题中发挥着关键作用。
1.2 输入与输出
-
输入:二叉树的根节点。对于不同编程语言,二叉树节点的定义方式有所不同,但通常都包含节点的值以及指向左子节点和右子节点的引用或指针。
-
输出:一个包含二叉树所有节点值的数组,数组中的元素顺序符合后根遍历的规则。
2. 递归解题思路剖析
解决二叉树后根遍历问题的关键方法是递归。递归是一种自身调用自身的编程技巧,在处理树形结构问题时具有天然的优势,因为二叉树本身就具有递归的结构特性 —— 每个子树也都是一棵二叉树。
具体到后根遍历,其递归逻辑如下:
-
- 检查当前节点是否存在,如果不存在(即节点为
null
或None
),则直接返回,不进行任何操作,因为空节点没有值需要处理。
- 检查当前节点是否存在,如果不存在(即节点为
-
- 递归地对当前节点的左子树进行后根遍历,这样可以确保先处理完左子树的所有节点。
-
- 递归地对当前节点的右子树进行后根遍历,在左子树处理完成后,接着处理右子树的节点。
-
- 当左子树和右子树都遍历完成后,将当前节点的值加入到结果数组中,因为此时左右子树的节点都已按顺序处理完毕,符合后根遍历的规则。
通过不断重复上述递归过程,从根节点开始,逐步深入到二叉树的各个子树,最终可以按照后根遍历的顺序获取到所有节点的值。
3. JavaScript 实现与代码详解
/**
* @param {TreeNode} root
* @return {number[]}
*/
var postorderTraversal = function (root) {
let arr = [];
(function (root) {
if (root) {
arguments.callee(root.left);
arguments.callee(root.right);
arr.push(root.val);
}
})(root)
return arr;
};
在这段 JavaScript 代码中:
- 首先定义了一个空数组
arr
,用于存储后根遍历的结果。 - 然后使用了一个立即执行函数(IIFE)来实现递归逻辑。在这个立即执行函数内部:
- 通过
if (root)
判断当前节点是否存在,如果存在,则执行后续操作。 arguments.callee(root.left)
递归地调用自身,对当前节点的左子树进行后根遍历。这里arguments.callee
指向当前正在执行的函数,即递归调用自身以处理左子树。- 接着
arguments.callee(root.right)
递归地对当前节点的右子树进行后根遍历。 - 当左右子树都遍历完成后,
arr.push(root.val)
将当前节点的值添加到结果数组arr
中。
- 通过
- 最后,函数返回存储着后根遍历结果的数组
arr
。
4. Python 实现与代码解读
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def postorderTraversal(self, root: TreeNode) -> List[int]:
arr = []
def postorder(root:TreeNode):
if root:
postorder(root.left)
postorder(root.right)
arr.append(root.val)
postorder(root)
return arr
Python 代码的实现思路与 JavaScript 类似:
- 在
Solution
类的postorderTraversal
方法中,首先创建一个空列表arr
,用于存放后根遍历的结果。 - 定义了一个内部函数
postorder
,该函数实现了递归的后根遍历逻辑。在postorder
函数内部:- 通过
if root
判断当前节点是否存在,若存在则继续执行。 postorder(root.left)
递归地调用自身,对当前节点的左子树进行后根遍历。- 然后
postorder(root.right)
递归地对当前节点的右子树进行后根遍历。 - 当左右子树遍历结束后,
arr.append(root.val)
将当前节点的值添加到结果列表arr
中。
- 通过
- 调用内部函数
postorder(root)
启动递归遍历过程,最后返回存储着后根遍历结果的列表arr
。
二叉树的后根遍历通过递归的巧妙应用,能够简洁而高效地获取二叉树节点的特定顺序信息。无论是 JavaScript 还是 Python,都能很好地实现这一算法逻辑。掌握二叉树后根遍历的原理和实现,不仅有助于我们解决更多与二叉树相关的算法问题,还能加深对递归思想和树形数据结构的理解。希望本文的讲解能让你对二叉树后根遍历有更清晰、深入的认识,在今后的编程实践中灵活运用这一重要算法。