分分钟带你解决数据结构------Java详解二叉树

本文全面探讨二叉树的数据结构,包括概念、特殊类型(满二叉树和完全二叉树)、性质、存储方法、创建与遍历。此外,还介绍了如何通过前序、中序、后序遍历解决各种面试题,如检查两棵树的相似性、寻找子树、计算深度等,并提供了详细的代码实现。
摘要由CSDN通过智能技术生成

声明:此博客涵盖众多二叉树知识点,完全可供学校期末考试,oj题完全可供提升对二叉树的理解

备注:二叉树习题部分画图展示步骤过于繁琐,文章内只省略展示,如果看不懂,私信博主录视频讲解!


文章前提:

通过本文章可以掌握:

  • 二叉树数据结构的概念、性质、基本实现
  • 二叉树前中后序的递归
  • 二叉树层序的写法
  • 二叉树的前中后序的非递归写法
  • 二叉树相关的 oj 面试题

文章目录:

1、树型结构的概念

2. 二叉树


1、树型结构的概念

1.1、基本概念

树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。

树型结构具有以下特点:

  • 有一个特殊的节点,称为根节点根节点没有前驱节点
  • 除根节点外,其余节点被分成M(M > 0)个互不相交的集合T1、T2、…、Tm,其中每一个集合
    Ti (1 <= i <= m) 又是一棵与树类似的子树。每棵子树的根节点有且只有一个前驱,可以有0个或多个后继
  • 树是递归定义的

图解上述概念:

在这里插入图片描述
在这里插入图片描述

至于树的递归定义:在后面二叉树实现再细说

树型结构注意点:
在这里插入图片描述


1.2、基本名词

声明:这些名词较为重要一点,需牢记

  • 结点的度:一个结点含有子树的个数称为该结点的度;
  • 树的度:一棵树中,所有结点度的最大值称为树的度;
  • 叶子结点或终端结点:度为0的结点称为叶结点;
  • 双亲结点或父结点:若一个结点含有子结点,则这个结点称为其子结点的父结点;
  • 孩子结点或子结点:一个结点含有的子树的根结点称为该结点的子结点;
  • 根结点:一棵树中,没有双亲结点的结点;
  • 结点的层次:从根开始定义起,根为第1层,根的子结点为第2层,以此类推
  • 树的高度:树中结点的最大层次;
  • 结点的深度:当前结点所处的层数,即结点的深度,结点的最大深度就是树的高度

树的以下概念只需了解,在看书时只要知道是什么意思即可:

  • 非终端结点或分支结点:度不为0的结点; 如上图:D、E、F、G…等节点为分支结点
  • 兄弟结点:具有相同父结点的结点互称为兄弟结点; 如上图:B、C是兄弟结点
  • 堂兄弟结点:双亲在同一层的结点互为堂兄弟;如上图:H、I互为兄弟结点
  • 结点的祖先:从根到该结点所经分支上的所有结点;如上图:A是所有结点的祖先
  • 子孙:以某结点为根的子树中任一结点都称为该结点的子孙。如上图:所有结点都是A的子孙
  • 森林:由m(m>=0)棵互不相交的树组成的集合称为森林

图解上述名词:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


1.3、树的表示形式

声明:该内容了解即可

树结构相对线性表就比较复杂了,要存储表示起来就比较麻烦了,实际中树有很多种表示方式,如:双亲表示法,
孩子表示法、孩子双亲表示法、孩子兄弟表示法等等

最常用的是:孩子双亲表示法,孩子兄弟表示法

1、孩子兄弟表示法:
在这里插入图片描述
具体实例:
在这里插入图片描述
2、孩子双亲表示法
在这里插入图片描述


1.4、树的应用

文件系统管理(目录和文件)
在这里插入图片描述


声明:笔试、面试、考研二叉树被问到的概率非常大,务必重视

2、二叉树

2.1、概念

一棵二叉树是结点的一个有限集合,该集合:

  1. 或者为空
  2. 或者是由一个根节点加上两棵别称为左子树右子树二叉树组成。

二叉树的模式图:

在这里插入图片描述
二叉树与树的区别:

1、二叉树中每个结点最多有两个孩子,可以是一个、两个或者没有孩子,孩子的数量一定不会大于 2,所以二叉树中一定不存在度 > 2 的结点
2、二叉树的子树有左右之分,左右次序不能颠倒,因此二叉树是有序树,这里的有序指的不是大小,而是顺序有序
3、如果是一颗二叉树,那么它的每颗子树也一定都是二叉树

