代码随想录(七) —— 二叉树部分

news2024/11/30 12:44:43

1. 二叉树的四种遍历方式的理解

前序遍历,中序遍历,后序遍历;层次遍历

结合另一篇博客,关于灵神的题单刷题

二叉树刷题记录-CSDN博客 

理解:

        在二叉树类型题目中,遍历顺序的选择需要根据具体问题来确定。以下是四种常见的遍历方式及其特点:

一、前序遍历(根左右)

1. 特点:
   - 可以在遍历过程中较早地访问根节点,对于需要先处理根节点信息的问题比较适用。
   - 常用于需要快速确定整棵树的某些特征,比如构建二叉树的副本、判断两棵二叉树是否相等、求二叉树的深度等问题。

2. 应用场景示例:
   - 构建二叉树的副本:先复制根节点,再递归复制左右子树。
   - 判断两棵二叉树是否相等:比较根节点的值,然后递归判断左右子树是否相等。

二、中序遍历(左根右)

1. 特点:
   - 对于二叉搜索树 BST,中序遍历可以得到有序的节点值序列。
   - 在一些需要按特定顺序处理节点的问题中很有用,比如求二叉搜索树的中序后继节点。

2. 应用场景示例:
   - 验证二叉搜索树:通过中序遍历得到的序列应该是升序的。
   - 求二叉搜索树的第 k 小值:利用中序遍历的有序性,依次计数找到第 k 个节点。

三、后序遍历(左右根)

1. 特点:
   - 可以在处理完左右子树后再处理根节点,对于需要在处理完子树后进行一些清理工作计算依赖于子树结果的问题比较合适。
   - 常用于计算二叉树的高度、直径等问题。

2. 应用场景示例:
   - 计算二叉树的高度:先计算左右子树的高度,再加上根节点自身的高度。
   - 释放二叉树的内存:先递归释放左右子树的内存,再释放根节点的内存。

四、层序遍历

  1. 特点

    • 从上到下、从左到右依次访问每一层的节点。
  2. 适用场景

    • 当需要按层次顺序访问二叉树的节点时,层序遍历是合适的选择。
    • 在一些图形相关的问题中,如广度优先搜索等,层序遍历可以提供一种按层次处理节点的方式。

此外,还有层序遍历等方式,可根据问题需求灵活选择遍历顺序。在解决二叉树问题时,要充分理解不同遍历方式的特点和适用场景,以便选择最合适的遍历顺序来高效地解决问题。

2. 翻转二叉树

226. 翻转二叉树

遍历顺序分析:

        思路是翻转一个节点的左右孩子,处理逻辑应该放在左右孩子之前或之后,所以可以使用前序或者后序遍历,不能使用中序遍历,否则一个节点会翻转两次;比如左孩子翻转之后变成了右孩子,然后右孩子又翻转了一次变成了左孩子。在本题中层序遍历也可以使用。

递归三部曲:(1)确定递归函数的参数与返回值 (2)确定终止条件(3)确定单层递归的逻辑

class Solution {
    public TreeNode invertTree(TreeNode root) {
        preOrder(root);
        return root;
    }
    public void preOrder(TreeNode root) {
        if(root == null) return; 
        TreeNode tmp = root.right;
        root.right = root.left;
        root.left = tmp;
        preOrder(root.left);
        preOrder(root.right);
    }
}
//  使用栈来模拟前序遍历:因为前序遍历是根左右顺序,所以入栈方式应当为先入根节点,再加入右节点,最后左节点;
//  这样遍历出来的方式才是根左右
class Solution {
public:
    TreeNode* invertTree(TreeNode* root) {
        if(root == NULL) return root;
        stack<TreeNode*> st;
        st.push(root); 
        while(!st.empty()) {
            TreeNode* node = st.top();
            st.pop();  // 遍历中
            // 遍历出中了就进行中节点的操作
            TreeNode* tmp = node->right;
            node->right = node->left;
            node->left = tmp;

            if(node->right) st.push(node->right);
            if(node->left) st.push(node->left);
        } 
        return root;
    }
};

