靓仔靓女们大家好,我是公众号:java小杰要加油,现就职京东,不定期分享京东面试真题以及java相关知识,今天我来分享一篇关于二叉树的文章(建议收藏,便于巩固基础)。
- 看完此文leetcode至少解决八道题
- 掌握二叉树的前序、中序、后序遍历以及两种不同的实现方式:递归与非递归
- 非递归时遍历与层次遍历时,有详细的图解表示队列/栈中的元素是如何移动的,有助于理解代码的运行
二叉树介绍
二叉树(binary tree) 是指树中节点的度不大于2的有序树,它是一种最简单且最重要的树。
二叉树的递归定义为: 二叉树是一棵空树,或者是一棵由一个根节点和两棵互不相交的,分别称作根的左子树和右子树组成的非空树;左子树和右子树又同样都是二叉树
- 逻辑上二叉树有五种基本形态,如图所示
- 空二叉树
- 只有一个根结点的二叉树
- 只有左子树
- 完全二叉树
- 只有右子树
二叉树相关属性解释:
- 结点:包含一个数据元素及若干指向子树分支的信息。
- 结点的度:一个结点拥有子树的数目称为结点的度。
- 叶子结点:也称为终端结点,没有子树的结点或者度为零的结点。
- 分支结点:也称为非终端结点,度不为零的结点称为非终端结点。
- 树的度:树中所有结点的度的最大值。
- 结点的层次:从根结点开始,假设根结点为第1层,根结点的子节点为第2层,依此类推,如果某一个结点位于第L层,则其子节点位于第L+1层。
- 树的深度:也称为树的高度,树中所有结点的层次最大值称为树的深度。
- 有序树:如果树中各棵子树的次序是有先后次序,则称该树为有序树。
- 无序树:如果树中各棵子树的次序没有先后次序,则称该树为无序树。
二叉树遍历方式
- 二叉树遍历方式分为三种
- 前序遍历(根左右): 访问根结点,再访问左子树、再访问右子树。
- 中序遍历(左根右): 先访问左子树,再访问根结点、再访问右子树。
- 后续遍历(左右根): 先访问左子树,再访问右子树,再访问根结点。
例如一个这个样子的二叉树,按三种遍历方法分别遍历,输出的结果分别是
- 前序遍历: ABDECFG
- 中序遍历: DBEAFCG
- 后续遍历: DEBFGCA
下面我们一起来用代码实现下这三种遍历
- 注:以上前序、中序、后序每一种遍历方式都有递归和非递归两种实现方法
- 前序遍历就是深度优先遍历(DFS)
- 层次遍历就是广度优先遍历(BFS)
二叉树递归遍历
class Solution {
//声明列表
ArrayList<Integer> list = new ArrayList<>();
public List<Integer> preorderTraversal(TreeNode root) {
// 如果根节点为空,则直接返回空列表
if (root == null){
return new ArrayList<>();
}
//节点不为空,将节点的值添加进列表中
list.add(root.val);
//判断此节点的左节点是否为空,如果不为空则将递归遍历左子树
if (root.left != null){
preorderTraversal(root.left);
}
//判断此节点的右节点是否为空,如果不为空则将递归遍历右子树
if (root.right != null){
preorderTraversal(root.right);
}
//最后返回列表
return list;
}
}
class Solution {
//声明列表
ArrayList<Integer> list = new ArrayList<>();
public List<Integer> inorderTraversal(TreeNode root) {
// 如果根节点为空,则直接返回空列表
if (root == null){
return new ArrayList<>();
}
//判断此节点的左节点是否为空,如果不为空则将递归遍历此节点的左子树
if (root.left != null){
inorderTraversal(root.left);
}
//节点不为空,将节点的值添加进列表中
list.add(root.val);
//判断此节点的右节点是否为空,如果不为空则将递归遍历此节点的右子树
if (root.right != null){
inorderTraversal(root.right);
}
//最后返回列表
return list;
}
}
class Solution {
//声明列表
ArrayList<Integer> list = new ArrayList<>();
public List<Integer> postorderTraversal(TreeNode root) {
// 如果根节点为空,则直接返回空列表
if (root == null){
return new ArrayList<>();
}
//判断此节点的左节点是否为空,如果不为空则将递归遍历此节点的左子树
if (root.left != null){
postorderTraversal(root.left);
}
//判断此节点的右节点是否为空,如果不为空则将递归遍历此节点的右子树
if (root.right != null)