以下几种情况都可以被称为二叉树:

在这里插入图片描述
下面欣赏一下来自大自然的二叉树:

在这里插入图片描述


2.2、两种特殊的二叉树
2.2.1、满二叉树

1、 满二叉树: 一棵二叉树,如果每层的结点数都达到最大值,则这棵二叉树就是满二叉树。

2、满二叉树模式图:

在这里插入图片描述
在这里插入图片描述
通过上述的推导:

我们可以发现当层数为K的二叉树结点个数满足:2 ^ K - 1 时此二叉树为满二叉树

2.2.2、完全二叉树

1、完全二叉树:完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树而引出来的。对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从0至n-1的结点一一对应时称之为完全二叉树。 要注意的是满二叉树是一种特殊的完全二叉树

上面的概念简化后就是从二叉树的根结点开始编号,如果编号一直是连续的,那么这颗二叉树就是一颗完全二叉树,反之就不是完全二叉树

2、完全二叉树模式图:
在这里插入图片描述
在这里插入图片描述


2.3、二叉树的性质

在这里插入图片描述
性质推导:

性质 1 和性质 2 在满二叉树时已经推导过,结点数最多就是满二叉树的情况
性质 3 推导:

在这里插入图片描述

该公式还可以进行推广:

在这里插入图片描述

性质四注意点:一定要是完全二叉树才有此性质

在这里插入图片描述

性质五推导:

在这里插入图片描述


2.4、有关二叉树性质的习题

声明:学校数据结构期末考试常见题型

习题一:计算二叉树叶子结点的个数(考查性质3的使用)

在这里插入图片描述

解题过程:

在这里插入图片描述


习题二:计算叶子结点的个数(考查完全二叉树的性质)

在这里插入图片描述

解题过程:

在这里插入图片描述

推导出来的完全二叉树结点性质:

在这里插入图片描述


习题三:计算叶子结点个数(利用完全二叉树结点的性质)

在这里插入图片描述

解题过程:

在这里插入图片描述


习题四:考查性质4

在这里插入图片描述

解题过程

在这里插入图片描述


2.5、二叉树的存储

二叉树的存储结构分为:顺序存储和类似于链表的链式存储
在这里插入图片描述

二叉树的链式存储是通过一个一个的节点引用起来的,常见的表示方式有二叉和三叉表示方式
在这里插入图片描述
孩子表示法:
在这里插入图片描述
孩子双亲表示法(AVL树,红黑树,B-树常使用此方法存储):
在这里插入图片描述
在这里插入图片描述

2.6、二叉树的创建

声明:这里创建二叉树的方法是孩子表示法
在这里插入图片描述

1、创建一个 TreeNode 类代表的是二叉树的每一个结点

在这里插入图片描述
在这里插入图片描述


2、把各个结点按照一定顺序连接起来。组成一颗二叉树

这里创建如图的二叉树:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
调试结果:

