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

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.mfbz.cn/a/80524.html

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

相关文章

Java教程:如何使用切面环绕方法对所有接口进行添加出入参日志保存功能

背景&#xff1a; ----在很多时候我们做开发时&#xff0c;往往只是提供一个对外接口来进行前后端调试&#xff0c;或第三方系统联调&#xff0c;并使用log进行日志打印&#xff0c;每当出现问题进行排查时&#xff0c;只需要查看服务器日志就可以定位到问题&#xff0c;从而解…

[Raspberry Pi]如何用VNC遠端控制樹莓派(Ubuntu desktop 23.04)?

之前曾利用VMware探索CentOS&#xff0c;熟悉Linux操作系統的指令和配置運作方式&#xff0c;後來在樹莓派價格飛漲的時期&#xff0c;遇到貴人贈送Raspberry Pi 4 model B / 8GB&#xff0c;這下工具到位了&#xff0c;索性跳過樹莓派官方系統(Raspberry Pi OS)&#xff0c;直…

使用 Python 在 NLP 中进行文本预处理

一、说明 自然语言处理 &#xff08;NLP&#xff09; 是人工智能 &#xff08;AI&#xff09; 和计算语言学的一个子领域&#xff0c;专注于使计算机能够理解、解释和生成人类语言。它涉及计算机和自然语言之间的交互&#xff0c;允许机器以对人类有意义和有用的方式处理、分析…

智能电视与win10电脑后续无法实现DLNA屏幕共享

问题背景&#xff1a; 我用的是TCL电视&#xff0c;但是并不是最新&#xff0c;打开的方式是U盘->电脑&#xff0c;各位看自己情况&#xff0c;很多问题都大概率是智能电视问题。 情景假设&#xff1a; 假设你已经完成原先智能电视该有的步骤&#xff0c;通过DLNA&#xf…

前馈神经网络正则化例子

直接看代码&#xff1a; import torch import numpy as np import random from IPython import display from matplotlib import pyplot as plt import torchvision import torchvision.transforms as transforms mnist_train torchvision.datasets.MNIST(root…

链游再进化 Web3版CSGO来袭

过去几年&#xff0c;游戏开发者们一直希望借Web3这个价值流通网络&#xff0c;改造传统游戏的经济系统&#xff0c;将虚拟资产的掌管权交给用户&#xff0c;让资产自由地在市场流通。 Web3游戏发展史上&#xff0c;涌现过CryptoKitties、Axie Infinity两大爆款&#xff0c;但…

爬虫框架- feapder + 爬虫管理系统 - feaplat 的学习简记

文章目录 feapder 的使用feaplat 爬虫管理系统部署 feapder 的使用 feapder是一款上手简单&#xff0c;功能强大的Python爬虫框架 feapder 官方文档 文档写的很详细&#xff0c;可以直接上手。 基本命令&#xff1a; 创建爬虫项目 feapder create -p first-project创建爬虫 …

LRU算法源码实现

算法介绍&#xff1a; 最近最久未使用&#xff08;Least Recently Used LRU&#xff09;算法是⼀种缓存淘汰策略。该算法的思路是&#xff0c;将最近一段时间内最久未使用的页面置换出去。 升级版LRUK算法见 基于LRU-K算法设计本地缓存实现流量削峰https://blog.csdn.net/l…

Deep Learning With Pytorch - 最基本的感知机、贯序模型/分类、拟合

文章目录 如何利用pytorch创建一个简单的网络模型&#xff1f;Step1. 感知机&#xff0c;多层感知机&#xff08;MLP&#xff09;的基本结构Step2. 超平面 ω T ⋅ x b 0 \omega^{T}xb0 ωT⋅xb0 or ω T ⋅ x b \omega^{T}xb ωT⋅xb感知机函数 Step3. 利用感知机进行决策…

虚拟机问题

虚拟机无法识别USB设备 经排查为VMware USB Arbitration Service 没有启动,但是VMware USB Arbitration Service依赖于VMware Workstation Server启动 VMware USB Arbitration Service(VMUSBArbService)是由 VMware 虚拟化软件提供的一个服务,用于协调和管理主机系统上的…

Flink CDC系列之:基于 Flink CDC 构建 MySQL 和 Postgres 的 Streaming ETL

