目录
树
树的学术名词
树的种类
二叉树的遍历
算法实现
遍历命名
二叉树的中序遍历
二叉树的后序遍历
二叉树的后序遍历迭代算法
二叉树的前序遍历
二叉树的前序遍历迭代算法
树是一种非线性的数据结构,它是由n(n≥0)个有限节点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具有以下的特点:
无序树:树中任意节点的子结点之间没有顺序关系,这种树称为无序树,也称为自由树;
有序树:树中任意节点的子结点之间有顺序关系,这种树称为有序树;
二叉树:每个节点最多含有两个子树的树称为二叉树;
满二叉树:所有节点均含有两个子树的树被称为满二叉树;
完全二叉树:除最后一层外,所有层都是满节点,且最后一层缺右边连续节点的二叉树称为完全二叉树;
哈夫曼树(最优二叉树):带权路径最短的二叉树称为哈夫曼树或最优二叉树。
所谓遍历(Traversal)是指沿着某条搜索路线,依次对树中每个结点均做一次且仅做一次访问
访问结点所做的操作依赖于具体的应用问题。 遍历是二叉树上最重要的运算之一,是二叉树上进行其它运算之基础
从二叉树的递归定义可知,一棵非空的二叉树由根结点及左、右子树这三个基本部分组成。因此,在任一给定结点上,可以按某种次序执行三个操作:
以上三种操作拥有六种执行顺序:
NLR,LNR,LRN,NRL,RNL,RLN。
但是注意前三种次序和后三种次序对称,所以我们只学习前三种次序
根据访问结点操作发生位置命名:
NLR:二叉树的前序遍历(Preorder Traversal 亦称(先序遍历))
访问根结点的操作发生在遍历其左右子树之前
LNR:二叉树的中序遍历(Inorder Traversal)
访问根结点的操作发生在遍历其左右子树之中(间)
LRN:二叉树的后序遍历(Postorder Traversal)
访问根结点的操作发生在遍历其左右子树之后
若二叉树非空,则依次执行如下操作:
# 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: Optional[TreeNode]) -> List[int]:
# 左 根 右
def inorder(root : TreeNode):
if not root:
return
inorder(root.left)
res.append(root.val)
inorder(root.right)
res = list()
inorder(root)
return res
若二叉树非空,则依次执行如下操作:
# 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 postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
# 后序遍历的顺序:左 右 根
def postorder(root : TreeNode):
if not root:
return
postorder(root.left)
postorder(root.right)
res.append(root.val)
res = list()
postorder(root)
return res
期望结果:[9,5,7,4,3]
# 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 postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
res = []
stack = []
while root or stack:
while root:
res.append(root.val)
stack.append(root)
root = root.right
root = stack.pop().left #根 右 左的顺序
res.reverse()
return res
若二叉树非空,则依次执行如下操作:
访问根节点
遍历左子树
遍历右子树
class Solution:
def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
# 创建一个集合存储数据
res = []
def preorder(root:TreeNode):
# 判断root是否有值
if not root:
return
else:
# 获取根节点
res.append(root.val)
# 获取左节点
preorder(root.left)
# 获取右节点
preorder(root.right)
preorder(root)
return res
class Solution:
def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
# 创建res存储结果
res = []
stack = [] # 存储分支节点
# 只要root有数据 或者stack的数据
while root or stack:
# 只要root有数据,第一轮循环把左节点搞定
while root:
res.append(root.val)
stack.append(root)
# 获取左节点
root = root.left
# 取出右节点,遍历
root = stack.pop().right
return res