在这里插入图片描述](https://img-blog.csdnimg.cn/331a00c28164462b9d83098e0f86a66e.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5qKm44Gu5r6c,size_20,color_FFFFFF,t_70,g_se,x_16)![在这里插入图片描述

在这里插入图片描述


声明:所有二叉树的相关题目,基本都是通过某种遍历方式来解决的

2.7、二叉树的遍历

所谓遍历:是指沿着某条搜索路线,依次对树中每个结点均做一次且仅做一次访问。访问结点所做的操作依赖于具体的应用问题(比如:打印节点内容、节点内容加1)

二叉树的遍历分为四种:前序遍历,中序遍历,后序遍历,层次遍历。他们的区别就是根结点的打印顺序不同

注:
在这里插入图片描述

2.7.1、二叉树的前序遍历

前序遍历顺序:根结点—》左子树—》右子树

前序遍历过程:

在这里插入图片描述
前序遍历代码实现:

public void preOrder(BTNode root) {
        if (root == null) {
            return;
        }
        System.out.print(root.val + " ");
        preOrder(root.left);
        preOrder(root.right);
    }

具体遍历流程:
在这里插入图片描述
在这里插入图片描述


2.7.2、二叉树的中序遍历

中序遍历:左子树—》根结点—》右子树

中序遍历过程:先访问左子树再打印根结点最后访问右子树

在这里插入图片描述
中序遍历代码实现:

public void inOrder(TreeNode root){
        if(root == null){
            return;
        }
        inOrder(root.left);
        System.out.print(root.val+" ");
        inOrder(root.right);
    }

具体遍历流程:
在这里插入图片描述
在这里插入图片描述


2.7.3、二叉树的后序遍历

后序遍历:左子树—》右子树—》根结点

后序遍历过程:先访问左右子树最后打印根结点

在这里插入图片描述
后序遍历代码实现:

public void postOrder(TreeNode root){
        if(root == null){
            return;
        }
        postOrder(root.left);
        postOrder(root.right);
        System.out.print(root.val+" ");
    }

在这里插入图片描述

在这里插入图片描述


2.7.4、二叉树的层次遍历

在这里插入图片描述

类似于完全二叉树给每个结点编号后,按照结点编号顺序打印结点即可

在这里插入图片描述


练习前中后序遍历:

在这里插入图片描述


2.7.5、二叉树遍历习题

习题一、给定完全二叉树的层次遍历,求其前序序列结果
在这里插入图片描述
解题过程:
在这里插入图片描述


习题二、给定先序遍历和中序遍历的结果,确定一棵二叉树
在这里插入图片描述
解题过程:
在这里插入图片描述


习题三、给定中序遍历和后序遍历,确定一棵二叉树

在这里插入图片描述
解题过程:
在这里插入图片描述
习题四、已知两个序列结果相同,确定一棵二叉树
在这里插入图片描述
解题过程:
在这里插入图片描述


2.8、二叉树的基本操作

声明:针对于二叉树的问题建议使用子问题的思路,子问题思路为面试常考思路

2.8.1、获取树中节点的个数

在这里插入图片描述
在这里插入图片描述
①、遍历思路:

int count = 0;
    public int size(TreeNode root) {
        if (root == null) {
            return 0;
        }
        count++;
        size(root.left);
        size(root.right);
        return count;
    }

代码解析:

在这里插入图片描述
代码执行过程:
在这里插入图片描述


②、子问题思路

在这里插入图片描述
代码执行过程:

在这里插入图片描述
代码:

 public int size2(TreeNode root) {
        if (root == null) {
            return 0;
        }
        return size2(root.left) + size2(root.right) + 1;
    }

<div id = "23>2.8.2、获取叶子节点的个数

在这里插入图片描述
①、遍历思路
在这里插入图片描述

int leftCount = 0;

    public int getLeafNodeCount(TreeNode root) {
        if (root == null) {
            return 0;
        }
        if (root.left == null && root.right == null) {
            leftCount++;
        }
        getLeafNodeCount(root.left);
        getLeafNodeCount(root.right);
        return leftCount;
    }

②、子问题思路
在这里插入图片描述

public int getLeafNodeCount2(TreeNode root) {
        if (root == null) {
            return 0;
        }
        if (root.left == null && root.right == null) {
            return 1;
        }
        return getLeafNodeCount2(root.left) + getLeafNodeCount2(root.right);
    }

2.8.3、获取第K层节点的个数

声明:由于子问题思路比较常用,从此题后不再展示遍历思路
在这里插入图片描述

public int getKLevelNodeCount(TreeNode root, int k) {
        if (root == null || k <= 0) {
            return 0;
        }
        if (k == 1) {
            return 1;
        }
        return getKLevelNodeCount(root.left, k - 1) + getKLevelNodeCount(root.right, k - 1);
    }

2.8.4、获取二叉树的高度

在这里插入图片描述

public int getHeight(TreeNode root) {
        if (root == null) {
            return 0;
        }
        return Math.max(getHeight(root.left), getHeight(root.right)) + 1;
    }

2.8.5、检测值为value的元素是否存在

在这里插入图片描述

public TreeNode find(TreeNode root, char val) {
        if (root == null) {
            return null;
        }
        if (root.val == val) {
            return root;
        }
        TreeNode ret = find(root.left, val);
        if (ret != null) {
            return ret;
        }
        ret = find(root.right, val);
        if (ret != null) {
            return ret;
        }
        return null;
    }

2.8.6、判断一棵树是不是完全二叉树

在这里插入图片描述

public boolean isCompleteTree(TreeNode root) {
        if (root == null) return true;
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            TreeNode cur = queue.poll();
            if (cur != null) {
                queue.offer(cur.left);
                queue.offer(cur.right);
            }else{
                break;
            }
        }
        for (TreeNode t : queue) {
            if (t != null) {
                return false;
            }
        }
        return true;
    }

3、二叉树的相关 oj 习题

