文章目录

前序遍历的思想。
思路:先判断左右节点是否存在,再判断根分别和左右节点的值是
否相等。
1.如果左子节点存在,但是值不等于根节点的值,返回false
2.如果右子节点存在,但是值不等于根节点的值,返回false
如果相等,递归其左子节点和右子节点。
不拿如果子节点的值等于根节点的值这个条件来判断的原因是:
就算子节点的值和根节点的相等,也不能代表什么,因为还需要判断下一层子节点的值都与它们的根节点的值相等才行,这样才能达到判断整棵树的值都相等的效果。
即:先判断结构,再判断值
注意:如果根节点为空,返回true,特殊情况特殊处理。
//思路:前序遍历的思想,根先与左右比较,如果不同,直接返回假
//再让左子树与左子树的左右子树比较,这样分治下去
bool isUnivalTree(struct TreeNode* root)
{
//空树返回真,因为最后叶子节点的左右子树都为空
if(root == NULL)
{
return true;
}
//两个不能写反了,先判断是否为空再比较数据
if(root->left!=NULL && root->left->val != root->val)
{
return false;
}
if(root->right!=NULL && root->right->val != root->val)
{
return false;
}
return isUnivalTree(root->left)
&& isUnivalTree(root->right);
}
思路:分别递归根节点的左子节点和右子节点,每次递归一层就计算一层深度,然后比较左右子节点的高度,让大的值+1,(+1是加根节点自己的高度)

//思路:前序遍历的思想+分治算法
//把整棵树看作根左子树右子树组成,先计算左子树的高度和右子树的高度,
//比较之后,大的再加上自己的高度
//左子树又让左子树的左右子树比较高度
int maxDepth(struct TreeNode* root)
{
if(root == NULL)
{
return 0;
}
//注意:千万不能写成:
//return maxDepth(root->left)>maxDepth(root->right)?maxDepth(root->left)+1:maxDepth(root->right)+1;
//这样写虽然能通过,但是效率大大降低,因为同样的事情重复了好多次
int lheight = maxDepth(root->left);
int rheight = maxDepth(root->right);
return lheight>rheight?lheight+1:rheight+1;
}
思路:后序遍历的思想,先从最底层开始交换:
root->left = right,root->right = left
如果递归到叶子节点了,该叶子节点的左右子树都为NULL,交换它们结果是一样的
所以最底层交换完了,回到上一层,左子树交换完了,到右子树,最后返回根节点即可
//思路:后序遍历的思想,先从最底层开始交换:
//root->left = right,root->right = left
//如果递归到叶子节点了,该叶子节点的左右子树都为NULL,交换它们结果是一样的
//所以最底层交换完了,回到上一层,左子树交换完了,到右子树,最后返回根节点即可
struct TreeNode* invertTree(struct TreeNode* root)
{
if(root == NULL)
{
return NULL;
}
struct TreeNode*left = invertTree(root->left);
struct TreeNode*right = invertTree(root->right);
root->left = right;
root->right = left;
return root;
}

