python的二叉树定义
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
题目 144/145/94 二叉树的前后中递归遍历
题目描述:
对二叉树进行前序遍历
代码:
class Solution:
def preorderTraversal(self, root: TreeNode) -> List[int]:
if not root:
return []
left = self.preorderTraversal(root.left)
right = self.preorderTraversal(root.right)
return [root.val] + left + right
如果是中序遍历,只需要把最后一行换成:
return left + [root.val] + right
如果是后序遍历,只需要把最后一行换成:
return left + right + [root.val]
复杂度:
-
时间复杂度:时间复杂度为 O(n),其中 n 是二叉树中的节点数。这是因为我们需要访问二叉树的每一个节点恰好一次。每一个节点在被访问时,我们需要为它创建一个新的列表(
[root.val]
),并进行两次列表连接操作(+
操作符)。在最坏的情况下,列表的连接操作可能需要线性的时间,但在这种情况下,我们可以认为每个节点对应的操作时间是常数的,因此总的时间复杂度为 O(n)。 -
空间复杂度:空间复杂度为 O(n),这是因为在最坏的情况下(当二叉树完全不平衡,像一个链表那样),递归的深度可以达到 n。因为 Python 的函数调用是通过栈(stack)这种数据结构实现的,所以在这种情况下,我们需要 O(n) 的空间来存储递归栈。在最好的情况下(当二叉树完全平衡时),递归的深度为 log(n),此时空间复杂度为 O(log(n))。但在计算复杂度时,我们通常考虑最坏的情况,所以空间复杂度为 O(n)
额外知识点:
递归:
在前序遍历中,我们只在访问到具体的树节点(TreeNode)时,才会将该节点的值加入结果列表。而在递归的过程中,我们看待整棵子树(包括根节点和其所有的子节点)作为一个待处理的单元,但这个单元(整棵子树)本身并不会被加入到结果列表。
也就是说,self.preorderTraversal(root.left)
和 self.preorderTraversal(root.right)
这两个递归调用,是用来获取当前节点的左子树和右子树的前序遍历结果的,这两个递归调用返回的是一个节点值的列表,而不是整棵子树。