二叉树的层序遍历/后序遍历(leetcode104二叉树的最大深度、111二叉树的最小深度)(华为OD悄悄话、数组二叉树)

104二叉树的最大深度

给定一个二叉树 root ,返回其最大深度。
二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。
在这里插入图片描述
本题可以使用前序(中左右),也可以使用后序遍历(左右中),使用前序求的就是深度,使用后序求的是高度。

二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数或者节点数(取决于深度从0开始还是从1开始)
二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数或者节点数(取决于高度从0开始还是从1开始)
而根节点的高度就是二叉树的最大深度,所以本题中我们通过后序求的根节点高度来求的二叉树最大深度。
我先用后序遍历(左右中)来计算树的高度。

1、确定递归函数的参数和返回值:参数就是传入树的根节点,返回就返回这棵树的深度,所以返回值为int类型。
代码如下:

int getdepth(TreeNode* node)
2、确定终止条件:如果为空节点的话,就返回0,表示高度为0。
代码如下:
```c
if (node == NULL) return 0;
3、确定单层递归的逻辑:先求它的左子树的深度,再求右子树的深度,最后取左右深度最大的数值 再+1 (加1是因为算上当前中间节点)就是目前节点为根节点的树的深度。
代码如下:
`int leftdepth = getdepth(node->left);       // 左
int rightdepth = getdepth(node->right);     // 右
int depth = 1 + max(leftdepth, rightdepth); // 中
return depth;``

``int maxDepth(struct TreeNode* root) {
    if(root==NULL) return 0;
    int left=maxDepth(root->left);
    int right=maxDepth(root->right);
    return 1+fmax(left,right);
}                                       

111、二叉树的最小深度

给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明:叶子节点是指没有子节点的节点。
在这里插入图片描述

1 、递归法(后序遍历)

I、确定递归函数的参数和返回值
参数为要传入的二叉树根节点,返回的是int类型的深度。
代码如下:

int getDepth(TreeNode* node)
II、确定终止条件
终止条件也是遇到空节点返回0,表示当前节点的高度为0。
代码如下:

