大数据最全【数据结构】有妙手、本手、俗手?这7道二叉树题(3),2024年最新2024年互联网大厂大数据开发面经总结

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以戳这里获取

🌍题目描述:给你一个二叉树的根节点 root , 检查它是否轴对称。

在这里插入图片描述

💫关键思路:

  • ➡️ 本题目可复用上题的思路
  • 只需把树拆开看成左子树右子树两棵树,再复用相同树的代码即可

💥特别注意:

  • 注意对称的问题
    • 左树的左子树是和右树的右子树相比较的
    • 左树的右子树是和右树的左子树相比较的

代码实现💡:

bool issam(struct TreeNode\* q,struct TreeNode\* p)
{
    if(p == NULL && q == NULL)
      return true;
    if(p == NULL || q == NULL)
      return false;
    if(q->val != p->val)
      return false;
    return issam(q->left,p->right) && issam(q->right,p->left);
}
bool isSymmetric(struct TreeNode\* root){
    if(root==NULL)
        return true;
    return issam(root->left,root->right);
}

🛫难度提升

🌍第4️⃣题:另一棵树的子树【难度:中等】

🏷️力扣地址:🌈572. 另一棵树的子树

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

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

在这里插入图片描述
💫关键思路:

  • 原树中的所有子树找出来和SubRoot进行比较一下就可以了

💥特别注意::

  • 判断 t 是否和树 s 的任意子树相等。那么就转化成🌈100. 相同的树
    即可,这个题的做法就是在 s 的每个子节点上,判断该子节点是否和 t 相等

  • 判断两个树是否相等的三个条件是的关系,即:

    • 1️⃣当前两个树的根节点值相等
    • 2️⃣并且,s 的左子树和 t 的左子树相等;
    • 3️⃣并且,s 的右子树和 t 的右子树相等
  • 而判断 t 是否为 s 的子树的三个条件是的关系,即:

    • 1️⃣ 当前两棵树相等
    • 2️⃣ 或者,t 是 s 的左子树;
    • 3️⃣ 或者,t 是 s 的右子树。

我们发现:判断 是否是相等的树 与 是否是子树 的代码简直是对称美啊~
请添加图片描述

🌠动图解析:👇🏻

请添加图片描述

代码实现💡:

bool isSameTree(struct TreeNode\* p, struct 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){
    if(root==NULL)
      return false;
    //遍历跟,和所有的子树都比较一遍
    if(isSameTree(root,subRoot))
      return true;
  
    //但凡有一个相等就认为是我的子树
    return isSubtree(root->left,subRoot)||isSubtree(root->right,subRoot);
}

🌍第5️⃣题:二叉树的前序遍历【难度:中等】

🏷️力扣地址:🌈144. 二叉树的前序遍历

同学们卡到这里心想:二叉树的前序不就那三步吗?好戏还在后头

🌍题目描述:给你二叉树的根节点 root ,返回它节点值的 前序 遍历。

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

题目要求的不是要把前序的值打印一下,而是把前序的结果放在malloc的数组

  • returnSize是输出型参数,与root不同,要解引用,外面要拿取数据

在这里插入图片描述

💫关键思路:

  • 先把TreeSize函数输出给returnSize,然后malloc一个数组a,下标为i
  • 定义 preorder 表示当前遍历到 root 节点的答案。按照定义,我们只要首先将 root 节点的值数组下标i加入答案,然后递归调用 preorder(root->left,a,i) 来遍历 root 节点的左子树,最后递归调用 preorder(root->right,a,i) 来遍历 root 节点的右子树即可,递归终止的条件为碰到空节点。

❌意料之外报错:

在这里插入图片描述

💥特别注意:

  • 当root递归左子树的时候,左子树的i++,不影响root的i(因为i是局部变量),所以左右子树的i都相同,放进数组里会放在同一个位置。
  • 也就说:不是一个i在往后走

在这里插入图片描述

对此我们可以传i的地址解引用i,使得只有一个i走完全程。

代码实现💡:

int TreeSize(struct TreeNode\* root)
{
    return root == NULL? 0 :TreeSize(root->left)+TreeSize(root->right)+1;
}

void preorder(struct TreeNode\* root,int \*a,int \*pi)
{
    if(root==NULL)
      return;
    a[(\*pi)++]=root->val;
    preorder(root->left,a,pi);
    preorder(root->right,a,pi);
}

int\* preorderTraversal(struct TreeNode\* root, int\* returnSize){
    \* returnSize =TreeSize(root);
    int\* a = (int\*)malloc(\* returnSize \* sizeof(int));
    int i=0;
    preorder(root,a,&i);

    return a;
}

🌍第6️⃣题:二叉树遍历 【难度:中等】

🏷️地址:🌈KY11 二叉树遍历

🌍题目描述:编一个程序,读入用户输入的一串先序遍历字符串,根据此字符串建立一个二叉树(以指针方式存储)。 例如如下的先序遍历字符串: ABC##DE#G##F### 其中“#”表示的是空格,空格字符代表空树。建立起此二叉树以后,再对二叉树进行中序遍历输出遍历结果。

  • 输入描述:
    输入包括1行字符串,长度不超过100
  • 输出描述:
    可能有多组测试数据,对于每组数据, 输出将输入字符串建立二叉树后中序遍历的序列,每个字符后面都有一个空格。 每个输出结果占一行。

