二叉树之建树

        树结构如下所示。

class TreeNode{
	int val;
	TreeNode left;
	TreeNode right;
	public TreeNode(){};
	public TreeNode(int val){
		this.val = val;
	}
}

        二叉树的建树逻辑一般可以采用后序遍历的逻辑,先创建父结点,然后通过递归的方式得到左右孩子结点,最后将父节点返回。

给定集合建立二叉树

给定一个list集合[1,2,None,None,3,4,None,None,5,None,None],根据该集合建立如下图所示二叉树。
请添加图片描述

public TreeNode build(LinkedList<String> list) {
    if(list.get(0).equals("None")){
        list.remove(0);
        return null;
    }else{
        TreeNode node = new TreeNode(Integer.valueOf(list.get(0)));
        list.remove(0);
        node.left = bulid(list);
        node.right = bulid(list);
        return node;
    }
}

        首先,获取list的第一个元素1,判断1不等于None,进入else,利用TreeNode的有参构造,创建根节点,将list中首元素即1移除。之后递归方式得到左右孩子结点。先看left,递归进入bulid方法,获取list首元素2,创建结点,移除元素2,先看left,递归进入build方法,获取list首元素None,删除None,并返回null,2元素的left为null,在看2结点的right,获取list元素None,删除None,返回null,2元素的right为null,2结点bulid方法递归结束,返回2结点赋值给根节点1的left,left递归结束,递归根节点1的right。right和left同理,最终就可以建立一棵二叉树。

给定有序数组建立二叉搜索树

        给出一个示例为[-10,-3,0,5,9],建立如下图所示二叉搜索树。基本思路为:

  • 选取有序数组的中间元素作为父结点
  • 根据父结点在数组中的位置,得到左子树和右子树对应的有序数组序列
  • 同样思路递归得到左右子节点
    请添加图片描述
class Solution {
    public TreeNode sortedArrayToBST(int[] nums) {
        return helper(nums, 0, nums.length - 1);
    }
    private TreeNode helper(int[] nums, int left, int right){
        if(left > right) return null;
        int mid = (left + right) / 2;
        int val = nums[mid];
        TreeNode node = new TreeNode(val);
        node.left = helper(nums, left, mid - 1);
        node.right = helper(nums, mid + 1, right);
        return node;
    }
}

        首先sortedArrayToBST方法调用helper方法,进入helper方法,left为0,right为4,mid的值为2,将下标2对应的值0建立树结点,递归建立左右子结点,先看左节点,递归调用helper,left为0,right为1,mid为0,选取下标0对应的值-10建立树结点,之后递归结点-10左右子结点,左节点helper传入left为0,right为-1,left>right,返回null,-10左结点left赋值为null,右结点helper传入left为1,right为1,left>right不成立,mid为1,将下标为1的元素-3建立树结点,之后递归下标元素为-3的左右子节点,左节点helper传入left为1,right为0,递归结束,-3左结点赋值为null,右结点helper传入left为2,right为1,递归结束,-3右节点赋值为null,-3的helper方法运行结束,将-3的结点返回给-10结点的右结点,-10结点右结点递归结束,-10结点helper方法运行结束,赋值给根节点1的左节点,根节点左子树建立完成,同样的步骤能够得到根节点的右子树。

给定前序和中序序列遍历建立二叉树

        先给出示例,先序遍历序列为[3,9,20,15,7], 中序遍历序列为[9,3,15,20,7]。基本思路为:

  • 从左到右遍历先序序列,获取先序序列的元素,建立树结点
  • 找出先序序列元素在中序序列中的位置,从而划分左右子树
  • 按第一、二步规则递归遍历左右子树
    请添加图片描述
class Solution {
    Map<Integer, Integer> map = new HashMap<>();
    int[] preorder;
    int[] inorder;
    int idx;
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        this.preorder = preorder;
        this.inorder = inorder;
        this.idx = 0;
        for(int i = 0;i < inorder.length;i++){
            map.put(inorder[i], i);
        }
        return helper(0, inorder.length - 1);
    }
    private TreeNode helper(int l, int r){
        if(l > r) return null;
        int val = preorder[idx];
        idx++;
        TreeNode node = new TreeNode(val);
        int i = map.get(val);
        node.left = helper(l, i - 1);
        node.right = helper(i + 1, r);
        return node;
    }
}

        上述代码主要有两个方法,一个方法是buildTree,在该方法中主要工作就是有哈希表保存中序序列中每个结点对应的下标位置,方便切分为左右子序列。并调用helper方法返回二叉树。helper方法中,传递left为0,right为5,首先从先序遍历中获取首个元素,为3,并建立树结点,根据哈希表找出结点3在中序序列中的下标,划分左侧序列为[9],右侧序列为[15,20,7]。看右侧,左侧类似,且相对右侧比较简单。直接进入根结点right的递归helper,传递left为2,right为5,此时,先序序列中idx指向了元素20,建立结点值为20的树结点,之后根据哈希表找到中序序列中20所在位置,得到左侧序列[15]和右侧序列[7],递归进入结点20的left,传递left为2,right为2,从前序序列中继续获取结点值为15,建立树结点,递归进入结点值为15的left,传递left为2,right为1,满足left>right,返回null,结点值为15的left赋值为null,递归进入15的right,传递left为3,right为2,满足left>right,结点值为15的right赋值为null,15结点helper方法结束,返回结点15赋值给结点20的left,同理递归20的right,将结点7赋值给结点20的right。结点20的helper方法结束,返回结点20赋值给根节点的right。

