【题目】
给定一个二叉树的根节点 root ,返回它的 中序 遍历。
【示例 1】
输入:root = [1,null,2,3]
输出:[1,3,2]
【示例 2】
输入:root = []
输出:[]
【示例 3】
输入:root = [1]
输出:[1]
【示例 4】
输入:root = [1,2]
输出:[2,1]
【示例 5】
输入:root = [1,null,2]
输出:[1,2]
【提示】
树中节点数目在范围 [0, 100] 内
-100 <= Node.val <= 100
进阶: 递归算法很简单,你可以通过迭代算法完成吗?
【代码】
【1 递归】

# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def visit(self,root):
if not root:
return
self.visit(root.left)
self.ans.append(root.val)
self.visit(root.right)
def inorderTraversal(self, root: TreeNode) -> List[int]:
self.ans=[]
self.visit(root)
return self.ans
【2 迭代】

# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def inorderTraversal(self, root: TreeNode) -> List[int]:
ans=[]
if not root:
return ans
stack=[]
node=root
while stack or node:
while node:
stack.append(node)
node=node.left
node=stack.pop()
ans.append(node.val)
node=node.right
return ans
【Morris 中序遍历】能将非递归的中序遍历空间复杂度降为 O(1)
步骤:
假设当前遍历到的节点为 x
- 如果 x无左孩子,先将 x 的值加入答案数组,再访问 x 的右孩子,即 x=x.right
- 如果 x 有左孩子,则找到 x 左子树上最右的节点(即左子树中序遍历的最后一个节点,x在中序遍历中的前驱节点),我们记为 predecessor。根据 predecessor 的右孩子是否为空,进行如下操作。
2.1 如果 predecessor的右孩子为空,则将其右孩子指向 x,然后访问 x 的左孩子,即 x=x.left
2.2如果 predecessor的右孩子不为空,则此时其右孩子指向 x,说明我们已经遍历完 x 的左子树,我们将 predecessor 的右孩子置空,将 x的值加入答案数组,然后访问 x的右孩子,即 x=x.right - 重复上述操作,直至访问完整棵树。

# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def inorderTraversal(self, root: TreeNode) -> List[int]:
res=[]
while root:
if root.left:
# predecessor 节点就是当前 root 节点向左走一步,然后一直向右走至无法走为止
predecessor = root.left
while predecessor.right != None and predecessor.right != root:
predecessor = predecessor.right
# 让 predecessor 的右指针指向 root,继续遍历左子树
if predecessor.right is None:
predecessor.right = root
root = root.left
# 说明左子树已经访问完了,我们需要断开链接
else:
res.append(root.val)
predecessor.right = None
root = root.right
# 如果没有左孩子,则直接访问右孩子
else:
res.append(root.val)
root = root.right
return res
3774



被折叠的 条评论
为什么被折叠?



