当前位置: 首页 > wzjs >正文

cad线下培训班海南网站seo

cad线下培训班,海南网站seo,链家网的网站开发费用大概多少钱,设计类哪个专业好目录 1 另一棵树的子树 1) 题目描述 示例1: 示例2: 2) 算法解析 3) 代码 2 二叉树的遍历 1) 问题描述 2) 算法解析 3) 代码 3 总结 1 另一棵树的子树 leetcode链接…

目录

1  另一棵树的子树 

 1) 题目描述

示例1:

示例2:

2) 算法解析

3) 代码

2  二叉树的遍历

1) 问题描述

2) 算法解析

3) 代码

3  总结  


1  另一棵树的子树 

leetcode链接https://leetcode.cn/problems/subtree-of-another-tree/description/


 1) 题目描述

  给你两棵二叉树 root 和 subRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。如果存在,返回 true ;否则,返回 false 。

  二叉树 tree 的一棵子树包括 tree 的某个节点和这个节点的所有后代节点。tree 也可以看做它自身的一棵子树。

示例1:

输入:root = [3,4,5,1,2], subRoot = [4,1,2]
输出:true

示例2:

输入:root = [3,4,5,1,2,null,null,null,null,0], subRoot = [4,1,2]
输出:false

  该题目是想让你判断 root 这棵树中是否有 subRoot 这棵树,不管是相同的树,还是左子树中有与subRoot 相同的树或者是在右子树中有与 subRoot 相同的树,subRoot 都算是 root 的子树。


2) 算法解析

  该题目可以采用递归算法来解决。这道题的解决需要使用到前一篇文章里的相同的树的算法,因为判断 subRoot 是否是 root 的子树,本质上就是判断 root 里是否有与 subRoot 相同的树,具体算法思想描述如下:
  该递归算法可以抽象为 root 的左子树里是否有与 subRoot 相同的树或者右子树里是否有与 subRoot 相同的树,这个就是递归解决该问题的过程。边界条件共有两条:(1) 如果 root 本身是一棵空树,那么 root 里肯定没有与 subRoot 相同的树,直接返回 false;(2) 如果 root 这棵树本身就是与 subRoot 相同的树,说明 subRoot 是 root 的一棵子树,那就返回 true。


3) 代码

typedef struct TreeNode TreeNode;//判断相同的树bool isSameTree(TreeNode* p, TreeNode* q){if (p == NULL && q == NULL){return true;}if (p == NULL || q == NULL){return false;}if (p->val != q->val){return false;}return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);}bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot) 
{//如果root为空,那就返回falseif (root == NULL){return false;}//如果两个结点对应的树是相同的树,返回trueif (isSameTree(root, subRoot)){return true;}//判断subRoot是否是左子树或者右子树的子树return isSubtree(root->left, subRoot) || isSubtree(root->right, subRoot);
}

2  二叉树的遍历

leetcode链接https://leetcode.cn/problems/binary-tree-preorder-traversal/description/


1) 问题描述

  给你二叉树的根节点 root ,返回它节点值的 前序 遍历。

  这里看似是一个简单的前序遍历,但是其实没有那么简单,我们来看一下函数头部:

int* preorderTraversal(struct TreeNode* root, int* returnSize) 
{}

  可以看到其返回值为 int* ,也就是一个指针,并不像之前我们写过的前序遍历一样返回值为 void。实际上这里是需要返回一个存储了节点前序遍历值的数组,所以返回值才为 int*。


2) 算法解析

  这里最大的难点就在与如何将前序遍历的结果存储在数组里面,而且所给的函数头部里面也有一个 returnSize 参数,通过名字可以看出来,该参数的作用实际上就是返回数组的大小,所以我们不仅需要将数组返回,还得计算数组中有多少元素,也就是二叉树里面有多少节点。所以我们需要首先计算二叉树里面节点的个数(在链式二叉树文章中提到过相关操作的实现),所以这里总共需要 3 个函数:

(1) TreeSize函数:用来计算二叉树里面节点的个数。

(2) PreOrder函数:用来进行前序遍历,将结果存储在数组中。

(3) preorderTraversal函数:用来创建数组,返回存储结果的数组。

  接下来我们来讲解如何将前序遍历的结果存储在数组中。

  可能开始我们想的是按照前序遍历的代码,只需将打印的地方改为向数组中存储值即可:

void PreOrder(TreeNode* root, int* arr)
{int i = 0;if (root == NULL){return;}arr[i] = root->val;i++;PreOrder(root->left, arr);PreOrder(root->right, arr);
}

但是这样会存在一个问题,就是在不断递归的过程中,每次进入新的递归的时候,里面的 i 都会变成0,也就是总是往 arr[0] 位置存储前序遍历的结果,这里借助函数栈帧(每次调用函数时,会新开辟的一块空间,每个函数的空间是独立的)的概念来解释:

可以看到每次调用PreOrder函数,都会新开辟一块空间,所以其实里面的 i 都是属于不用空间的,一个 i 改变并不会影响另一个函数里面的 i ,所以每次递归调用函数 i 都是为 0 的。

  那么要想在递归过程中改变这个下标,我们就需要传递一个整形的地址,让其能够找到存储 arr 下标的空间,让存储空间里面的值改变,就会让下标随着递归的而改变了

