概念:
遍历命名
根据访问结点操作发生位置命名:
① NLR: 前序遍历(Preorder Traversal 亦称(先序遍历))
——访问根结点的操作发生在遍历其左右子树之前。
② LNR: 中序遍历(Inorder Traversal)
——访问根结点的操作发生在遍历其左右子树之中(间)。
③ LRN: 后序遍历(Postorder Traversal)
——访问根结点的操作发生在遍历其左右子树之后。
共同特点:三种遍历方式中,叶子节点的顺序均为从左往右的相同的顺序。
举例:
温馨提示:可以根据代码理解遍历顺序,然后对着这张图片自己走一遍。
遍历算法:
1.前序遍历
先(根、前)序遍历的 递归算法定义:
若二叉树非空,则依次执行如下操作:
(1)访问根结点;
(2)遍历左子树;
(3)遍历右子树。
前序遍历python代码:
class Solution:
def preorderTraversal(self, root: TreeNode) -> List[int]:
def forward(root1):
if not root1:
return
ans.append(root1.val)
forward(root1.left)
forward(root1.right)
ans = []
forward(root)
return ans
2.中序遍历
中(根)序遍历的递归算法定义:
若二叉树非空,则依次执行如下操作:
(1)遍历左子树;
(2)访问根结点;
(3)遍历右子树。
中序遍历python代码:
class Solution:
def inorderTraversal(self, root: TreeNode) -> List[int]:
def middle(root1):
if not root1:
return
middle(root1.left)
ans.append(root1.val)
middle(root1.right)
ans = []
middle(root)
return ans
3.后序遍历
后(根)序遍历得递归算法定义:
若二叉树非空,则依次执行如下操作:
(1)遍历左子树;
(2)遍历右子树;
(3)访问根结点。
后序遍历python代码:
class Solution:
def postorderTraversal(self, root: TreeNode) -> List[int]:
def backward(root1):
if not root1:
return
backward(root1.left)
backward(root1.right)
ans.append(root1.val)
ans = []
backward(root)
return ans
4、层序遍历
class Solution:
def Print(self, pRoot):
# write code here
from collections import deque
res = []
q = deque()
q.append(pRoot)
while q:
temp = q.popleft()
res.append(temp.val)
if temp.left:
q.append(temp.left)
if temp.right:
q.append(temp.right)
return res
5、利用前、中遍历序列重构二叉树
思路:前序遍历的第一个元素肯定是根节点,然后通过找到中序根节点在中序遍历中的位置,就可以判断左右叶子的分布(中序遍历中,根节点左边都是左叶子,后边都是右叶子)。
# 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 buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
if len(preorder)==0:
return
root = TreeNode(preorder[0]) # 根节点肯定是前序遍历的第一个
root_index = inorder.index(preorder[0]) # 返回中序遍历中根节点的位置,该位置之前全是左叶子,之后全是右叶子。注意前序和中序遍历序列中,左右叶子的长度肯定相同
root.left = self.buildTree(preorder[1:root_index+1], inorder[:root_index])
root.right = self.buildTree(preorder[root_index+1:], inorder[root_index+1:])
return root
6、利用中、后遍历序列重构二叉树
思路:后序遍历的最后一个元素肯定是根节点,然后通过找到中序根节点在中序遍历中的位置,就可以判断左右叶子的分布(中序遍历中,根节点左边都是左叶子,后边都是右叶子)。最后在根据中序左右叶子的长度判断后序遍历的分布(后序遍历中,左叶子全部分布左边,右叶子全部在右边)
# 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 buildTree(self, inorder: List[int], postorder: List[int]) -> TreeNode:
if not postorder:
return None
root = TreeNode(postorder[-1]) # 后序最后一个节点是根节点
n = inorder.index(root.val) # 取出中序中根节点的index,可以快速判别左右子树
root.left = self.buildTree(inorder[:n], postorder[:n]) # 在中序中,根节点的左子树元素都在左边;在后序中,根节点的右子树元素也都在左边
root.right = self.buildTree(inorder[n+1:], postorder[n:-1]) # 在中序中,根节点的右子树元素都在右边;在后序中,也都在左边,但是就不取最后一个元素了,因为最后一个是根
return root
注意:无法使用前、后遍历序列重构出唯一的二叉树