【二叉树相关问题】

文章目录

    • 一、二叉树的三种遍历方式
      • 怎么看遍历结果
      • 相关题目:已知一颗二叉树的后续遍历序列为:GFEDCBA;中序遍历序列为:FGAEBDC。画出这棵二叉树
        • 思路
        • 代码版
    • 二、先序线索树
    • 三、二叉树转树、或森林
      • 树转二叉树
      • 二叉树转树
      • 二叉树转森林
      • 森林转二叉树

一、二叉树的三种遍历方式

怎么看遍历结果

前中后序遍历,咱先看代码,方便理解

//先序遍历:Preorder Traversal
//中序遍历:Inorder Traversal
//后序遍历:Postorder Traversal
// 前序遍历
public static void preorderTraversal(TreeNode root) {
    if (root == null) {
        return;
    }
    // 访问根节点
    System.out.print(root.val + " ");
    // 递归遍历左子树
    preorderTraversal(root.left);
    // 递归遍历右子树
    preorderTraversal(root.right);
}

// 中序遍历
public static void inorderTraversal(TreeNode root) {
    if (root == null) {
        return;
    }
    // 递归遍历左子树
    inorderTraversal(root.left);
    // 访问根节点
    System.out.print(root.val + " ");
    // 递归遍历右子树
    inorderTraversal(root.right);
}

// 后序遍历
public static void postorderTraversal(TreeNode root) {
    if (root == null) {
        return;
    }
    // 递归遍历左子树
    postorderTraversal(root.left);
    // 递归遍历右子树
    postorderTraversal(root.right);
    // 访问根节点
    System.out.print(root.val + " ");
}

其实先中后说的都是打印“自己”的时机,先序遍历,就是先打印自己的值,然后再去左子树判断,再去右子树。最先打印的一定是头结点。
而中序遍历就是先打印左子树的值,再打印自己的,再去右子树看。
后序遍历,最后打印的是头结点。

二叉树三种遍历方式的参考图↓
二叉树三种遍历方式参考图

相关题目:已知一颗二叉树的后续遍历序列为:GFEDCBA;中序遍历序列为:FGAEBDC。画出这棵二叉树

思路
  1. 首先根据后序遍历的规律——最后打印的为头结点——A

  2. 找到A之后,再个根据中序遍历,将中序遍历的序列分为两组。A的左边为左子树,右边为右子树
    在这里插入图片描述

  3. 非标准思路:如果手写,到这一步,其实可以先尝试画左子树。尝试着画就行,画出来一个就按照给出的两种遍历序列,自己遍历遍历,看看结果不一样,一样了,就再画下一个结点,不一样了,就再改。

  4. 标准思路:递归建树。重复第2步的操作,把中序遍历的序列分为两组之后,[F,G],[E,B,D,C],后序遍历序列去掉已经画好的头结点A,[G,F,E,D,C,B]。再把←这个也分成两组[G,F],[E,D,C,B](分法其实还是看左子树的节点个数,A左边有两个,所以左子树有两个结点)

  5. 中序[F,G],后序[G,F],假如这也是一个二叉树的遍历结果,画出来它对应的树,你先画出来的不还是头结点F吗?F是后序最后一个,把它接在A的左孩子的位置。接着在去考虑G就好了。(我这里没画出来G,当是练习吧)
    在这里插入图片描述

  6. 中序[E,B,D,C],后序[E,D,C,B],这不直接老规矩了都?B是后序最后一个,直接连成A的右孩子。然后再分组就行了
    在这里插入图片描述

  7. 去掉已经画好的B,你看中序遍历B左边不就一个E吗?所以中序[E],[D,C],后序[E],[D,C]。
    在这里插入图片描述

  8. 对答案
    在这里插入图片描述

代码版
import java.util.HashMap;
import java.util.Map;

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    TreeNode(int val) {
        this.val = val;
    }
}

public class BuildTree {
    public static TreeNode buildTree(int[] postorder, int[] inorder) {
        if (postorder == null || postorder.length == 0 || inorder == null || inorder.length == 0) {
            return null;
        }

        Map<Integer, Integer> postIndexMap = new HashMap<>();
        for (int i = 0; i < postorder.length; i++) {
            postIndexMap.put(postorder[i], i);
        }

        return buildTree(postorder, 0, postorder.length - 1, inorder, 0, inorder.length - 1, postIndexMap);
    }

