# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def postorderTraversal(self, root: TreeNode) -> List[int]:
res = [] # 用来存储后序遍历节点的值
stack = []
node = root
while stack or node:
while node:
stack.append(node) # 第一次入栈的是根节点
#判断当前节点的左子树是否存在,若存在则持续左下行,若不存在就转向右子树
node = node.left if node.left is not None else node.right
#循环结束说明走到了叶子节点,没有左右子树了,该叶子节点即为当前栈顶元素,应该访问了
node = stack.pop() # 取出栈顶元素进行访问
res.append(node.val) # 将栈顶元素也即当前节点的值添加进res
# (下面的stack[-1]是执行完上面那句取出栈顶元素后的栈顶元素)
if stack and stack[-1].left == node: #若栈不为空且当前节点是栈顶元素的左节点
node = stack[-1].right ## 则转向遍历右节点
else:
node = None # 没有左子树或右子树,强迫退栈
return res
①寻找最左边的开始结点
while node:
stack.append(node) # 第一次入栈的是根节点
#判断当前节点的左子树是否存在,若存在则持续左下行,若不存在就转向右子树
node = node.left if node.left is not None else node.right
首先要先找到这个树根节点左子树的最下端,也就是后序的第一个点
当左右结点都是 null 的时候这个循环退出
图上也就是4这个点
同时1 2 4入栈
②处理节点
#循环结束说明走到了叶子节点,没有左右子树了,该叶子节点即为当前栈顶元素,应该访问了
node = stack.pop() # 取出栈顶元素进行访问
res.append(node.val) # 将栈顶元素也即当前节点的值添加进res
# (下面的stack[-1]是执行完上面那句取出栈顶元素后的栈顶元素)
这个时候4结点进入了答案链表,并且从栈中弹出
返回到2结点
③观察是否有右节点
if stack and stack[-1].left == node: #若栈不为空且当前节点是栈顶元素的左节点
node = stack[-1].right ## 则转向遍历右节点
else:
node = None # 没有左子树或右子树,强迫退栈
这里stack[-1]
也就是栈顶元素2,如果之前的4时2的左节点,那现在转到2的右节点
又开始①的循环,寻找最左下的结点,这时候5,7入栈
处理完7之后,返回到5结点
7是5的左节点,转到5的右节点
这时候 node 是 null,①的循环不能进入
所以也就代表不需要找这个结点的左下结点
直接处理当下栈顶结点5