版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yinhui_zhang/article/details/88558674
讲在前面的话,网上一搜遍历二叉树出来的结果真的是良莠不齐,简直不能忍啊,很多前序、中序、后序遍历分别用三个结构不一样的算法来描述,这谁能顶得住啊!!!遍历二叉树代码,看一篇博客就够了。
1.二叉树遍历分类:
一般我们二叉树分为前序、中序、后序遍历(说明:本文不包括层次遍历),假设用L、D、R分别表示遍历左子树、访问根节点、遍历右子树,前序、中序、后序遍历可以分别表示为DLR、LDR、LRD(一定要记住这个顺序,在后面的代码中很重要!!)。
算法一般分为递归版本和迭代版本,下面都给出这两个版本的python代码,所有代码都测试通过。
2.talk is easy, show me the code
2.1递归版的二叉树前序、中序、后序遍历
前序遍历:
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def preorderTraversal(self, root: TreeNode) -> List[int]:
if not root:
return []
return [root.val] + self.preorderTraversal(root.left) + self.preorderTraversal(root.right)
中序遍历:
class Solution:
def inorderTraversal(self, root: TreeNode) -> List[int]:
if not root:
return []
return self.inorderTraversal(root.left) + [root.val] + self.inorderTraversal(root.right)
后序遍历:
class Solution:
def postorderTraversal(self, root: TreeNode) -> List[int]:
if not root:
return []
return self.postorderTraversal(root.left) + self.postorderTraversal(root.right) + [root.val]
发现规律没,只需要改变在代码中改变L、D、R的操作就可以了(开头已经定义过的)。
2.2迭代版的二叉树前序、中序、后序遍历
非递归的二叉树遍历思想主要是用栈和标志来不断的压栈和退栈,自己照着代码压一次栈就什么都明白了。
前序遍历:
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def preorderTraversal(self, root: TreeNode) -> List[int]:
stack = []
stack.append((0, root))
res = []
while len(stack) != 0:
flag, node = stack.pop()
if node is None:
continue
if flag == 1:
res.append(node.val)
else:
stack.append((0, node.right)) #DLR right最先压入堆栈,然后依次是LD
stack.append((0, node.left))
stack.append((1, node))
return res
中序遍历:
class Solution:
def inorderTraversal(self, root: TreeNode) -> List[int]:
stack = []
stack.append((0, root))
res = []
while len(stack) != 0:
flag, node = stack.pop()
if node is None:
continue
if flag == 1:
res.append(node.val)
else:
stack.append((0, node.right)) #LDR right最先压入堆栈,然后依次是DL
stack.append((1, node))
stack.append((0, node.left))
return res
后序遍历:
class Solution:
def postorderTraversal(self, root: TreeNode) -> List[int]:
stack = []
stack.append((0, root))
res = []
while len(stack) != 0:
flag, node = stack.pop()
if node is None:
continue
if flag == 1:
res.append(node.val)
else:
stack.append((1, node)) #LRD D最先压入堆栈,然后依次是RL
stack.append((0, node.right))
stack.append((0, node.left))
return res
又发现规律没,只需要改变最后stack的压入的顺序就可以应付三种遍历算法,简直完美。秒杀其他算法。