//arr为数组收元素的地址,pi为存储arr数组下标的地址
void PreOrder(TreeNode* root, int* arr, int* pi)
{if (root == nullptr){return;}arr[(*pi)++] = root->val;PreOrder(root->left);PreOrder(root->right);
}

这里就可以通过一个指针变量 pi 来指向存储 arr 数组下标的空间(传参时传递一个值为 0 的整型的地址即可), 这样通过 pi 就可以间接改变 arr 数组中的值了。


3) 代码

typedef struct TreeNode TreeNode;//先计算树的结点个数,依结点个数开辟数组空间int TreeSize(TreeNode* root){if (root == NULL){return 0;}return 1 + TreeSize(root->left) + TreeSize(root->right);}
//将前序遍历的序列存入数组中
void PreOrder(TreeNode* root, int* arr, int* pi)
{if (root == NULL){return;}arr[(*pi)++] = root->val;//遍历左子树PreOrder(root->left, arr, pi);//遍历右子树PreOrder(root->right, arr, pi);
}
int* preorderTraversal(struct TreeNode* root, int* returnSize) 
{*returnSize = TreeSize(root);int* arr = (int*)malloc(sizeof(int) * (*returnSize));if (arr == NULL){perror("malloc fail!\n");exit(1);}int n = 0;PreOrder(root, arr, &n);return arr;
}

3  总结  

  在该题目中,我们解决了如何在递归过程中向数组中存储数据的问题。只需用一个指针变量间接改变即可。所以以后如果遇到类似问题,一定要想到利用指针来改变下标。

  当然,除了前序遍历,还有中序遍历和后序遍历,在讲解完前序遍历之后,相信这两个遍历也很简单了,可以自己尝试一下:
中序遍历https://leetcode.cn/problems/binary-tree-inorder-traversal/代码:

typedef struct TreeNode TreeNode;//返回树的结点个数int TreeSize(TreeNode* root){if (root == NULL){return 0;}return 1 + TreeSize(root->left) + TreeSize(root->right);}
//中序遍历树,把遍历数据存放在数组里面
void InOrder(TreeNode* root, int* arr, int* pi)
{if (root == NULL){return;}InOrder(root->left, arr, pi);arr[(*pi)++] = root->val;InOrder(root->right, arr, pi);
}int* inorderTraversal(struct TreeNode* root, int* returnSize) 
{*returnSize = TreeSize(root);int* arr = (int*)malloc(sizeof(int) * (*returnSize));if (arr == NULL){perror("malloc fail!\n");exit(1);}int n = 0;InOrder(root, arr, &n);return arr;
}

后序遍历https://leetcode.cn/problems/binary-tree-postorder-traversal/description/代码:

typedef struct TreeNode TreeNode;//求节点个数int TreeSize(TreeNode* root){if (root == NULL){return 0;}return 1 + TreeSize(root->left) + TreeSize(root->right);}//二叉树的后序遍历并将遍历结果保存到数组中
void PostOrder(int* arr, TreeNode* root, int* i)
{if (root == NULL){return;}//遍历左子树PostOrder(arr, root->left, i);//遍历右子树PostOrder(arr, root->right, i);arr[(*i)++] = root->val;}int* postorderTraversal(struct TreeNode* root, int* returnSize) {*returnSize = TreeSize(root);//根据二叉树节点空间开辟数组int* arr = (int*)malloc(sizeof(int) * (*returnSize));int i = 0;PostOrder(arr, root, &i);return arr;
}
http://www.dtcms.com/wzjs/597581.html

相关文章:

  • 小说短篇做的好的网站怎么用VS2012建设网站
  • 做网站哪个语言好企业网站一般做多宽
  • 网站平台建设情况汇报电子简历表格 个人简历
  • 深圳网站建设专业乐云seo做偏门网站
  • 高端网站建设软件开发巨鹿网站建设设计
  • 网站备案资料 下载沈阳网站备案查询
  • 做多级分销的网站wordpress 解析
  • 企业网站商城建设方案高端营销网站建设
  • 怎么做网站的seo天津各区房价一览表
  • 软件外包公司招聘苏州seo怎么做
  • 网站开发职业生涯规划书百度主页面
  • 营销展示型网站模板电子商务网站建设参考文献2018
  • 建设银行网站怎么查开户行海兴县做网站
  • 浏览器怎样屏蔽网站ajax分页 WordPress
  • 湘潭网站建设 安全还踏实磐石网络自己设计虚拟人物app
  • 视频网站建设流程seo网站设计
  • 做那种的视频网站知名门户网站
  • php 导航网站模板网站 知乎
  • 手机wap网站免费建站青岛公司注册网站
  • 网站开发设计思路文档wordpress安装使用教程
  • 重庆网站优化网络服务crm免费版
  • 网站关键词排名分析微信上可以做网站吗
  • 创建公司网站需要准备哪些素材网页小游戏手机版
  • 网站后台的制作阳江招聘网最新消息今天招聘
  • 登录贵州省住房和城乡建设厅网站网站建设的初步预算
  • 苏州网站定制公司推广获客
  • wordpress外贸网站好用的模板下载淘宝客优惠卷网站怎么做的
  • 做电影网站怎么赚钱手机可以开发网站
  • 电子商务网站设计的书最简单的做网站
  • 外贸网站建设不可缺少的灵活性学习网站开发体会与感想