在这里插入图片描述

🌠画图解析:👇🏻

在这里插入图片描述

💫关键思路:

  • 使用数组的值依次按先序遍历分治思想,递归构建二叉树,构建二叉树先malloc出根节点然后再构建左子树,右子树即可。
  • 字符串需要构建之后str【(*pi)++】不断找到下一个字符,当指向‘#’代表到了空节点了完成返回NULL即可,
  • 若非空,则开创一个节点,递归构建左右子树

💥特别注意:

如果有不理解的地方,可以去画递归展开图多尝试理解

代码实现💡:

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

typedef char BTDataType;
typedef struct BinaryTreeNode
{
	BTDataType data;
	struct BinaryTreeNode\* left;
	struct BinaryTreeNode\* right;
}BTNode;

BTNode\* BuyNode(BTDataType x)
{
	BTNode\* node = (BTNode\*)malloc(sizeof(BTNode));
	assert(node);

	node->data = x;
	node->left = NULL;
	node->right = NULL;
	return node;
}
BTNode\* CreateTree(char\*str,int \*pi)
{
    if(str[\*pi]=='#')
    {
        (\*pi)++;
         return NULL;
    }
    BTNode\*root=BuyNode(str[(\*pi)++]);
    
    root->left=CreateTree(str, pi);
    root->right=CreateTree(str, pi);
    return root;
}
void InOrder(BTNode\*root)
{
    if(root==NULL)
        return ;
    InOrder(root->left);
    printf("%c ",root->data);
    InOrder(root->right);    
}

int main()
{
    char str[100];
    scanf("%s",str);
    int i=0;
    BTNode\* root = CreateTree(str, &i);
    InOrder(root);
}

🌍第7️⃣题:判断二叉树是否为完全二叉树 【难度:中等】

🌈科普:

  • 完全二叉树也就是没有满的满二叉树,它的节点在每一层一定是连续分布的。如果出现哪一层中两个非空节点间隔一个空节点,那一定不是完全二叉树。如下图所示👇🏻

在这里插入图片描述

假设这棵完全二叉树有K层,因此我们可以总结一下完全二叉树的规律

  • 前K-2层:每个节点都有两个孩子,节点饱和
  • 前K-1层:节点肯定是饱和的—>到达了最大值
  • 第K-1层:不一定所有的节点都有孩子节点,如果有孩子节点,至少要是左孩子节点,有可能出现不饱和节点

🌠动图解析:👇🏻

请添加图片描述

💫关键思路:
由于完全二叉树在每一层非空节点都是一个接一个连续分布的,不可能出现两个非空节点之间交叉一个空节点,因此:

  • 我们可以通过层序遍历从上往下,从左往右将每一个节点(包括非空节点)都放到队列里
  • 在出队列的过程中,如果遇到空节点,则跳出循环
  • 跳出循环后,然后再判断队列中剩下的元素是否有非空节点
    • 有非空节点:非完全二叉树;
    • 没有非空节点(全是空节点):完全二叉树。

在这里插入图片描述

代码实现💡:

int BinaryTreeComplete(BTNode\* root)
{
	Quene q;
	QueneInit(&q);
	if (root)
	{
		QuenePush(&q, root);
	}
	while (!QueneEmpty(&q))
	{
		BTNode\* front = QueneFront(&q);
		QuenePop(&q);

		if (front)
		{
			QuenePush(&q, front->left);
			QuenePush(&q, front->right);
		}
		else 
		{
			//遇到NULL ,跳出层序遍历
			break;
		}
	}
	//1、如果后面全是NULL,则是完全二叉树
    //2、如果空后面还有非空,则不是完全二叉树
	while (!QueneEmpty(&q))
	{
		BTNode\* front = QueneFront(&q);
		QuenePop(&q);
		if (front)
		{
			QueneDestroy(&q);
			return false;
		}
	}
	QueneDestroy(&q);
	return true;
}

💥特别注意:
我们发现这里:明明pop掉了节点,front为什么还能继续
在这里插入图片描述

  • 首先我们要知道队列原本存的就是树节点的指针
typedef struct BinaryTreeNode\* BTDataType;

  • BTNode* front = QueneFront(&q)——>指向的是队列的data相当于front指向节点1,也就变相保存了队列数据
  • pop掉的是头队列,但数据我们保存下来了,没有丝毫影响

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以戳这里获取

ct BinaryTreeNode* BTDataType;


* BTNode\* front = QueneFront(&q)——>`指向的是队列的data`、`相当于front指向节点1`,也就`变相保存了队列数据`
* pop掉的是头队列,但数据我们保存下来了,没有丝毫影响





[外链图片转存中...(img-T7OwsIrY-1715040058298)]
[外链图片转存中...(img-Mg5RSIrn-1715040058299)]
[外链图片转存中...(img-UH4V4rCj-1715040058299)]

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618545628)**

  • 21
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值