```c
if (node == NULL) return 0;

III、确定单层递归的逻辑

int leftDepth = getDepth(node->left);           // 左
int rightDepth = getDepth(node->right);         // 右
                                                // 中
// 当一个左子树为空,右不为空,这时并不是最低点
if (node->left == NULL && node->right != NULL) { 
    return 1 + rightDepth;
}   
// 当一个右子树为空,左不为空,这时并不是最低点
if (node->left != NULL && node->right == NULL) { 
    return 1 + leftDepth;
}
int result = 1 + min(leftDepth, rightDepth);
return result;
int minDepth(struct TreeNode* root) {
    if(root==NULL) return 0;
    int left= minDepth(root->left);
     int right= minDepth(root->right);
    if(root->left==NULL&&root->right!=NULL)
        return 1+right;
    if(root->left!=NULL&&root->right==NULL)
        return 1+left;
    return 1+fmin(left,right);   
}

2、迭代法(层序遍历)

int minDepth(struct TreeNode* root) {
    struct TreeNode* q[10000];
    if(root==NULL) return 0;
    int depth=0;
    int l=0,r=0;
    q[r++]=root;//将根节点入栈
    while(l<r){
        depth++;
        int len=r-l;
        for(int i=0;i<len;i++){
            root=q[l++];//队头元素为根节点
            if(root->left==NULL&&root->right==NULL)
            return depth;
            if(root->left!=NULL)
            q[r++]=root->left;
            if(root->right!=NULL)
            q[r++]=root->right;
        }
    }
    return depth;
}

华为OD机试C卷(100分)-悄悄话

题目描述

给定一个二叉树,每个节点上站一个人,节点数字表示父节点到该节点传递悄悄话需要花费的时间。
初始时,根节点所在位置的人有一个悄悄话想要传递给其他人,求二叉树所有节点上的人都接收到悄悄话花费的时间。

输入描述

给定二叉树

0 9 20 -1 -1 15 7 -1 -1 -1 -1 3 2

注:-1表示空节点
在这里插入图片描述

输出描述

返回所有节点都接收到悄悄话花费的时间
38

用例

输入 0 9 20 -1 -1 15 7 -1 -1 -1 -1 3 2
输出 38
说明 无

题目解析

题目给的输入信息对照图示来看,应该就是二叉树的层序遍历序列,如下图所示:
在这里插入图片描述
层序遍历序列中,父子节点存在如下关系:
如果父节点在序列中的索引是k,则其两个子节点在序列中的索引分别为 2k+1, 2k+2
因此,我们就无需建树操作了。
而悄悄话的传递,其实父节点将自身得到消息的时延累加到其各个子节点上,最终叶子节点中最大的时延值就是:二叉树所有节点上的人都接收到悄悄话花费的时间
在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>
int getResult(int *times,int len){
     int ans=0;
     int queue[100];
     int front=0,rear=0;
     queue[rear++]=0;
     while(front<rear){
          int fa=queue[front++];
          int ch1=2*fa+1;
          int ch2=2*fa+2;
          int ch1_exist=ch1<len&&times[ch1]!=-1;
           int ch2_exist=ch2<len&&times[ch2]!=-1;
           if(ch1_exist){
               times[ch1]+=times[fa];
               queue[rear++]=ch1;
           }
           if(ch2_exist){
               times[ch2]+=times[fa];
               queue[rear++]=ch2;
           }
           if(!ch1_exist&&!ch2_exist){
               if(times[fa]>ans)
                    ans=times[fa];
           }
     }
     return ans;
}
int main()
{
     int times[1000];
     int len=0;
     while(scanf("%d",&times[len++])){
          if(getchar()!=' ')break;
     }
    printf("%d\n",getResult(times,len));
    return 0;
}

华为OD机试(C卷,200分)- 数组二叉树

题目描述

二叉树也可以用数组来存储,给定一个数组,树的根节点的值存储在下标1,对于存储在下标N的节点,它的左子节点和右子节点分别存储在下标2N和2N+1,并且我们用值-1代表一个节点为空。
给定一个数组存储的二叉树,试求从根节点到最小的叶子节点的路径,路径由节点的值组成。

输入描述

输入一行为数组的内容,数组的每个元素都是正整数,元素间用空格分隔。
注意第一个元素即为根节点的值,即数组的第N个元素对应下标N,下标0在树的表示中没有使用,所以我们省略了。
输入的树最多为7层。

输出描述

输出从根节点到最小叶子节点的路径上,各个节点的值,由空格分隔,用例保证最小叶子节点只有一个。

用例

输入 3 5 7 -1 -1 2 4
输出 3 7 2
说明 最小叶子节点的路径为3 7 2。
输入 5 9 8 -1 -1 7 -1 -1 -1 -1 -1 6
输出 5 8 7 6
说明 最小叶子节点的路径为5 8 7 6,注意数组仅存储至最后一个非空节点,故不包含节点“7”右子节点的-1。

题目解析

本题有两种思路,一种是从树顶节点向下找,直到找到最小值节点。
这种方式是典型的深度优先搜索。
在这里插入图片描述
还有一种思路是先找到最小值节点,然后从最小值节点向上找父节点,由于向上找只有一个父节点,因此只有一种路径。
因此,我们应该选择这种方式。
在这里插入图片描述
采用这种方式,首先需要找到最小值节点在数组中的索引位置idx,然后根据题目定义的规则
对于存储在下标N的节点,它的左子节点和右子节点分别存储在下标2N和2N+1
当然上面这个规则是针对根节点索引从1开始的,如果根节点索引从0开始算法,则上面规则应变为
对于存储在下标N的节点,它的左子节点和右子节点分别存储在下标2N+1和2N+2
每找到一个父节点,就将其当成新的子节点,继续向上找父节点,直到子节点本身就是树顶节点为止。
另外,如何找到最小值叶子节点呢?
我们可以反向遍历输入的节点数组,如果遍历的节点符合下面条件,那么他就是一个叶子节点:
自身节点值不为-1
自身没有子节点(即既没有左子节点,也没有右子节点)

#include <stdio.h>
#include <limits.h>
#define MAXSIZE INT_MAX
char* getResult(int arr[], int size) {
    // 最小叶子节点的值
    int minV = MAXSIZE;
    // 最小节点在数组中的索引位置
    int minIdx = -1;
    int n = size - 1;

    for (int i = n; i > 0; i--) {
        if (arr[i] != -1) {
            if (i * 2 + 1 <= n && arr[i * 2 + 1] != -1) {
                continue;
            }
            if (i * 2 + 2 <= n && arr[i * 2 + 2] != -1) {
                continue;
            }

            if (minV > arr[i]) {
                minV = arr[i];
                minIdx = i;
            }
        }
    }

    // path 用于缓存最小叶子节点到根的路径
    char* path = (char*)malloc(100 * sizeof(char));
    int pathIndex = 0;
    char temp[10];
    sprintf(temp, "%d", minV);
    for (int i = 0; temp[i] != '\0'; i++) {
        path[pathIndex++] = temp[i];
        path[pathIndex++] = ' ';
    }

    // 从最小值节点开始向上找父节点,直到树顶
    while (minIdx != 0) {
        int f = (minIdx - 1) / 2;
        sprintf(temp, "%d", arr[f]);
        for (int i = 0; temp[i] != '\0'; i++) {
            path[pathIndex++] = temp[i];
        }
        path[pathIndex++] = ' ';
        minIdx = f;
    }


    path[pathIndex] = '\0';

    return path;
}
void reverseString(char* str) {
    int length = strlen(str)-1;
    for (int i = 0; i < length / 2; i++) {
        char temp = str[i];
        str[i] = str[length - i - 1];
        str[length - i - 1] = temp;
    }
}
int main() {
    // 输入数组
    int arr[1000];
    int n=0;
    while(scanf("%d",&arr[n++])){
     if(getchar()!=' ')break;
    }

    // 调用算法函数
    char* result =getResult(arr, n);
     reverseString(result);

    // 输出结果
    printf("%s\n", result);

    // 释放内存
    free(result);

    return 0;
}

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

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

相关文章

【MySQL】数据库——存储引擎

一、存储引擎概述 1.概念 MySQL中的数据用各种不同的技术存储在文件中&#xff0c;每一种技术都使用不同的存储机制、索引技巧、锁定水平并最终提供不同的功能和能力&#xff0c;这些不同的技术以及配套的功能在MySQL中称为存储引擎存储引擎是MySQL将数据存储在文件系统中的存…

数字化转型中,通过客户画像寻找触达客户经济路径

在当今数字化高速发展的时代&#xff0c;企业的数字化转型势在必行。其中&#xff0c;如何通过客户画像找到触达客户经济路径成为关键所在。 客户画像&#xff0c;是对客户全方位信息的精细描绘&#xff0c;涵盖了年龄、性别、地域、消费习惯、兴趣爱好等众多维度。这就如同为…

大模型和数据库最新结合进展

写在前面 本文主要内容是上次接受 infoQ 访谈&#xff0c;百度智能云朱洁老师介绍了大模型和 AI 结合相关话题&#xff0c;这次整体再刷新下&#xff0c;给到对这个领域感兴趣的同学。 当前&#xff0c;百度智能云云数据库特惠专场开始&#xff01;热销规格新用户免费使用&am…

前端技术栈学习:Vue2、Vue cli脚手架、ElementUI组件库、Axios

1 基本介绍 &#xff08;1&#xff09;Vue 是一个前端框架, 易于构建用户界面 &#xff08;2&#xff09;Vue 的核心库只关注视图层&#xff0c;不仅易于上手&#xff0c;还便于与第三方库或项目整合 &#xff08;3&#xff09;支持和其它类库结合使用 &#xff08;4&#…

mysql数据库的主从复制

MySQL主从复制的应用场景 当只有一台MySQL服务器要负责读写时&#xff0c;对于安全性&#xff0c;高可用&#xff0c;高并发等需求就不能满足&#xff0c;因此就要建立集群&#xff0c;集群的基础就是主从复制。 原理&#xff08;过程&#xff09; MySQL支持的复制类型 基于语…

守护你的每一步:揭秘电子厂劳保鞋的秘密

在电子厂的繁忙车间里&#xff0c;工友们忙碌的身影中&#xff0c;你是否注意到那一双双看似普通的劳保鞋&#xff1f;它们不仅承载着工人们辛勤的汗水&#xff0c;更是守护他们每一步安全的重要装备。今天&#xff0c;就让我们一起揭秘电子厂劳保鞋的秘密&#xff0c;看看它们…

Springcloud-消息总线-Bus

1.消息总线在微服务中的应用 BUS- 消息总线-将消息变更发送给所有的服务节点。 在微服务架构的系统中&#xff0c;通常我们会使用消息代理来构建一个Topic&#xff0c;让所有 服务节点监听这个主题&#xff0c;当生产者向topic中发送变更时&#xff0c;这个主题产生的消息会被…

【论文阅读】transformer及其变体

写在前面&#xff1a; transformer模型已经是老生常谈的一个东西&#xff0c;以transformer为基础出现了很多变体和文章&#xff0c;Informer、autoformer、itransformer等等都是顶刊顶会。一提到transformer自然就是注意力机制&#xff0c;变体更是数不胜数&#xff0c;一提到…

解决error Error: certificate has expired问题

安装环境遇到下面问题&#xff1a; 产生原因&#xff1a;可能是开了服务器代理访问导致ssl安全证书失效 解决办法&#xff1a; 在终端输入以下命令&#xff1a; yarn config set "strict-ssl" false -g

Element UI搭建使用过程

本章内容基于上一篇---Vue-cli搭建项目基础版 Vue-cli搭建项目----基础版-CSDN博客 官网地址:Element - The worlds most popular Vue UI framework 介绍:完全基于Vue.js ,用于快速搭建用户界面. 第一步:安装ElementUI 在终端输入 npm i element-ui -S 在main.js输入 …

《SpringBoot+Vue》Chapter04 SpringBoot整合Web开发

返回JSON数据 默认实现 依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>在springboot web依赖中加入了jackson-databind作为JSON处理器 创建一个实体类对象…

Python逻辑控制语句 之 判断语句--if、if else 和逻辑运算符结合

逻辑运算符&#xff1a; and or not 1.案例一 需求&#xff1a; 1. 获取⽤户输⼊的⽤户名和密码 2. 判断⽤户名是 admin 并且密码是 123456 时, 在控制台输出: 登录成功! 3. 否则在控制台输出: 登录信息错误! # 需求&#xff1a; # 1. 获取用户输入的用户名和密码 # 2. 判断…

Vue3使用jsbarcode生成条形码,以及循环生成条形码

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;我是前端菜鸟的自我修养&#xff01;今天给大家分享Vue3使用jsbarcode生成条形码&#xff0c;以及循环生成条形码&#xff0c;介绍了JsBarcode插件的详细使用方法&#xff0c;并提供具体代码帮助大家深入理解&#xff0c;彻…

005-GeoGebra基础篇-GeoGebra的点

新手刚开始操作GeoGebra的时候一般都会恨之入骨&#xff0c;因为有些操作不进行学习确实有些难以凭自己发现。 目录 一、点的基本操作1. 通过工具界面添加点2. 关于点的选择&#xff08;对象选择通用方法&#xff09;&#xff08;1&#xff09;选择工具法&#xff08;2&#xf…

synchronized 锁优化原理

目录 一、轻量级锁 二、锁膨胀 三、自旋优化 四、偏向锁 五、锁消除 一、轻量级锁 1. 会创建一个锁记录 Lock Record&#xff08;保存在线程栈中&#xff09;&#xff0c;尝试 CAS 修改 Mark Word 中的对象头&#xff0c;是一种乐观锁的思想&#xff0c;而不是将 Java 对…

如何选择适合的接口自动化测试工具!

引言&#xff1a; 在现代软件开发中&#xff0c;接口自动化测试已经成为保证软件质量的重要环节。通过自动化测试工具&#xff0c;可以有效地提高测试效率、减少人力成本&#xff0c;并且能够更好地发现和解决潜在的问题。然而&#xff0c;面对众多的接口自动化测试工具&#…

React+TS前台项目实战(十九)-- 全局常用组件封装:带加载状态和清除等功能的Input组件实现

文章目录 前言Input组件1. 功能分析2. 代码详细注释3. 使用方式4. 效果展示 总结 前言 今天我们来封装一个input输入框组件&#xff0c;并提供一些常用的功能&#xff0c;你可以选择不同的 尺寸、添加前缀、显示加载状态、触发回调函数、自定义样式 等等。这些功能在这个项目中…

数据结构-分析期末选择题考点(排序)

何似清歌倚桃李 一炉沈水醉红灯 契子 ✨ 上一期给大家提供了大概会考的题型给老铁们复习的大致思路 这一期还会是一样&#xff0c;我将整理一下排序的题型以及解题方法给你们 由于时间还很多&#xff0c;我就慢慢总结吧&#xff0c;一天一章的样子&#xff0c;明天总结串、后天…

开发技术-Java集合(List)删除元素的几种方式

文章目录 1. 错误的删除2. 正确的方法2.1 倒叙删除2.2 迭代器删除2.3 removeAll() 删除2.4 removeIf() 最简单的删除 3. 总结 1. 错误的删除 在写代码时&#xff0c;想将其中的一个元素删除&#xff0c;就遍历了 list &#xff0c;使用了 remove()&#xff0c;发现效果并不是想…

fiddler 返回Raw乱码

有时会发现自己发送的请求后&#xff0c;返回结果Raw里面是乱码&#xff0c;可以勾选Decode并重新发送请求就解决了 这个时候将Decode勾选一下 此时就好了
最新文章