思路:最好是前序遍历:只要从根节点开始,有一个节点的结构不相同,或者值不相同,都返回假
先判断结构,再判断值
判断值的时候,如果值为真,也没有什么意义,因为还需要不断往下比较
所以应该判断值为假,返回false比较合适
//思路:最好是前序遍历:只要从根节点开始,有一个节点的结构不相同,或者值不相同,都返回假
//先判断结构,再判断值
//判断值的时候,如果值为真,也没有什么意义,因为还需要不断往下比较
//所以应该判断值为假,返回false比较合适
bool isSameTree(struct TreeNode* p, struct TreeNode* q)
{
//1.先判断结构
//两个都是空树,返回真
if(p == NULL && q == NULL)
{
return true;
}
//来到这里,必有一假,其中一个是空树,返回假
if(p == NULL || q == NULL)
{
return false;
}
//2.结构判断完了,判断值
if(p->val!= q->val )
{
return false;
}
return isSameTree(p->left,q->left) && isSameTree(p->right,q->right);
}
思路:根节点无需判断,应该写一个函数单独判断两颗子树是否对称的问题
对称问题其实就是判断两颗子树是否相同问题的变形,判断两颗子树是否相同,就是递归两个子树的左和左,右和右,
判断两颗子树是否对称,是递归两个子树的左和右,右和左
先判断结构对称,再判断数据对称
bool isSymmetricalBinaryTree(struct TreeNode* l,struct TreeNode* r)
{
//两个都为空
if(!l && !r)
{
return true;
}
//其中一个为空
if(l == NULL || r == NULL)
{
return false;
}
//都不为空
if(l->val!=r->val)
{
return false;
}
return isSymmetricalBinaryTree(l->left,r->right) &&isSymmetricalBinaryTree(l->right,r->left);
}
bool isSymmetric(struct TreeNode* root)
{
//题目说了不是空树
// if(root == NULL)
// {
// return true;
// }
return isSymmetricalBinaryTree(root->left,root->right);
}