给定中序和后序序列遍历建立二叉树

        这个代码与给定前序和中序序列建立二叉树实现逻辑相同,不同之处如下:

  • 需要从右到左遍历后序数组
  • 先递归遍历右子树,后遍历左子树
class Solution {
    int[] postorder;
    int[] inorder;
    int post_idx;
    Map<Integer, Integer> map;
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        this.post_idx = postorder.length - 1;
        this.postorder = postorder;
        this.inorder = inorder;
        this.map = new HashMap<>();
        for(int i = 0;i < inorder.length;i++){
            map.put(inorder[i], i);
        }
        return helper(0, inorder.length - 1);
    }
    private TreeNode helper(int in_l, int in_r){
        if(post_idx < 0 || in_l > in_r) return null;
        int val = postorder[post_idx];
        post_idx = post_idx - 1;
        TreeNode node = new TreeNode(val);
        int idx = map.get(val);
        node.right = helper(idx + 1, in_r);
        node.left = helper(in_l, idx - 1);
        return node;
    }
}
实战
  • 二叉树的序列化与反序列化
  • 将有序数组转化为二叉搜索树
  • 从前序和中序遍历序列构造二叉树
  • 从中序和后序遍历序列构造二叉树

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

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

相关文章

04-使用Docker镜像和仓库

回忆一下之前的创建镜像命令&#xff1a; [rootnode2 /]# docker run -i -t --name another_centos7 centos:7 /bin/bash这个命令从centos7的镜像创建一个名为another_centos7的容器&#xff0c;并且启动bash界面 什么是Docker镜像 Docker镜像是由文件系统叠加而成的。 底层…

Centos 7.9.2009 下 Gitlab 完全卸载

一、linux版本&#xff1a;lsb_release -a 二、GtiLab 版本 # 查看gitlab的版本号 cat /opt/gitlab/embedded/service/gitlab-rails/VERSION 三、开始卸载 3.1&#xff0c;停止Gitlab 相关服务 # 停止所有GitLab相关服务&#xff1a; sudo gitlab-ctl stop# 移除GitLab包…

c语言->贪吃蛇实战技巧结合EasyX简单实现页面管理(简单实现)

✅作者简介&#xff1a;大家好&#xff0c;我是橘橙黄又青&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;再无B&#xff5e;U&#xff5e;G-CSDN博客 1. 游戏背景 贪吃蛇是久负盛名的游戏&#xff0c;它也和俄罗斯⽅…

CSS基础(上)(如果想知道CSS的全部基础知识点,那么只看这一篇就足够了!)

前言&#xff1a;在我们学习完了html之后&#xff0c;我们就要开始学习三大件中的第二件—CSS&#xff0c;CSS 可以控制多重网页的样式和布局&#xff0c;也就是将我们写好的html代码加上一层华丽的衣裳&#xff0c;使网页变得更加精美。 ✨✨✨这里是秋刀鱼不做梦的BLOG ✨✨✨…

家居网购项目(二)

文章目录 1.会员登录1.需求分析2.程序框架图3.修改MemberDao添加方法 4.修改MemberDaoImpl添加方法MemberDaoTest单元测试 5.修改MemberService添加方法 6.修改MemberServiceImpl添加方法MemberServiceTest单元测试 7.编写LoginServlet1.修改login.html表单2.引入login_ok.html…

DNS 各记录类型说明及规则

各记录类型使用目的 记录类型使用目的A 记录将域名指向一个 IP 地址。CNAME 记录将域名指向另一个域名&#xff0c;再由另一个域名提供 IP 地址。MX 记录设置邮箱&#xff0c;让邮箱能收到邮件。NS 记录将子域名交给其他 DNS 服务商解析。AAAA 记录将域名指向一个 IPv6 地址。…

python-study-day2