声明:以下12道题为面试常考题型,务必掌握

3.1、检查两颗树是否相同

leetcode – 100、相同的树

①、题目:
在这里插入图片描述
②、解题思路:
在这里插入图片描述
③、详细代码:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean isSameTree(TreeNode p, TreeNode q) {
        //情况1当p和q为空的位置不一致的时候
        if((p == null && q != null) || (p != null && q == null)){
            return false;
        }else if(p == null && q == null){
            return true;
        }else if(p.val != q.val){
            return false;
        }
        return isSameTree(p.left,q.left) && isSameTree(p.right,q.right);
    }
}

在这里插入图片描述


3.2、另一颗树的子树

LeetCode - 572、另一颗树的子树

①、题目:

在这里插入图片描述
②、解题思路:

在这里插入图片描述
③、详细代码

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    private boolean isSameTree(TreeNode p,TreeNode q){
        if(p != null && q == null || p == null && q != null){
            return false;
        }
        if(p == null && q == null){
            return true;
        }
        if(p.val != q.val){
            return false;
        }
        return isSameTree(p.left,q.left) && isSameTree(p.right,q.right);
    }
    public boolean isSubtree(TreeNode root, TreeNode subRoot) {
        if(root == null || subRoot == null){
            return false;
        }
        if(isSameTree(root,subRoot)){
            return true;
        }
        if(isSubtree(root.left,subRoot)){
            return true;
        }
        if(isSubtree(root.right,subRoot)){
            return true;
        }
        return false;
    }
}

在这里插入图片描述


3.3、二叉树最大深度

LeetCode–100、二叉树最大深度

此题就是求二叉树的深度,可以翻看上面的基本操作解析,这里不过多赘述

class Solution {
    public int maxDepth(TreeNode root) {
        if(root == null){
            return 0;
        }
        return Math.max(maxDepth(root.left),maxDepth(root.right)) + 1;
    }
}

在这里插入图片描述


3.4、 判断一颗二叉树是否是平衡二叉树

LeetCode–110、判断一颗二叉树是否是平衡二叉树

①、题目:
在这里插入图片描述
②、解题思路:
在这里插入图片描述
③、详细代码

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    private int getHeight(TreeNode root){
        if(root == null){
            return 0;
        }
        return Math.max(getHeight(root.left),getHeight(root.right)) + 1;
    }
    public boolean isBalanced(TreeNode root) {
        if(root == null){
            return true;
        }
        int lh = getHeight(root.left);
        int rh = getHeight(root.right);
        if(Math.abs(lh - rh) <= 1 && isBalanced(root.left) && isBalanced(root.right)){
            return true;
        }
        return false;
    }
}

在这里插入图片描述
④、代码改进

在这里插入图片描述
⑤、详细代码:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    private int getHeight(TreeNode root){
        if(root == null){
            return 0;
        }
        int lh = getHeight(root.left);
        int rh = getHeight(root.right);
        if(lh >= 0 && rh >= 0 && Math.abs(lh - rh) <= 1){
            return Math.max(lh,rh) + 1;
        }
        return -1;
    }
    public boolean isBalanced(TreeNode root) {
        if(root == null){
            return true;
        }
        return getHeight(root) >= 0;
    }
}

在这里插入图片描述


3.5、对称二叉树

LeetCode–101、对称二叉树

①、题目:
在这里插入图片描述
②、解题思路:
在这里插入图片描述
③、详细代码:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    private boolean isSame(TreeNode leftRoot,TreeNode rightRoot){
        if(leftRoot == null && rightRoot == null){
            return true;
        }
        if(leftRoot == null || rightRoot == null){
            return false;
        }
        if(leftRoot.val == rightRoot.val){
            return isSame(leftRoot.left,rightRoot.right) && 
            isSame(leftRoot.right,rightRoot.left);
        }
        return false;
    }
    public boolean isSymmetric(TreeNode root) {
        if(root == null){
            return true;
        }
        return isSame(root.left,root.right);
    }
}

在这里插入图片描述


3.6、二叉树的构建及遍历

牛客—KY11

①、题目:

在这里插入图片描述
②、解题思路:
在这里插入图片描述
③、详细代码:

