简单记录牛客top101算法题(初级题C语言实现)BM24 二叉树的中序遍历 BM28 二叉树的最大深度 BM29 二叉树中和为某一值的路径

news2025/1/23 3:52:41

1. BM24 二叉树的中序/后续遍历

  要求:给定一个二叉树的根节点root,返回它的中序遍历结果。
                        在这里插入图片描述

输入:{1,2,#,#,3}
返回值:[2,3,1]

1.1 自己的整体思路(与二叉树的前序遍历大致一样)

  1. 使用二叉树的前序遍历方法,递归完成二叉树元素的访问。
  2. 先遍历二叉树,求出二叉树的结点数量以后,再申请数组,这样节省内存大小。
  3. 二叉树的前中后序遍历,只需要改变访问根结点的代码位置,其与递归左子树和右子树的位置,代表是前中后序的一种。
#include <malloc.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
int  TreeSize(struct TreeNode* root) {                           //判断二叉树有多少个结点
    if (root == NULL) {
        return 0;
    }
    return TreeSize(root->left) + TreeSize(root->right) + 1;
}                                    
void  visit_root(struct TreeNode* root, int* arr,int *a){        //访问根结点
    *(arr + *a) = root->val;              //存下根结点元素
    (*a)++;                               //索引++
}
 void  Preorder(struct TreeNode* root, int* arr,int *a){         //遍历二叉树
    if (root!=NULL) {
        Preorder(root->left,arr,a);        //递归左结点
        visit_root(root,arr,a);            //访问根结点          //如果把这一行放到下面一行,就是后序遍历,其他的代码不用变的
        Preorder(root->right,arr,a);       //递归右结点
    }
 }              
int* inorderTraversal(struct TreeNode* root, int* returnSize ) {          //中序遍历
    // int n;                                              //这里没有初始化,导致程序卡死了
    int n = 0;
    int *i = &n;
    int count =  TreeSize(root);                        //计算二叉树有多少结点
    printf("val = %d\r\n",count);
    int *array = (int *)malloc(count * sizeof(int));      //申请一个空数组
    Preorder(root, array, i);                             //遍历二叉树
    *returnSize = *i;
    return array;
}

1.2 小结

1.2.1 求二叉树结点的个数

int  TreeSize(struct TreeNode* root) {                           //判断二叉树有多少个结点
    if (root == NULL) {
        return 0;
    }
    return TreeSize(root->left) + TreeSize(root->right) + 1;
}  

  假设这个二叉树如下所示:
               在这里插入图片描述
第一次进到这个程序中:结点1不为NULL,返回的是TreeSize(结点2) + TreeSize(结点3) + 1;
运行TreeSize(结点2) :结点2不为NULL,返回的是TreeSize(结点4) + TreeSize(结点5) + 1;
运行TreeSize(结点4) :结点4不为NULL,返回的是TreeSize(NULL) + TreeSize(NULL) + 1,也就是返回的0 + 0 +1 =1;
返回上面一层TreeSize(结点5):结点5不为NULL,返回的是TreeSize(NULL) + TreeSize(NULL) + 1,也就是返回的0 + 0 +1 =1;目前TreeSize(结点2) 返回的值就是1+1+1 = 3;
运行TreeSize(结点3):结点3不为NULL,返回的是TreeSize(NULL) + TreeSize(结点6) + 1;
  运行TreeSize(结点6):结点6不为NULL,返回的是TreeSize(NULL) + TreeSize(NULL) + 1,也就是返回的0 + 0 +1 =1;目前TreeSize(结点3) 返回的值就是0+1+1 = 2;
 所以整体TreeSize(结点2) + TreeSize(结点3) + 1 = 3 + 2 + 1 = 6,也就计算出来了二叉树结点的个数。

1.2.2 使用指针时,未初始化变量初值

  使用指针时,未初始化变量初值,导致程序报错。

int n;
int *i = &n;

在这里插入图片描述

2. BM28 二叉树的最大深度

  要求:求给定二叉树的最大深度,深度是指树的根节点到任一叶子节点路径上节点的数量。最大深度是所有叶子节点的深度的最大值.
  这个题,没有什么思路,看视频讲解的方法,代码如下:

#include <stdio.h>
int maxDepth(struct TreeNode* root ){
    int n1 = 0;
    int n2 = 0;
    if (root == NULL) {
        return 0;
    }
    n1 = maxDepth(root->left);
    n2 = maxDepth(root->right);
    return n1 > n2 ?  n1 + 1 : n2 + 1;
}

  假设这个二叉树如下所示,还是以下面这个二叉树为例,看这个代码具体运行的步骤:
          在这里插入图片描述
第一次进到这个程序中:结点1(根结点)不为NULL,运行 n1 = maxDepth(根结点的左结点(结点2));
因为结点2不为NULL,此时传入结点2进入函数:运行n1 = maxDepth(结点2的左结点(结点4));
因为结点4不为NULL,此时传入结点4进入函数:运行n1 = maxDepth(结点4的左结点(NULL)),并返回了n1 =0。
因为结点4的左结点为NULL,程序会执行下面一句,n2 = maxDepth(结点4的右结点(NULL)),并返回了n2 =0。
所以对于结点4,n1 = n2=0,程序会返回1。这里也就是结点2的左结点,n1 = maxDepth(结点2的左结点(结点4)),这里的n1 = 1;
此时程序会返回到,结点2上面,运行n2 = maxDepth(结点2的右结点(结点5));
因为结点5不为NULL,此时传入结点5进入函数:运行n1 = maxDepth(结点5的左结点(NULL)),并返回了n1 =0。
因为结点5的左结点为NULL,程序会执行下面一句,n2 = maxDepth(结点5的右结点(NULL)),并返回了n2 =0。
所以对于结点5,n1 = n2=0,程序会返回1。这里也就是结点2的右结点,n2= maxDepth(结点2的右结点(结点5)),这里的n2 = 1;
此时对于结点2来说,n1=1,n2=1,所以会返回2。这里也就是结点1的左结点,n1 = maxDepth(结点1的左结点(结点2)),这里的n1 = 2;
此时程序会返回到,结点1上面,运行n2 = maxDepth(结点1的右结点(结点3));
因为结点3不为NULL,此时传入结点3进入函数:运行n1 = maxDepth(结点3的左结点(NULL)),并返回了n1 =0。
因为结点3的左结点为NULL,程序会执行下面一句,n2 = maxDepth(结点3的右结点(结点6))。
因为结点6不为NULL,此时传入结点6进入函数:运行n1 = maxDepth(结点6的左结点(NULL)),并返回了n1 =0。
因为结点6的左结点为NULL,程序会执行下面一句,n2 = maxDepth(结点6的右结点(NULL)),并返回了n2 =0。
所以对于结点6,n1 = n2 = 0,程序会返回1。这里也就是结点3的右结点,n2 = maxDepth(结点3的右结点(结点6)),这里的 n2 = 1;
此时对于结点3来说,n1 = 0,n2 = 1,所以会返回2。也就是结点1中的n2 = maxDepth(结点1的右结点(结点3)) = 2;
此时对于结点1来说,n1 = 2,n2 = 2,所以会返回3。程序结束,二叉树的最大深度是3。

3. BM29 二叉树中和为某一值的路径

  要求:给定一个二叉树root和一个值 sum ,判断是否有从根节点到叶子节点的节点值之和等于 sum 的路径。
1.该题路径定义为从树的根结点开始往下一直到叶子结点所经过的结点
2.叶子节点是指没有子节点的节点
3.路径只能从父节点到子节点,不能从子节点到父节点
4.总节点数目为n

               在这里插入图片描述

  这个题,也没有什么思路,看视频讲解的方法,代码如下:

bool bianli(struct TreeNode* root, int sum, int sum1){           //遍历一个子树,必须要返回一个值
    if (root == NULL) {
        return  false;
    }
    sum1 +=  root->val;                                          //求和
    if (root->left == NULL && root->right == NULL) {
        if (sum1 == sum){
            return true;
        }else{
            return false;
        }
    }
    bool leftHasPath  =   bianli(root->left, sum, sum1);
    bool rightHasPath =   bianli(root->right, sum, sum1);
    return  leftHasPath || rightHasPath;
}

bool hasPathSum(struct TreeNode* root, int sum){
    //如何遍历一个子树
    // int * arr = (int *)malloc(1000*sizeof(int)); 
    int a = 0;   //求和
    return bianli(root,sum,a);
}

  假设这个二叉树如下所示,还是以下面这个二叉树为例,看这个代码具体运行的步骤:(结点每一排依次称为结点1,2,3…)
 第一次进到这个程序中:结点1(根结点)不为NULL,sum1 = 5; 然后进入这一句:bool leftHasPath = bianli(结点2, 22, 5);
  sum1 = 5 + 4 = 9; bool leftHasPath = bianli(结点4, 22, 9); 这是结点3的左结点。
  sum1 = 9 + 1 = 10;return false; 返回上一层循环,返回到结点3, bool rightHasPath = bianli(结点5, 22, 9);因为到结点3的时候,sum1的值就是9。
  sum1 = 9 + 11 = 20; bool leftHasPath = bianli(结点7, 22, 20);
  sum1 = 20 + 2 = 22; return true;综上就是leftHasPath = false; rightHasPath = true;程序会继续运行,直到遍历完所有可能的路径。最终会返回true。
  改进代码如下,找到一条路径后就会停止(不会遍历所有的路径的):

bool findPath(struct TreeNode* node, int targetSum, int currentSum) {
    if (node == NULL) {
        return false;
    }
    currentSum += node->val;
    if (node->left == NULL && node->right == NULL && currentSum == targetSum) {
        return true;
    }
    bool foundInLeft = findPath(node->left, targetSum, currentSum);
    if (foundInLeft) {
        return true; // 找到路径,立即中断递归
    }
    bool foundInRight = findPath(node->right, targetSum, currentSum);
    if (foundInRight) {
        return true; // 找到路径,立即中断递归
    }
    return false; // 未找到路径
}

bool hasPathSum(struct TreeNode* root, int sum){
    //如何遍历一个子树
    // int * arr = (int *)malloc(1000*sizeof(int)); 
    int a = 0;   //求和
    return findPath(root,sum,a);
}

  假设这个二叉树如下所示,还是以下面这个二叉树为例,看这个代码具体运行的步骤:
               在这里插入图片描述
 第一次进到这个程序中:结点1(根结点)不为NULL,currentSum = 5; 然后进入这一句:bool foundInLeft = findPath(结点2, 22, 5);
 currentSum = 5 + 4 = 9; bool foundInLeft = findPath(结点4, 22, 9);
 currentSum = 9 + 1 = 10; bool foundInLeft = findPath(NULL, 22, 10); return false;并返回到了结点2了。
  bool foundInRight = findPath(结点5, 22, 9); currentSum = 9 + 11 = 20; bool foundInLeft = findPath(结点7, 22, 20);
 currentSum = 20 + 2 = 22; return true; 程序不会会继续运行,不会遍历完所有可能的路径。当找到路径后,递归会立即中断,从而停止遍历。

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

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

相关文章

HCIP——BGP协议

目录 一.什么是BGP&#xff1f; 二.IGP和EGP 三.BGP的特点 四.BGP的数据包 五.BGP的工作过程 BGP的六种状态机 六.BGP的路由黑洞问题 七.BGP的防环机制——水平分割 八.BGP的宣告问题 九.BGP的自动汇总 十.BGP的安全特性 十一.BGP的选路规则 一.什么是BGP&#xff1f; 1.…

ATF(TF-A)安全通告 TFV-8 (CVE-2018-19440)

安全之安全(security)博客目录导读 ATF(TF-A)安全通告汇总 目录 一、ATF(TF-A)安全通告 TFV-8 (CVE-2018-19440) 二、CVE-2018-19440 一、ATF(TF-A)安全通告 TFV-8 (CVE-2018-19440) Title 不保存x0~x3寄存器可能会将信息从一个非安全世界的SMC client泄漏到另一个 CVE ID …

学习ts(二)数据类型(接口和对象类型、数组类型)

interface 重名会重合到一起 如果两个interface名称相同&#xff0c;会把两个合到一起 重复定义同一个需要类型相同 不能多或者减少属性 设置任意key 当定义接口返回数据时&#xff0c;我们不确定接口会返回多少&#xff0c;知道所需要的固定属性&#xff0c;其余属性可以…

第九章 动态规划part08(代码随想录)

139.单词拆分 1. 确定dp[i][j] dp数组以及下标的含义一维dp数组的递推公式 dp[i] : 字符串长度为i的话&#xff0c;dp[i]为true&#xff0c;表示可以单词能被在字典中出现的单词组成。 dp[s.size()] true; 说明可以利用字典中出现的单词拼接出 s 。 2. 一维dp数组的递推公式…

【STM32 学习】电源解析(VCC、VDD、VREF+、VBAT)

VCC电源电压GND电源供电负电压&#xff08;通常接地&#xff09;VDD模块工作正电压VSS模块工作负电压VREFADC参考正电压VREF-ADC参考负电压VBAT电池或其他电源供电VDDA模拟供电正电压VSSA模拟供电负电压 一、VCC&#xff08;供电电压&#xff09; VCC是指芯片的电源电压&#…

linux安装mysql-8.0.33正确方式及常见问题

目录 获取mysql下载地址链接 解压安装包 复制文件到安装目录 添加用户和用户属组修改权限 创建存储数据的文件夹/usr/local/mysql 初始化安装 修改配置文件 创建日志文件并赋予对应权限 启动成功​编辑 创建软链接 之前安装过mysql&#xff0c;时间比较长忘记安装步骤了今天…

【C语言】memset()函数

一.memset()函数简介 我们先来看一下cplusplus.com - The C Resources Network网站上memset()函数的基本信息&#xff1a; 1.函数功能 memset()函数的功能是:将一块内存空间的每个字节都设置为指定的值。 这个函数通常用于初始化一个内存空间&#xff0c;或者清空一个内存空间…

HCIP第五节------------------------------------------ospf

一、OSPF基础 1、动态路由分类 2、距离矢量协议 运行距离矢量路由协议的路由器周期性地泛洪自己的路由表。通过路由的交互&#xff0c;每台路由器都从相邻的路由器学习到路由&#xff0c;并且加载进自己的路由表中&#xff0c;然后再通告给其他相邻路由器。 对于网络中的所有…

服务器数据恢复-EqualLogic存储RAID5数据恢复案例

服务器数据恢复环境&#xff1a; 一台DELL EqualLogic存储中有一组由16块SAS硬盘组建的RAID5阵列。存储存放虚拟机文件&#xff0c;采用VMFS文件系统&#xff0c;划分了4个lun。 服务器故障&检测&分析&#xff1a; 存储设备上有两个硬盘指示灯显示黄色&#xff0c;存储…

使用python读Excel文件并写入另一个xls模版

效果如下&#xff1a; 原文件内容 转化后的内容 大致代码如下&#xff1a; 1. load_it.py #!/usr/bin/env python import re from datetime import datetime from io import BytesIO from pathlib import Path from typing import List, Unionfrom fastapi import HTTPExcep…

炬芯科技发布全新第二代智能手表芯片,引领腕上新趋势!

2023年7月&#xff0c;炬芯科技宣布全新第二代智能手表芯片正式发布。自2021年底炬芯科技推出第一代的智能手表芯片开始便快速获得了市场广泛认可和品牌客户的普遍好评。随着技术的不断创新和突破&#xff0c;为了更加精准地满足市场多元化的变幻和用户日益增长的体验需求&…

二.net core 自动化发布到docker (Jenkins安装之后向导)

目录 ​​​​​​​​​​​​​​ 参考资料&#xff1a;https://www.jenkins.io/doc/book/installing/docker/#setup-wizard Post-installation setup wizard.(安装后安装向导) 基于上一篇文章安装&#xff0c;在安装并运行Jenkins&#xff08;不包括使用Jenkins Opera…

数据结构-单链表(C语言简单实现)

简介 以顺序结构进行数据存储时&#xff0c;它的特点就是可以用一组任意的存储单元存储数据元素&#xff0c;这组存储单元可以是连续的&#xff0c;也可以是不连续的&#xff0c;这些数据可以存在内存未被占用的任意位置。它也是有缺点的&#xff0c;就是在插入和删除时需要移…

SpringBoot、Java 使用 Jsoup 解析 HTML 页面

使用 Jsoup 解析 HTML 页面 什么是 Jsoup&#xff1f; Jsoup 是一个用于处理 HTML 页面的 Java 库&#xff0c;它提供了简单的 API&#xff0c;使得从 HTML 中提取数据变得非常容易。无论是获取特定标签的内容还是遍历整个页面的元素&#xff0c;Jsoup 都能轻松胜任。 如何使…

CI/CD流水线实战

不知道为什么&#xff0c;现在什么技术都想学&#xff0c;因为我觉得我遇到了技术的壁垒&#xff0c;大的项目接触不到&#xff0c;做的项目一个字辣*。所以&#xff0c;整个人心浮气躁&#xff0c;我已经得通过每天的骑行和长跑缓解这种浮躁了。一个周末&#xff0c;我再次宅在…

echarts图表的应用

1、echarts的简介 echarts 是国内的一个图表应用插件&#xff0c;只需要下载echarts的js 在js中引入。 echarts 的官网&#xff1a;https://echarts.apache.org/zh/index.html 进去之后点击这里&#xff0c; 点击下载按钮&#xff0c;下载文件&#xff0c;下载后解压&#xf…

如何卖 Click to WhatsApp 广告最有效

2022年&#xff0c;大多数直接面向消费者的品牌都面临相同挑战—— Facebook 和 Instagram 的广告成本大幅增加。Business Insider 报导指出&#xff0c;2021年 Facebook 广告每次点击的平均成本&#xff08;average cost per click&#xff09;达到0.974美元&#xff0c;按年升…

概念解析| 压缩感知:在稀疏的世界中寻找完整的信息

注1:本文系“概念解析”系列之一,致力于简洁清晰地解释、辨析复杂而专业的概念。本次辨析的概念是:压缩感知(Compressed Sensing)。 压缩感知:在稀疏的世界中寻找完整的信息 TI - Research - Applications - Compressed Sensing 一、背景介绍 在信息爆炸的时代,我们每天都…

AWS EKS 集群自动扩容 Cluster Autoscaler

文章目录 一&#xff0c;需求工作需求说明 二&#xff0c;部署精简命令执行1&#xff0c;要求2&#xff0c;查看EC2 Auto Scaling groups Tag3&#xff0c;创建Serviceaccount需要的Policy&#xff0c;Role4&#xff0c;部署Cluster Autoscaler5&#xff0c;验证6&#xff0c;常…

Verilog同步FIFO设计

同步FIFO(synchronous)的写时钟和读时钟为同一个时钟&#xff0c;FIFO内部所有逻辑都是同步逻辑&#xff0c;常常用于交互数据缓冲。 异步FIFO&#xff1a;数据写入FIFO的时钟和数据读出FIFO的时钟是异步的(asynchronous) 典型同步FIFO有三部分组成: &#xff08;1&#xff0…