3. 二叉树的最大深度

104. 二叉树的最大深度

  • 二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数或者节点数(取决于深度从0开始还是从1开始)
  • 二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数或者节点数(取决于高度从0开始还是从1开始)

遍历顺序分析:

        求二叉树的最大深度就是在求根节点的高度,根节点的高度等于左右子树高度的最大值+1;很显然,这里在处理节点时需要有左右节点的高度,所以最好的选择是使用后序遍历。

class Solution {
public:
    int maxDepth(TreeNode* root) {
        /*
            后序遍历
        */
        return postOrder(root);
    }
private:
    // 返回当前节点的高度
    int postOrder(TreeNode* root) {
        if(root == NULL) {
            return 0;
        } 
        int left = postOrder(root->left);
        int right = postOrder(root->right);
        // 处理当前节点高度
        return max(left,right) + 1;
    }
};

        也可以使用层序遍历解决;即二叉树的最大深度即层序遍历的层数

代码

559. N 叉树的最大深度

待办

4. 二叉树的最小深度

111. 二叉树的最小深度

给定一个二叉树,找出其最小深度。

最小深度是从根节点到最近叶子节点的最短路径上的节点数量。

说明:叶子节点是指没有子节点的节点。

注意:这里有一个坑点,即最小高度并不是左右子树的最小高度 + 1; 因为可能左子树都没有孩子,自然就没有叶子节点了,此时如果按照这种方式计算的话那二叉树的高度会为1,但实际上不是。

所以这里需要把这种情况去掉:

        当左子树为空,右子树不为空时,此时该节点最小深度 = 右子树的最小深度 + 1;

        当右子树为空,左子树不为空时,此时该节点最小深度 = 左子树的最小深度 + 1;

        当左右子树都不是空的时候,此时该节点最小深度 = 左右子树中的最小深度 + 1;

        递归终止情况,当该节点为叶子节点时,返回1; 或者是该节点为null时返回0,表示没有节点的树最小深度为0。

遍历方式分析

因为在处理节点时需要用到左右子树的信息,所以可以采用后序遍历。

class Solution {
public:
    int minDepth(TreeNode* root) {
        return postOrder(root);
    }
private:
    int postOrder(TreeNode* root) {
        if(root == NULL) return 0;
        int leftMin = postOrder(root->left);
        int rightMin = postOrder(root->right);
        // 处理逻辑
        if(root->left == NULL && root->right != NULL) {
            return rightMin + 1;
        }
        if(root->left != NULL && root->right == NULL) {
            return leftMin + 1;
        }
        return min(leftMin, rightMin)  + 1; // 叶子节点 以及 左右子树都存在的节点 其返回值都是这个
    }
};

5. 完全二叉树的节点数

222. 完全二叉树的节点个数

给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。

完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2h 个节点。

遍历顺序分析:

对于普通的一颗二叉树

        递归的思想:二叉树的节点数目 = 左子树的节点数 + 右子树的节点数 + 1;

        层序遍历的思想:就是一层一层的遍历,直到队列变空

class Solution {
public:
    int countNodes(TreeNode* root) {
        /*
            后序遍历
        */
        return postOrder(root);
    }

private: 
    // 返回子树的高度
    int postOrder(TreeNode* root) {
        if(root == NULL) {
            return 0;
        }
        int left = postOrder(root->left);
        int right = postOrder(root->right);
        return left + right + 1;
    }
};
class Solution {
public:
        /*
            层序遍历
        */
    int countNodes(TreeNode* root) {
        if(root == NULL) return 0;
        queue<TreeNode*> que;
        que.push(root);  // --> 准备op: 建队并根节点入队
        int res = 0;
        while(!que.empty()) { 
            int size = que.size();  // 控制每一层的遍历次数
            for(int i=0; i< size; i++) {
                TreeNode* node = que.front();
                que.pop(); // 元素出队
                res ++; // 记录节点数目
                if(node -> left) que.push(node->left);
                if(node -> right) que.push(node -> right); // 左右孩子节点入队
            }
        }
        return res;
    }
}; 

 二叉树的所有路径

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