import java.util.*;
class TreeNode{
    public char val;
    public TreeNode left;
    public TreeNode right;
    public TreeNode(char val){
        this.val = val;
    }
}
public class Main{
    public static int i = 0;
    private static TreeNode createTree(String str){
        TreeNode root = null;
        if(str.charAt(i) != '#'){
            root = new TreeNode(str.charAt(i));
            i++;
            root.left = createTree(str);
            root.right = createTree(str);
        }else{
            i++;
        }
        return root;
    }
    private static void inOrder(TreeNode root){
        if(root == null){
            return;
        }
        inOrder(root.left);
        System.out.print(root.val + " ");
        inOrder(root.right);
    }
    public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);
        while(scanner.hasNextLine()){
            String str = scanner.nextLine();
            TreeNode root = createTree(str);
            inOrder(root);
        }
    }
}

在这里插入图片描述


3.7、二叉树的分层遍历

LeetCode—102、二叉树的分层遍历

①、题目:

在这里插入图片描述
②、解题思路:
在这里插入图片描述
③、详细代码

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
import java.util.*;
class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> leveLorder = new ArrayList<List<Integer>>();
        if(root == null){
            return leveLorder;
        }
        Queue<TreeNode> qu = new LinkedList<>();
        qu.offer(root);
        while(!qu.isEmpty()){
            int size = qu.size();
            List<Integer> ret = new ArrayList<>();
            while(size != 0){
                TreeNode cur = qu.poll();
                 ret.add((int) cur.val);
            if(cur.left != null){
                qu.offer(cur.left);
            }
            if(cur.right != null){
                qu.offer(cur.right);
            }
            size--;
            }
            leveLorder.add(ret);
        }
        return leveLorder;
    }
}

在这里插入图片描述


3.8、给定一个二叉树, 找到该树中两个指定节点的最近公共祖先

LeetCode—236、给定一个二叉树, 找到该树中两个指定节点的最近公共祖先

①、题目

在这里插入图片描述
②、解题思路

在这里插入图片描述
③、详细代码

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root == null){
            return null;
        }
        if( p == root || q == root){
            return root;
        }
        TreeNode leftNode = lowestCommonAncestor(root.left,p,q);
        TreeNode rightNode = lowestCommonAncestor(root.right,p,q);
        if (leftNode != null && rightNode != null){
            return root;
        }
        if(leftNode != null){
            return leftNode;
        }
        if(rightNode != null){
            return rightNode;
        }
        return null;
    }
}

在这里插入图片描述


3.9、二叉树搜索树转换成排序双向链表

LeetCode—36、二叉树搜索树转换成排序双向链表

①、题目

在这里插入图片描述
②、解题思路

在这里插入图片描述
③、详细代码

/*
// Definition for a Node.
class Node {
    public int val;
    public Node left;
    public Node right;

    public Node() {}

    public Node(int _val) {
        val = _val;
    }

    public Node(int _val,Node _left,Node _right) {
        val = _val;
        left = _left;
        right = _right;
    }
};
*/
class Solution {
    Node prev = null;
    private void inOrder(Node root){
        if(root == null) return;
        inOrder(root.left);
        root.left = prev;
        if (prev != null){
            prev.right = root;
        }
        prev = root;
        inOrder(root.right);
    }
    public Node treeToDoublyList(Node root) {
        if(root == null){
            return null;
        }
        inOrder(root);
        Node head = root;
        while(head.left != null){
            head = head.left;
        }
        Node tail = root;
        while(tail.right != null){
            tail = tail.right;
        }
        tail.right = head;
        head.left = tail;
        return head;
    }
}

在这里插入图片描述


3.10、 根据一棵树的前序遍历与中序遍历构造二叉树

LeetCode—105、根据一棵树的前序遍历与中序遍历构造二叉树

①、题目:

在这里插入图片描述
②、解题思路:

在这里插入图片描述
③、详细代码:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    int preIndex = 0;
    private TreeNode creatTreeBypAndi(int[] preorder, int[] inorder,int begin,int end){
        if(begin > end){
            return null;
        }
        TreeNode root = new TreeNode(preorder[preIndex]);
        int index = find(inorder,begin,end,preorder[preIndex]);
        if(index == -1){
            return null;
        }
        preIndex++;
        root.left = creatTreeBypAndi(preorder,inorder,begin,index - 1);
        root.right = creatTreeBypAndi(preorder,inorder,index + 1,end);
        return root;
    }
    private int find(int[] inorder,int begin,int end, int key){
        for(int i = begin; i <= end; i++){
            if(inorder[i] == key){
                return i;
            }
        }
        return -1;
    }
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        if(preorder == null || inorder == null){
            return null;
        }
        return creatTreeBypAndi(preorder,inorder,0,inorder.length - 1);
    }
}