Flink CDC系列之&#xff1a;基于 Flink CDC 构建 MySQL 和 Postgres 的 Streaming ETL 一、技术路线二、MySQL数据库建表三、PostgreSQL数据库建表四、在 Flink SQL CLI 中使用 Flink DDL 创建表五、关联订单数据并且将其写入 Elasticsearch 中六、Kibana查看商品和物流信息的…

leetcode611. 有效三角形的个数(java)

有效三角形的个数 有效三角形的个数排序加二分排序 双指针 上期算法 有效三角形的个数 给定一个包含非负整数的数组 nums &#xff0c;返回其中可以组成三角形三条边的三元组个数。 示例 1: 输入: nums [2,2,3,4] 输出: 3 解释:有效的组合是: 2,3,4 (使用第一个 2) 2,3,4 (使…

如何修复损坏的DOC和DOCX格式Word文件?

我们日常办公中&#xff0c;经常用到Word文档。但是有时会遇到word文件损坏、无法打开的情况。这时该怎么办&#xff1f;接着往下看&#xff0c;小编在这里就给大家带来最简单的Word文件修复方法&#xff01; 很多时候DOC和DOCX Word文件会无缘无故的损坏无法打开&#xff0c;一…

【C++ 记忆站】引用

文章目录 一、引用概念二、引用特性1、引用在定义时必须初始化2、一个变量可以有多个引用3、引用一旦引用一个实体&#xff0c;再不能引用其他实体 三、常引用四、使用场景1、做参数1、输出型参数2、大对象传参 2、做返回值1、传值返回2、传引用返回 五、传值、传引用效率比较六…

【C语言】每日一题(找到所有数组中消失的数字)

找到所有数组中消失的数字&#xff0c;链接奉上。 这里简单说一下&#xff0c;因为还没有接触到动态内存&#xff0c;数据结构&#xff0c;所以知识有限&#xff0c;也是尽力而为&#xff0c;结合题库的评论区找到了适合我的解法&#xff0c;以后有机会&#xff0c;会补上各种…

图数据库_Neo4j中文版_Centos7.9安装Neo4j社区版3.5.9_基于jdk1.8---Neo4j图数据库工作笔记0012

由于我们在国内使用啊,具体还是要用中文版滴,找了好久这个neo4j,原来还是有中文版的, https://we-yun.com/doc/neo4j-chs/ 中文版下载地址在这里: 所有版本都在这里了,需要哪个自己去下载就可以了,要注意下载以后,参考: https://we-yun.com/blog/prod-56.html 在这个位置下载…

画质提升+带宽优化,小红书音视频团队端云结合超分落地实践

随着视频业务和短视频播放规模不断增长&#xff0c;小红书一直致力于研究&#xff1a;如何在保证提升用户体验质量的同时降低视频带宽成本&#xff1f; 在近日结束的音视频技术大会「LiveVideoStackCon 2023」上海站中&#xff0c;小红书音视频架构视频图像处理算法负责人剑寒向…

2023.8 - java - 对象和类

public class Dog {String breed;int size;String colour;int age;void eat() {}void run() {}void sleep(){}void name(){} } 一个类可以包含以下类型变量&#xff1a; 局部变量&#xff1a;在方法、构造方法或者语句块中定义的变量被称为局部变量。变量声明和初始化都是在方…

实现Java异步调用的高效方法

文章目录 为什么需要异步调用&#xff1f;Java中的异步编程方式1. 使用多线程2. 使用Java异步框架 异步调用的关键细节结论 &#x1f389;欢迎来到Java学习路线专栏~实现Java异步调用的高效方法 ☆* o(≧▽≦)o *☆嗨~我是IT陈寒&#x1f379;✨博客主页&#xff1a;IT陈寒的博…

LabVIEW开发最小化5G系统测试平台

LabVIEW开发最小化5G系统测试平台 由于具有大量存储能力和数据的应用程序的智能手机的激增&#xff0c;当前一代产品被迫提高其吞吐效率。正交频分复用由于其卓越的品质&#xff0c;如单抽头均衡和具有成本效益的实施&#xff0c;现在被广泛用作物理层技术。这些好处是以严格的…
最新文章