导言
对于二叉树,无疑是Leetcode 刷题最难的部分之一,对小编也是如此,从今天开始学习或复习二叉树。
对于二叉树,我们要了解一下几个方面知识:
一、二叉树种类
- 满二叉树
如果一棵二叉树只有度为0的结点和度为2的结点,并且度为0的结点在同一层上,则这棵二叉树为满二叉树。如图所示:
- 完全二叉树
一棵深度为k的有n个结点的二叉树,对树中的结点按从上至下、从左到右的顺序进行编号,如果编号为i(1≤i≤n)的结点与满二叉树中编号为i的结点在二叉树中的位置相同,则这棵二叉树称为完全二叉树。(简单理解为,完全二叉树只有最后一层不满,但只有右边没有节点)
由此可知,满二叉树是特殊的完全二叉树。如图所示:
- 二叉搜索树(又,二叉查找树(Binary Search Tree),二叉排序树)
是一个有数据的树,也就是节点上有数值,满足三个条件。
- 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
- 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
- 它的左、右子树也分别为二叉排序树
- 平衡二叉搜索树
平衡二叉搜索树的任何结点的左子树和右子树高度最多相差1。
二、 二叉树的存储方式
- 链式存储
- 线性存储
三、 二叉树的遍历方式
- 深度优先遍历(前序遍历,中序遍历,后序遍历)【递归法 ,迭代法】
- 广度优先遍历(层次遍历 )【迭代法】
Leetcode 144 先序遍历
题目:
给你二叉树的根节点root,返回它的节点值的 前序 遍历。
示例1:
输入: root = [1,null,2,3]
输出: [1,2,3]
示例2:
输入: root = []
输出: []
示例3:
输入: root = [1]
输出: [1]
示例4:
输入: root = [1,2]
输出: [1,2]
示例5:
输入: root = [1,null,2]
输出: [1,2]
提示:
- 树中节点数量在范围[0, 100]内
- -100 <= Node.val <= 100
算法思想:
前序遍历的节点是“中,左,右”。递归算法注意三个要点:1、传入什么参数 2、递归结束条件 3、单层递归的逻辑。如代码中TreeNode 所示,树结构为链式结构,因此传入树的root节点即可,其余节点通过指针搜索。递归结束条件当然是指针走到叶子结点后没有可以走的节点。
迭代法利用栈的结构解决问题,将根节点入栈后,栈不空,从栈顶中弹出元素。因为目标遍历顺序是“根,左,右”,因此,为了这个效果,先对右子树进栈,再将左子树进栈。
代码实现:
- 递归法
# 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 preorderTraversal(self, root: TreeNode):
if not root:
return []
left = self.preorderTraversal(root.left)
right = self.preorderTraversal(root.right)
return [root.val] + left + right
- 迭代法
# 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 preorderTraversal(self, root):
# 根节点是否为None
if not root:
return []
stack = [root] # 访问节点
result = [] # 处理节点保存
while stack:
# 访问节点
node = stack.pop()
# 中节点优先处理
result.append(node.val)
# 右孩子先入栈
if node.right:
stack.append(node.right)
# 左孩子后入栈
if node.left:
stack.append(node.left)
return result
Leetcode 145 后序遍历
题目:
给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历 。
示例 1:
输入:root = [1,null,2,3]
输出:[3,2,1]
示例 2:
输入:root = []
输出:[]
示例 3:
输入:root = [1]
输出:[1]
提示:
树中节点的数目在范围 [0, 100] 内
-100 <= Node.val <= 100
算法思想:
后序遍历类似于前序遍历。后序遍历的节点是“左,右,中”。不难发现,前序遍历是“中,左,右”,因此,在跌打实现中,只需要先序遍历先遍历左子树,后遍历右子树,最后翻转即可。
代码实现
- 递归法
# 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 preorderTraversal(self, root: TreeNode):
if not root:
return []
left = self.preorderTraversal(root.left)
right = self.preorderTraversal(root.right)
return left + right + [root.val]
- 迭代法
# 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):
'''
在先序遍历的基础上,入栈顺序调换一下;
在逆序即可
'''
if not root:
return []
result = []
stack = [root]
while stack:
node = stack.pop()
# 中节点先处理
result.append(node.val)
# 左孩子先入栈
if node.left:
stack.append(node.left)
# 右孩子入栈
if node.right:
stack.append(node.right)
# 将最终结果翻转
return result[::-1]
Leetcode 94 中序遍历
题目
给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。
示例 1:
输入:root = [1,null,2,3]
输出:[1,3,2]
示例 2:
输入:root = []
输出:[]
示例 3:
输入:root = [1]
输出:[1]
提示:
- 树中节点数目在范围 [0, 100] 内
- -100 <= Node.val <= 100
算法思想:
中序遍历的思想是“左,中,右”。
代码实现:
- 递归法
# 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 preorderTraversal(self, root: TreeNode):
if not root:
return []
left = self.preorderTraversal(root.left)
right = self.preorderTraversal(root.right)
return left + [root.val] + right
- 迭代法
# 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):
if not root:
return []
stack = []
result = []
cur = root
while cur or stack:
# 一路向左
if cur:
stack.append(cur)
cur = cur.left
else:
# 左为空,返回到上一个节点;指向当前节点的右节点,如果右节点在为空的话,在出栈一个元素
cur = stack.pop()
result.append(cur.val)
# 栈顶元素在向右走
cur = cur.right
return result