    private static TreeNode buildTree(int[] postorder, int postStart, int postEnd, int[] inorder, int inStart, int inEnd, Map<Integer, Integer> postIndexMap) {
        if (postStart > postEnd || inStart > inEnd) {
            return null;
        }

        int rootVal = postorder[postEnd];
        TreeNode root = new TreeNode(rootVal);

        int rootIndex = postIndexMap.get(rootVal);
        // 计算左子树的节点个数
        int leftSize = searchElement(inorder,rootVal);
        // 递归构建左子树
        root.left = buildTree(postorder, postStart, rootIndex - 1, inorder, inStart, rootIndex - 1, postIndexMap);
        // 递归构建右子树
        root.right = buildTree(postorder, rootIndex + 1, postEnd - 1, inorder, rootIndex + 1, inEnd, postIndexMap);

        return root;
    }    
		//遍历方法可以从上边粘,过来就能用
    public static void main(String[] args) {
        // 后续遍历:4 5 2 6 7 3 1
        int[] postorder = {4, 5, 2, 6, 7, 3, 1};
        // 中序遍历:2 4 5 1 3 6 7
        int[] inorder = {2, 4, 5, 1, 3, 6, 7};

        TreeNode root = buildTree(postorder, inorder);
        System.out.println(root);
    }
    public static int searchElement(int[] array, int target) {
        int left = 0;
        int right = array.length - 1;
        while (left <= right) {
            int mid = left + (right - left) / 2;
            if (array[mid] == target) {
                return mid;
            } else if (array[mid] < target) {
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        // 元素未找到,返回 -1
        return -1;
    }
}

二、先序线索树

题目:根据先序遍历序列[A,F,G,B,E,C,D],线索化二叉树。
在这里插入图片描述

先序遍历序列:[A,F,G,B,E,C,D]
在先序遍历中,为了提高查找一个元素的前驱、后继的速度,有了线索化这个概念。
如何线索化:左孩子原来为空指前驱右孩子原来为空指后继不为空不看没前驱后继指到空

例:F的前驱是A,并且F的做指针原来指向空,所以现在指向A。而F原来右指针已经指向了G,不为空,不用考虑。
D左右指针原来都为空,D的前驱为C,所以做指针指向C,D没有后继,所以右指针还为空。

三、二叉树转树、或森林

树转二叉树

在这里插入图片描述
一棵树↑
横着,把自己的左孩子和它的兄弟给连起来
在这里插入图片描述
只连亲兄弟,F–G就别连了。
然后去掉“多余”的连线,再拉直。
多余的连线<A,C>,<A,D>,<B,F>
在这里插入图片描述

二叉树转树

把红色的这些节点(都是自己父节点的右孩子),“拉上去”
在这里插入图片描述
再补上蓝色的边,就是用父节点,连接自己左孩子的兄弟们
删除横这的边
在这里插入图片描述

二叉树转森林

在这里插入图片描述
把B和D拉上去,然后去掉横着的边(和转树其实挺像的,看头结点有没有右孩子吧,有了就转成森林了)
在这里插入图片描述

森林转二叉树

先把每一棵树都转成二叉树。转完之后头结点肯定没右孩子,有了,你就是没转对。
然后把后面的二叉树,当成第一棵树的右子树加进来
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
再把<D,C>连到B的右子树就行了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/244657.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

解析硬盘备份与云备份的差异

​  在数字信息时代&#xff0c;保护您的数据至关重要。外部硬盘驱动器 (HDD) 备份和云备份算是两种流行的数据备份方法。当然&#xff0c;每种方法都有其优点和考虑因素&#xff0c;选择正确的解决方案取决于您的具体需求和偏好。 一、外部硬盘备份 传统的数据备份方法之一是…

Java刷题篇——LeetCode118. 杨辉三角

1.题目描述 给定一个非负整数numRows&#xff0c;生成杨辉三角的前numRows行。 在杨辉三角中&#xff0c;每个数是它左上方和右上方的数的和。 示例1 输入&#xff1a;numRows 5 输出&#xff1a;[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1] 示例2 输入&#xff1a;numRows 1…

基于CNN+数据增强+残差网络Resnet50的少样本高准确度猫咪种类识别—深度学习算法应用(含全部工程源码)+数据集+模型(二)

系列文章目录 基于CNN数据增强残差网络Resnet50的少样本高准确度猫咪种类识别—深度学习算法应用(含全部工程源码)数据集模型&#xff08;一&#xff09; 基于CNN数据增强残差网络Resnet50的少样本高准确度猫咪种类识别—深度学习算法应用(含全部工程源码)数据集模型&#xf…

【Java8系列08】Java8中reducing妙用

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

提升团队效率,防止员工飞单私单的秘诀!

在如今竞争激烈的商业环境中&#xff0c;每个企业都追求更高的销售业绩和客户满意度。然而&#xff0c;有些员工可能会利用V信等社交工具进行私下交易&#xff0c;导致公司的利益损失和客户信任的瓦解。所以&#xff0c;如何防止员工飞单私单成为了一个需要解决的问题。 在这里…

喜报丨迪捷软件入选2023年浙江省信息技术应用创新典型案例

12月6日&#xff0c;浙江省经信厅公示了2023年浙江省信息技术应用创新典型案例入围名单。本次案例征集活动&#xff0c;由浙江省经信厅、省密码管理局、工业和信息化部网络安全产业发展中心联合组织开展&#xff0c;共遴选出24个优秀典型解决方案&#xff0c;迪捷软件“基于全数…

单例模式:饿汉模式、懒汉模式

目录 一、什么是单例模式 二、饿汉模式 三、懒汉模式 一、什么是单例模式 单例模式是Java中的设计模式之一&#xff0c;能够保证某个类在程序中只存在唯一一份实例&#xff0c;而不会创建出多个实例 单例模式有很多实现方式&#xff0c;最常见的是饿汉和懒汉两种模式 二、…

KNN朴素贝叶斯(根据已知推测未知)

KNN&#xff08;哲学思想&#xff1a;物以类聚&#xff0c;人以群分&#xff09; KNN算法原理及示例1&#xff1a; 向量化 画点&#xff0c;计算欧式距离&#xff1a; 可行代码展示&#xff1a; #!/usr/bin/python # codingutf-8 ######################################### …

如何在 VeriStand 中设置反射内存通道

环境 硬件 cPCI-5565PIORC 软件 VeriStand 我正在设置我的反射内存 PXI 卡&#xff08;例如 cPCI-5565PIORC&#xff09;。 我可以在我的 PXI 系统之间使用反射内存发送/接收什么&#xff1f; 如何设置我的 PXI 系统之间共享的通道&#xff1f; 使用反射内存&#xff0c;您…

国际语音呼叫中心的工作流程

国际语音呼叫中心的工作流程一般包括以下几个步骤&#xff1a; 1.呼叫分配 当客户拨打企业的客服电话时&#xff0c;国际语音呼叫中心会自动将呼叫分配给示闲的客服代表&#xff0c;或者根据客户的需求&#xff0c;将呼叫转接给相应的客服代表。 2.客服代表接听电话 客服代…

网络小测------

使用软件PT7.0按照上面的拓扑结构建立网络&#xff0c;进行合理配置&#xff0c;使得所有计算机之间能够互相通信。并且修改各交换机的系统名称为&#xff1a;学号_编号&#xff0c;如你的学号为123&#xff0c;交换机Switch0的编号为0&#xff0c;则系统名称为123_0&#xff1…

史上最全的设计模式总结

从七月份开始一直到九月底才看完设计模式&#xff0c;在这个过程中我不敢说我已经掌握了那本书里面的内容&#xff0c;或者说1/5&#xff0c;没能力说也没有资格说。但是结果不重要&#xff0c;重要的是这个过程我的收获&#xff01;主要包括如下几个方面&#xff1a; 1、认识了…

华为OD机试 - 任务最优调度 - 深度优先搜索dfs算法(Java 2023 B卷 200分)

目录 专栏导读一、题目描述二、输入描述三、输出描述1、输入2、输出3、说明 四、解题思路1、题目解读2、解题思路3、具体步骤 五、Java算法源码六、效果展示1、输入2、输出3、说明思路分析执行顺序 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收…

Vue3+Ts项目(Naive UI组件)——创建有图标可伸缩的左边菜单栏

文章目录 安装、配置vue-router1、安装2、main.ts配置3、在App.vue中&#xff0c;渲染路由配置到的组件 创建测试路径页面1、src\views\dashboard\index.vue2、src\views\dashboard\test.vue3、src\views\table\index.vue 配置页面路由1、src\router\modules\dashboard.ts2、sr…

Java-----链表

本篇碎碎念&#xff1a;唐朝诡事录中的西安与洛阳让我想到了&#xff0c;远赴人间惊鸿宴会&#xff0c;一睹人间盛世颜&#xff0c;描绘的就是这两个古都吧&#xff0c;有机会一定要去游览一番 今日份励志文案: 最好的状态就是向自己喜欢的东西一点点靠近 …

基于SSM的OA办公系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

在线免费压缩pdf文件

在线免费压缩pdf文件&#xff0c;不用登陆哦&#xff0c; https://www.ilovepdf.com/ https://online2pdf.com/#

IPIDEA科普大数据企业怎样使用IP代理工具进行数据抓取

相信有很多的朋友都很好奇一件事&#xff0c;一般大数据企业需要拥有海量的数据才能够进行数据分析整理和利用&#xff0c;那么他们都是如何抓取到这么多的数据呢&#xff1f;这些企业在抓取数据时都会使用什么工具&#xff0c;今天就跟大家科普一下。 其实大数据企业在进行数…

uniapp x 相比于其他的开发系统框架怎么样?

首先我们要知道niapp这是一种基于Vue.js开发的跨平台应用框架&#xff0c;可以将同一套代码同时运行在多个平台上&#xff0c;包括iOS、Android、H5等。相比其他开发系统框架&#xff0c;他有什么优点呢&#xff1f;让我们共同探讨一下吧&#xff01; 图片来源&#xff1a;unia…

《数据结构、算法与应用C++语言描述》-最大高度优先左高树-C++实现

左高树 完整可编译运行代码见&#xff1a;Github::Data-Structures-Algorithms-and-Applications/_26maxHblt 定义 (大顶堆和小顶堆)堆结构是一种隐式数据结构(implicit data structure)。用完全二叉树表示的堆在数组中是隐式存储的(即没有明确的指针或其他数据能够用来重塑…