在这里插入图片描述


3.11、 根据一棵树的中序遍历与后序遍历构造二叉树

LeetCode—106、根据一棵树的中序遍历与后序遍历构造二叉树

①、题目:
在这里插入图片描述

②、解题过程:

在这里插入图片描述
③、详细代码:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    int postIndex = 0;
    private TreeNode createTreeByIandP(int[] inorder, int[] postorder,int begin,int end){
        if (begin > end){
            return null;
        }
        TreeNode root = new TreeNode(postorder[postIndex]);
        int index = find(inorder,begin,end,postorder[postIndex]);
        if(index == -1){
            return null;
        }
        postIndex--;
        root.right = createTreeByIandP(inorder,postorder,index + 1,end);
        root.left = createTreeByIandP(inorder,postorder,begin,index - 1);
        return root;
    }
    private int find(int[] inorder,int begin,int end, int key){
        for(int i = begin; i <= end; i++){
            if(inorder[i] == key){
                return i;
            }
        }
        return -1;
    }
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        postIndex = inorder.length - 1;
        if(inorder == null || postorder == null){
            return null;
        }
        return createTreeByIandP(inorder,postorder,0,inorder.length - 1);
    }
}

在这里插入图片描述


3.12、 二叉树创建字符串

LeetCode—606、二叉树创建字符串

①、题目:
在这里插入图片描述
②、解题思路:

在这里插入图片描述
③、详细代码

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    private void treeToString(StringBuffer sb,TreeNode root){
        if(root == null) return;
        sb.append(root.val);
        if(root.left != null){
            sb.append("(");
            treeToString(sb,root.left);
            sb.append(")");
        }else{
            if(root.right == null){
                return;
            }else{
                sb.append("()");
            }
        }
        if(root.right != null){
            sb.append("(");
            treeToString(sb,root.right);
            sb.append(")");
        }else{
            return;
        }
    }
    public String tree2str(TreeNode root) {
        if(root == null){
            return null;
        }
        StringBuffer sb = new StringBuffer();
        treeToString(sb,root);
        return sb.toString();
    }
}

在这里插入图片描述


3.13、 二叉树前序非递归遍历实现

LeetCode—144、二叉树前序非递归遍历实现

①、题目

注意:我们之前写过二叉树前序遍历的递归实现 这里采用非递归去实现

在这里插入图片描述
②、解题思路

在这里插入图片描述
③、详细代码

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
import java.util.*;
class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        TreeNode cur = root;
        Stack<TreeNode> stack = new Stack<>();
        while(cur != null || !stack.isEmpty()){
            while(cur != null){
                list.add(cur.val);
                stack.push(cur);
                cur = cur.left;
            }
            TreeNode top = stack.pop();
            cur = top.right;
        }
        return list;
    }
}

在这里插入图片描述


3.14、 二叉树中序非递归遍历实现

LeetCode–94、二叉树中序非递归遍历实现

①、题目:
在这里插入图片描述
②、解题思路

在这里插入图片描述
③、详细代码:

public void inOrder1(TreeNode root){
        TreeNode cur = root;
        Stack<TreeNode> stack = new Stack<>();
        while(cur != null || !stack.isEmpty()){
            while(cur != null){
                stack.push(cur);
                cur = cur.left;
            }
            TreeNode top = stack.pop();
            System.out.print(top.val+" ");
            cur = top.right;
        }
    }

3.15、 二叉树后序非递归遍历实现

①、题目:
在这里插入图片描述

②、解题思路:
在这里插入图片描述

③、详细代码:

public void lastOrder1(TreeNode root){
        TreeNode cur = root;
        TreeNode prev = null;
        Stack<TreeNode> stack = new Stack<>();
        while(cur != null || !stack.isEmpty()){
            while(cur != null){
                stack.push(cur);
                cur = cur.left;
            }
            TreeNode top = stack.peek();
            if(top.right == null || prev == top.right){
                stack.pop();
                System.out.print(top.val+" ");
                prev = top;
            }else{
                cur = top.right;
            }
        }
    }

文章结束

以上就是二叉树博客的全部内容,几乎覆盖了所有二叉树的知识点,希望对大家的学习有一定帮助,如果哪里有疑问,或者哪里有错误,随时连续博主,博主24h随时在线,博主定尽全力帮助解决!感谢大家的支持!

评论 40
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦の澜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值