算法笔记day04

目录 1. 在字符串中找出连续最长的数字串 2.岛屿数量 3.拼三角 1. 在字符串中找出连续最长的数字串 字符串中找出连续最长的数字串_牛客题霸_牛客网 (nowcoder.com) 算法思路&#xff1a; 这是一道简单的双指针题目&#xff0c;首先用i遍历数组&#xff0c;当遍历到数字的时…

春日技术辅导:Spring Boot课程答疑

3系统分析 3.1可行性分析 通过对本课程答疑系统实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本课程答疑系统采用JAVA作为开发语言&#xff0c;Spring Boot框…

数据驱动,漫途能耗管理系统打造高效节能新生态!

在我国能源消耗结构中&#xff0c;工业企业所占能耗比例相对较大。为实现碳达峰、碳中和目标&#xff0c;工厂需强化能效管理&#xff0c;减少能耗与成本。高效的能耗管理系统通过数据采集与分析&#xff0c;能实时监控工厂能源使用及报警情况&#xff0c;为节能提供数据。构建…

JVM 调优篇10 使用arthas排优

一 Arthas的作用 1.1 作用 1. 这个类从哪个 jar 包加载的&#xff1f;为什么会报各种类相关的 Exception&#xff1f; 2.是否有一个全局视角来查看系统的运行状况&#xff1f; 3. 有什么办法可以监控到JVM的实时运行状态&#xff1f; 4. 怎么快速定位应用的热点&#x…

TensorFlow详细配置

Anaconda 的安装路径配置系统环境变量 1 windows path配置 2 conda info C:\Users\Administrator>conda info active environment : None user config file : C:\Users\Administrator\.condarc populated config files : C:\Users\Administrator\.condarc …

【含文档】基于Springboot+Vue的高校科研信息管理系统(含源码+数据库+lw)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 系统定…

mybatis之入门(详细介绍)

1.Mybatis简介 MyBatis 是一个开源、轻量级的数据持久化框架&#xff0c;是 JDBC 和 Hibernate 的替代方案。MyBatis 内部封装了 JDBC&#xff0c;简化了加载驱动、创建连接、创建 statement 等繁杂的过程&#xff0c;开发者只需要关注 SQL 语句本身。 1.1.什么是Mybatis MyB…

VSCODE 导入cubeide工程

1.下载vscode及插件STM32 VS Code Ectersion 版本号1.0.0&#xff0c;之后这个有导入功能。 2.等待自动安装对应插件&#xff0c;提示缺少什么就补什么 3.在左侧出现stm32图标。点击Import a local project导入本地项目。 4.报错 [{"resource": "/f:V11/cmak…

【Linux】进程控制:从fork到exec

&#x1f308; 个人主页&#xff1a;Zfox_ &#x1f525; 系列专栏&#xff1a;Linux 目录 一&#xff1a;&#x1f525; 进程创建 &#x1f95d; fork函数初识&#x1f95d; 写时拷贝&#x1f95d; fork常规用法&#x1f95d; fork调用失败的原因 二&#xff1a;&#x1f525;…

群晖使用Docker搭建NASTool自动化观影工具并实现在线远程管理

文章目录 前言1. 本地搭建Nastool2. nastool基础设置3. 群晖NAS安装内网穿透工具4. 配置公网地址5. 配置固定公网地址 前言 本文主要分享一下如何在群晖NAS中本地部署Nastool&#xff0c;并结合cpolar内网穿透工具&#xff0c;轻松实现公网环境远程管理与访问本地NAS中储存的影…

惠普电脑怎么开启vt_惠普电脑开启vt虚拟化图文教程(支持新旧bios开启方法)