pycharm注释(也可修改) 快捷键ctrl /手敲一个 " # " 这个是单行注释""" """ 左边这个三个引号可以完成多行注释 基础知识 常用的数据类型 def hello(self):print("Hello")print(type(1)) print(type("1"…

2024最新数据分级分类的架构方法流程指南(附下载)

以下是资料目录&#xff0c;如需下载请前往知识星球下载&#xff1a;https://t.zsxq.com/18KTZnJMX

微信小程序全屏开屏广告

效果图 代码 <template><view><!-- 自定义头部 --><u-navbar title" " :bgColor"bgColor"><view class"u-nav-slot" slot"left"><view class"leftCon"><view class"countDown…

C/C++内存泄漏及检测

“该死系统存在内存泄漏问题”&#xff0c;项目中由于各方面因素&#xff0c;总是有人抱怨存在内存泄漏&#xff0c;系统长时间运行之后&#xff0c;可用内存越来越少&#xff0c;甚至导致了某些服务失败。内存泄漏是最难发现的常见错误之一&#xff0c;因为除非用完内存或调用…

计算机网络---第十一天

生成树协议 stp作用&#xff1a; 作用&#xff1a;stp用于解决二层环路问题。 BPDU&#xff1a; 含义&#xff1a;桥协议数据单元&#xff0c;用于传递stp协议相关报文 分类&#xff1a;配置bpdu---用于传递stp的配置信息 tcn bpdu---用于通告拓扑变更信息 包含信息&…

基于opencv的视觉巡线实现

前言 这段时间在和学弟打软件杯的比赛&#xff0c;有项任务就是机器人的视觉巡线&#xff0c;这虽然不是什么稀奇的事情&#xff0c;但是对于一开始不了解视觉的我来说可以说是很懵了&#xff0c;所以现在就想着和大家分享一下&#xff0c;来看看是如何基于opencv来实现巡线的…

前端三剑客 —— JavaScript (第十一节)

内容回顾&#xff1a; jQuery 操作DOM jQuery 事件处理 Ajax jQuery 特效案例 全选效果 tab切换 下拉菜单 自定义动画 Bootstrap 入门 首先我们可以在bootstrap官网上进行下载。官网地址:https//www.bootcss.com/ 首先在我们的页面中导入bootstrap的样式&#xff0c;我们可…

知乎创作分评估体系

维度释义 创作分评估体系分为五个维度&#xff1a;创作活跃度、内容优质分、创作影响力、关注者亲密度及社区成就分&#xff0c;有助于用户了解近期的创作表现&#xff0c;每个维度的分值计算原理如下&#xff1a; 1、创作活跃度&#xff08;日更&#xff09; 与你的创作行为及…

研究了一款Vue2开发的Markdown编辑器

最近突然喜欢开始写作了&#xff0c;写笔记&#xff0c;写日记&#xff0c;写总结&#xff0c;各种写。所以&#xff0c;想要打造一个自己喜欢的编辑器&#xff0c;于是开始研究。 首先来看看我从Github丄扒拉到的这个开源的代码&#xff1a; 运行起来以后效果是这样的&…

「51媒体」如何有效进行媒体邀约,提升宣传传播效果?

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 进行有效的媒体邀约&#xff0c;提升宣传传播效果的关键在于策略性和专业性。以下是具体的做法&#xff1a; 明确目标&#xff1a;要确立清晰的品牌推广目标和策略&#xff0c;包括确定目…

Maven打包无效的标记: --release

原因&#xff1a;jdk与SpringBoot版本不匹配 解决方法&#xff1a;升级与SpringBoot版本相匹配的jdk&#xff0c;如果使用idea则可以下载 如图&#xff0c;我的版本是22最新版&#xff0c;需要下最新版的jdk 可以打开idea的文件->项目结构->项目->SDK->下载SDK 添…

QA测试开发工程师面试题满分问答12: 用户上传照片如何设计测试用例并进行测试

针对用户上传照片的功能&#xff0c;以下是一些从 QA 角度设计测试用例的示例&#xff0c;涵盖了前端功能点、后端功能点、缓存、异常处理、资源占用、并发和网络等维度&#xff1a; 前端功能点&#xff1a; a. 用户界面&#xff1a;验证上传照片的用户界面是否易于使用和导航&…

中介者模式:简化对象间通信的协调者

在面向对象的软件开发中&#xff0c;中介者模式是一种重要的行为型设计模式&#xff0c;用于降低多个对象间通信的复杂性。通过提供一个中心化的对象来处理不同组件之间的交互&#xff0c;中介者模式使得组件间不必显式引用彼此&#xff0c;从而使其松散耦合、更易于维护。本文…

RHCE:配置DNS服务的正反向解析

一反向解析 1.关闭防火墙&#xff0c;安全软件 2.服务端安装bind软件 3.服务端配置静态ip 4.客户端设置静态ip 5.服务端操作&#xff0c;编辑主配置文件 6.服务端操作&#xff0c;编辑区域配置文件&#xff0c;添加反向解析记录&#xff0c;注意&#xff1a;区域名称中IP地址反…