这道题是IO型,需要完全实现输入输出。
思路:按照题目要求,按前序遍历的思想建立一棵树。
然后以中序遍历打印出来,注意:打印完后需要销毁树。
#include <stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef char BTDataType;
struct BTNode
{
struct BTNode*left;
struct BTNode*right;
BTDataType data;
};
struct BTNode* CreatTree(BTDataType*a,int *pi)
{
//(*pi)++不能放在判断这里++,要放在里面,因为如果a[*pi]不为'#',也一样++了,到下面pi这里就++两次了。
if(a[(*pi)] =='#')
{
(*pi)++;
return NULL;
}
struct BTNode*root = (struct BTNode*)malloc(sizeof(struct BTNode));
assert(root!=NULL);
root->data = a[(*pi)++];
root->left = CreatTree(a,pi);
root->right = CreatTree(a,pi);
return root;
}
void InOrder(struct BTNode*root)
{
if(root == NULL)
{
return ;
}
InOrder(root->left);
printf("%c ",root->data);
InOrder(root->right);
}
void BTDestroy(struct BTNode*root)
{
if(root == NULL)
{
return ;
}
BTDestroy(root->left);
BTDestroy(root->right);
free(root);
//置空没效果
root = NULL;
}
int main() {
BTDataType a[100];
scanf("%s",a);
int i =0;
struct BTNode*root = CreatTree(a,&i);
InOrder(root);
BTDestroy(root);
root = NULL;
return 0;
}
最近在学习CAN,记录一下,也供大家参考交流。推荐几个我觉得很好的CAN学习,本文也是在看了他们的好文之后做的笔记首先是瑞萨的CAN入门,真的通透;秀!靠这篇我竟然2天理解了CAN协议!实战STM32F4CAN!原文链接:https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252CAN详解(小白教程)原文链接:https://blog.csdn.net/xwwwj/article/details/105372234一篇易懂的CAN通讯协议指南1一篇易懂的CAN通讯协议指南1-知乎(zhihu.com)视频推荐CAN总线个人知识总
Transformers开始在视频识别领域的“猪突猛进”,各种改进和魔改层出不穷。由此作者将开启VideoTransformer系列的讲解,本篇主要介绍了FBAI团队的TimeSformer,这也是第一篇使用纯Transformer结构在视频识别上的文章。如果觉得有用,就请点赞、收藏、关注!paper:https://arxiv.org/abs/2102.05095code(offical):https://github.com/facebookresearch/TimeSformeraccept:ICML2021author:FacebookAI一、前言Transformers(VIT)在图
关闭。这个问题不符合StackOverflowguidelines.它目前不接受答案。我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。关闭3年前。Improvethisquestion我正处于学习Ruby的阶段,我想查看一些小型库的源代码以了解它们是如何构建的。我不知道什么是小型图书馆,但希望SO能推荐一些易于理解的图书馆来学习。因此,如果有人知道一两个非常小的库,这是新手Rubyists学习的好例子,请推荐!我想使用Manveru'sInnatelib,因为它试图保持在2000LOC以下,但我还不熟悉其中经常使用的Ruby速记。也许大约100-5
由于匿名block和散列block看起来大致相同。我正在玩它。我做了一些严肃的观察,如下所示:{}.class#=>Hash好的,这很酷。空block被视为Hash。print{}.class#=>NilClassputs{}.class#=>NilClass为什么上面的代码和NilClass一样,下面的代码又显示了Hash?puts({}.class)#Hash#=>nilprint({}.class)#Hash=>nil谁能帮我理解上面发生了什么?我完全不同意@Lindydancer的观点你如何解释下面几行:print{}.class#NilClassprint[].class#A
我一直在尝试在Ruby中实现BinaryTree类,但我得到了stackleveltoodeep错误,尽管我似乎没有在该特定代码段中使用任何递归:1.classBinaryTree2.includeEnumerable3.4.attr_accessor:value5.6.definitialize(value=nil)7.@value=value8.@left=BinaryTree.new#stackleveltoodeephere9.@right=BinaryTree.new#andhere10.end11.12.defempty?13.(self.value==nil)?true:
我很难理解Ruby中sender和receiver的实际含义。它们一般是什么意思?到目前为止,我只是将它们理解为方法调用和获取其返回值的调用。但是,我知道我的理解还远远不够。谁能给我一个Ruby中发送者和接收者的具体解释? 最佳答案 面向对象中的一个核心概念是消息传递和早期概念化,这在很大程度上借鉴了计算的Actor模型。艾伦·凯(AlanKay)创造了面向对象一词并发明了最早的OO语言之一SmallTalk,他拥有voicedregretatusingatermwhichputthefocusonobjectsinsteadofo
rails新手。只是想了解\assests目录中的这两个文件。例如,application.js文件有如下行://=requirejquery//=requirejquery_ujs//=require_tree.我理解require_tree。只是将所有JS文件添加到当前目录中。根据上下文,我可以看出requirejquery添加了jQuery库。但是它从哪里得到这些jQuery库呢?我没有在我的Assets文件夹中看到任何jquery.js文件——或者直接在我的整个应用程序中没有看到任何jquery.js文件?同样,我正在按照一些说明安装TwitterBootstrap(http:
我在某些代码中遇到了三元组,但我无法理解条件:str.split(/',\s*'/).mapdo|match|match[0]==?,?match:"somestring"end.join我确实理解我是在某些点上拆分字符串并将总结果转换为数组,然后依次处理数组的每个元素。除此之外,我不知道发生了什么。 最佳答案 一种(稍微)不那么令人困惑的写法是:str.split(/',\s*'/).mapdo|match|ifmatch[0]==?,matchelse"somestring"endend.join我认为多行三元语句很糟糕,尤其是
有没有人成功地将S3存储桶读取为子文件夹?文件夹1--子文件夹2----文件3----文件4--文件1--文件2文件夹2--子文件夹3--文件5--文件6我的任务是读取文件夹1。我希望看到子文件夹2、文件1和文件2,但看不到文件3或文件4。现在,因为我将存储桶键限制为prefix=>'folder1/',你仍然会得到file3和4,因为它们在技术上具有folder1前缀。似乎真正做到这一点的唯一方法是吸收folder1下的所有键,然后使用字符串搜索从结果数组中实际排除file3和file4。有没有人有过这方面的经验?我知道像Transmit和Cyberduck这样的FTP风格的S3
关于yolov5训练时参数workers和batch-size的理解yolov5训练命令workers和batch-size参数的理解两个参数的调优总结yolov5训练命令python.\train.py--datamy.yaml--workers8--batch-size32--epochs100yolov5的训练很简单,下载好仓库,装好依赖后,只需自定义一下data目录中的yaml文件就可以了。这里我使用自定义的my.yaml文件,里面就是定义数据集位置和训练种类数和名字。workers和batch-size参数的理解一般训练主要需要调整的参数是这两个:workers指数据装载时cpu所使