最近使用惠普电脑的小伙伴们问我&#xff0c;惠普电脑怎么开启vt虚拟。大多数可以在Bios中开启vt虚拟化技术&#xff0c;当CPU支持VT-x虚拟化技术&#xff0c;有些电脑会自动开启VT-x虚拟化技术功能。而大部分的电脑则需要在Bios Setup界面中&#xff0c;手动进行设置&#xff…

数字媒体产业园区:创新资源集聚,助力企业成长

在当今数字化浪潮汹涌的时代&#xff0c;数字媒体产业园区作为创意与技术的交汇点&#xff0c;正以其独特的魅力和无限的潜力&#xff0c;成为助力企业成长的重要平台。其中&#xff0c;“数字媒体产业园区”以其创新资源的集聚效应&#xff0c;为入驻企业提供了广阔的发展空间…

双十一有什么好物推荐?双十一必买清单大汇总

双十一的钟声即将敲响&#xff0c;数码好礼的选购热潮已然兴起。在这个信息爆炸的时代&#xff0c;我们被各种数码产品的广告和推荐所包围。如何从中筛选出真正适合自己的数码礼物呢&#xff1f;本文将以专业的视角、客观的评价&#xff0c;为你梳理数码产品的优缺点&#xff0…

将 QT 应用程序打包成如意玲珑软件包

在上一篇文章《国产系统之如意玲珑》中&#xff0c;我为大家介绍了一款创新的国产软件包管理工具——如意玲珑&#xff08;Linyaps&#xff09;。该工具集致力于解决 Linux 系统下传统软件包格式带来的复杂性和依赖问题&#xff0c;提供了一种更独立、更简洁的打包和管理方式。…

python爬虫,爬取网页壁纸图片

python爬虫实战&#xff0c;爬取网页壁纸图片 使用python爬取壁纸图片&#xff0c;保存到本地。 爬取彼岸图网&#xff0c;网站地址https://pic.netbian.com/ 本人小白&#xff0c;记录一下学习过程。 开始前的准备 安装python环境&#xff0c;略。 python编辑器pycharm2…

Linux:防火墙相关命令使用(Ubuntu)

1.安装防火墙工具 虚拟机安装好系统后&#xff0c;默认是没有管理工具的。如果已经安装可以跳过。 # 安装ufw&#xff08;Uncomplicated Firewall&#xff09;&#xff0c;这是Ubuntu上管理防火墙的一个简单工具 sudo apt-get install ufw2.开启和关闭防火墙 # 开启防火墙 sud…

RuoYi-Vue若依框架-后端设置不登陆访问(白名单)

找到SecurityConfig类 确认自己的需求 /*** anyRequest | 匹配所有请求路径* access | SpringEl表达式结果为true时可以访问* anonymous | 匿名可以访问* denyAll | 用户不能访问* fullyAuthenticated | 用户完全认证可…

请速度收藏,Python爬虫必备的8大技巧!

想要快速学习爬虫&#xff0c;最值得学习的语言一定是Python&#xff0c;Python应用场景比较多&#xff0c;比如&#xff1a;Web快速开发、爬虫、自动化运维等等&#xff0c;可以做简单网站、自动发帖脚本、收发邮件脚本、简单验证码识别脚本。 爬虫在开发过程中也有很多复用的…

输电线路语义分割图像数据集,图片总共1200张左右,包含分割标签,json标签

输电线路语义分割图像数据集&#xff0c;图片总共1200张左右&#xff0c;包含分割标签&#xff0c;json标签 输电线路语义分割图像数据集介绍 数据集概述 名称&#xff1a;输电线路语义分割图像数据集图片数量&#xff1a;约1200张标注格式&#xff1a;JSON (包含像素级分割标…

中小型医院网站:Spring Boot开发策略

2 相关技术简介 2.1 Java技术 Java是一种非常常用的编程语言&#xff0c;在全球编程语言排行版上总是前三。在方兴未艾的计算机技术发展历程中&#xff0c;Java的身影无处不在&#xff0c;并且拥有旺盛的生命力。Java的跨平台能力十分强大&#xff0c;只需一次编译&#xff0c;…