一、递归遍历尔察使
144. 二叉树的前序遍历 - 力扣(LeetCode)
1. 文章链接
2. 看到题目的第一想法
要返回的是一个list,但是这个函数似乎又没有传参传list,与其创建新的DFS函数,不如直接做个成员变量记录结果。
# 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 __init__(self):
self.node_list = list()
def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
if root is None:
return self.node_list
else:
self.node_list.append(root.val)
if root.left:
self.preorderTraversal(root=root.left)
if root.right:
self.preorderTraversal(root=root.right)
return self.node_list
145. 二叉树的后序遍历 - 力扣(LeetCode)
1. 文章链接
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 __init__(self):
self.node_list = list()
def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
if root is None:
return self.node_list
else:
if root.left:
self.postorderTraversal(root=root.left)
if root.right:
self.postorderTraversal(root=root.right)
self.node_list.append(root.val)
return self.node_list
94. 二叉树的中序遍历 - 力扣(LeetCode)
1. 文章链接
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 __init__(self):
self.node_list = list()
def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
if root is None:
return self.node_list
else:
if root.left:
self.inorderTraversal(root=root.left)
self.node_list.append(root.val)
if root.right:
self.inorderTraversal(root=root.right)
return self.node_list
二、迭代遍历
144. 二叉树的前序遍历 - 力扣(LeetCode)
1. 文章链接
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 __init__(self):
self.node_list = list()
self.stack = list()
def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
if root is None:
return self.node_list
else:
self.stack.append(root)
while self.stack:
node = self.stack.pop()
if node.right:
self.stack.append(node.right)
if node.left:
self.stack.append(node.left)
self.node_list.append(node.val)
return self.node_list
145. 二叉树的后序遍历 - 力扣(LeetCode)
1. 文章链接
2. 看到题目的第一想法
关键是什么时候停止节点入栈,直观地理解上当然是所有叶子节点都已入栈就终止。 但是我们其实可以做到用一个循环就连最后的遍历结果也输出,那就是:
- 每pop一个node,看这个node是否有一个左孩子或者右孩子。
- 如果有,那就不是叶子,我们把它们的孩子加进来,但是在加进来之前,我们还是把node放回栈,再加孩子。但是如果这样的话,每次pop到这个node,我们还是会把左右孩子压进栈来。这样就陷入了无限循环,不停的加入同样的node左右孩子。所以我们应该在压入左右孩子前,先把node的左右孩子砍掉,变成独立节点,这样他就被认为是叶子,就不会再压入他的左右孩子了。
- 如果遇到没有左右孩子的node,就应该果断把他pop出来,把值放进结果列表里就可以了。
# 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 __init__(self):
self.node_list = list()
self.stack = list()
def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
if root is None:
return self.node_list
else:
self.stack.append(root)
while self.stack:
node = self.stack.pop()
if (node.left is None) and (node.right is None):
self.node_list.append(node.val)
else:
self.stack.append(TreeNode(node.val, None, None))
if node.right:
self.stack.append(node.right)
if node.left:
self.stack.append(node.left)
return self.node_list
3. 看完代码随想录之后的想法
文档使用的是前序遍历(但是不是中左右,而是中右左)得到的结果列表就需要反转一下就行。
4. 学习时长
30分钟
94. 二叉树的中序遍历 - 力扣(LeetCode)
1. 文章链接
2. 看到题目的第一想法
输出的node,先压入他的node.right, 再压入被砍掉左右孩子的node,最后压入node.left. 如果遇见无子的节点(叶子节点或被砍去左右孩子的节点)就出栈。
# 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 __init__(self):
self.node_list = list()
self.stack = list()
def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
if root is None:
return self.node_list
else:
self.stack.append(root)
while self.stack:
node = self.stack.pop()
if (node.left is None) and (node.right is None):
self.node_list.append(node.val)
else:
if node.right:
self.stack.append(node.right)
self.stack.append(TreeNode(val=node.val))
if node.left:
self.stack.append(node.left)
return self.node_list
我觉得我这个实现好,和后序遍历很一致。
三、统一迭代法
代码随想录 (programmercarl.com)文档中使用的所谓统一的方法,其基本思想与我自己上面写的很一致,唯一的区别就是他用一个node后面是否有None来表达。但是我们直接将node砍成无子节点,达到同样的效果。