【Leetcode&nowcode】代码强化练习(二叉树)

系列文章目录

《Leetcode&nowcode代码强化刷题》


文章目录


前言

数据结构与算法是计算机领域的核心,既是面试考察重点,也是优化项目性能的关键。而刷题是掌握它最有效的方式,能帮我们巩固理论、提升解题能力。​

我选择LeetCodeNowCode 作为主要刷题平台:LeetCode 题目丰富、分类清晰,适合夯实基础;NowCode 贴近国内企业笔试场景,助力对接实战需求,二者互补性强。​

这份刷题记录不只是题目与答案的罗列,更会记录解题思路、难点易错点,以及解法优化过程。希望它能成为我的复盘工具,也为其他学习者提供参考。​

接下来,就从第一道题开始,在刷题中积累提升,让数据结构与算法成为解决问题的有力工具。


正文


一、单值二叉树

题目链接: 965.单值二叉树
题目描述:

题目分析:

题目要求很简单,就是让我们判断给定二叉树的每个结点 是不是都相等
思路讲解:

我们可以不断遍历,判断当前结点的值和左右结点的值是否相等

在此之前,想要判断当前结点为不为空,为空的话返回true,其次判断再判断左右结点是否存在并且相等

最后判断完之后,继续去递归遍历左右子树,并且它们之间用&&连接,只要有一个结点的值不相等,就返回false
代码展示:

c 复制代码
/**
* Definition for a binary tree node.
* struct TreeNode {
*     int val;
*     struct TreeNode *left;
*     struct TreeNode *right;
* };
*/

bool isUnivalTree(struct TreeNode* root) {
   //是空返回T
  if(root==NULL)
  {
   return true;
  }
  //右子树存在,但是值不等
  if(root->left&&root->left->val!=root->val)
  {
   return false;
  }
  
  //左子树存在,但是值不等
  if(root->right&&root->right->val!=root->val)
  {
   return false;
  }
//继续左右子树
  return isUnivalTree(root->left)&&isUnivalTree(root->right);
}

二、相同的树

题目链接: 100.相同的树:
题目描述:

题目分析:

给我们两棵二叉树,让我们判断两棵二叉树是不是相同的

注意,这里的二叉树,是有左右之分 的,就像示例2,虽然一样,形态也差不多,但是一个在,一个在,这也是不行的
思路讲解:

我们同时遍历两棵树,两棵树必须满足左右结点 同时存在,或者同时不存在,并且在存在的情况下,必须相等除此之外 就返回false,并且它们俩的左子树也要满足右子树也要满足
代码展示:

c 复制代码
/**
* Definition for a binary tree node.
* struct TreeNode {
*     int val;
*     struct TreeNode *left;
*     struct TreeNode *right;
* };
*/
bool isSameTree(struct TreeNode* p, struct TreeNode* q) {
  
   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);
}

三、对称二叉树

题目链接: 101.对称二叉树:
题目描述:

题目分析:

简单来说,就是给你一个二叉树,你看看它可不可以从中间对折
思路讲解:

结合我们上一道题目,这里的对称,其实也存在一种相等关系,只不过是那左边右边进行比较,对于每一个相对称的结点,它的应该和另一个相等

所以我们只需要把刚刚判断相同树的代码,让它传这棵树的左和右,递归的时候也是比较 左树右树
代码展示:

c 复制代码
/**
* Definition for a binary tree node.
* struct TreeNode {
*     int val;
*     struct TreeNode *left;
*     struct TreeNode *right;
* };
*/

/**
* Definition for a binary tree node.
* struct TreeNode {
*     int val;
*     struct TreeNode *left;
*     struct TreeNode *right;
* };
*/
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->right, q->left) && isSameTree(p->left, q->right);
}
bool isSymmetric(struct TreeNode* root) {
  return isSameTree(root->left,root->right);
  
}

这里我们把上道题目封装成一个函数,放到这里


四、二叉树的前序遍历

题目链接: 144.二叉树的前序遍历
题目描述:

题目分析:

题目很好理解,但是我们要看看它给的代码和注释

它想让我们自己malloc一个数组空间,将遍历结果放到这个数组中,最后返回给它
思路讲解:

首先我们想malloc一块空间,需要先计算出它给的二叉树的结点个数,然后在前序遍历,按顺序把结点的值放入数组空间中
代码展示:

c 复制代码
/**
* Definition for a binary tree node.
* struct TreeNode {
*     int val;
*     struct TreeNode *left;
*     struct TreeNode *right;
* };
*/
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int BinaryTreeSize(struct TreeNode* root)
{
  if(root==NULL)
  {
      return 0;
  }
  return 1+BinaryTreeSize(root->left)+BinaryTreeSize(root->right);
}
void PrevOrder(struct TreeNode* root,int* arr,int *pi)//为了保证每次递归我们的i都可以同步跟进
{
  if(root==NULL)
  {
return ;
  }
  arr[(*pi)++]=root->val;
  PrevOrder(root->left,arr,pi);
  PrevOrder(root->right,arr,pi);
}
int* preorderTraversal(struct TreeNode* root, int* returnSize) {
  *returnSize =BinaryTreeSize(root);
  int * arr=(int*)malloc(sizeof(int)*(*returnSize));
  int i=0;
  PrevOrder(root,arr,&i);
  return arr;
}

这里还有几道相似的题目,大家可以试试看:
94.二叉树的中序遍历
145.二叉树的后序遍历

这三道题目本质上是在练习二叉树的前中后序遍历


五、二叉树遍历

题目链接 二叉树遍历
题目描述:

题目分析:

题目中给我们一个二叉树先序遍历的结果,我们输出它的中序遍历

所以我们一个通过前序遍历,把这棵树给还原出来,再对它进行中序遍历
思路讲解:

那么我们如何对它进行还原呢?

我们首先来看,前序遍历,所以a肯定的节点
根左右 ,如果b不是左节点,那么应该是#,所以b是左节点
根左右 ,b的左如果为空,那个是#,但是是c,所以c是b的左节点
根左右 ,再以c为根,后面两个都是#,所以c的左右都为空回到 b
b左好了为d
根左右d的左不为空,是e
根左右e左为空右是g
根左右g左右都是回到e ,e的根左右结束回到d左结束到右,右为f,f的左右都是空再回到dd右好了回到bb的右好了回到aa左好了到右为空结束

大家可以参考博主画的图,和题目给的字符串反复读这段话

所以我们需要先定义一下树的结点结构
代码块1

c 复制代码
typedef struct BinaryTreeNode {
    char ch;
    struct BinaryTreeNode* left;
    struct BinaryTreeNode* right;
} BTNode;

如何需要一个函数用来根据字符串,建出一棵树

再遇到#,我们就返回NULL,不是#,我们按照根左右的顺序,递归建树,最后返回根节点
代码块2

c 复制代码
//建树
BTNode* CreatTree(char* arr, int* pi) {
    if (arr[*(pi)] == '#') {
        (*pi)++;
        return NULL;
    }
    BTNode* root = BuyNode(arr[(*pi)++]);
    root->left = CreatTree(arr, pi);
    root->right = CreatTree(arr, pi);
    return root;
}

代码展示:

c 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>


typedef struct BinaryTreeNode {
  char ch;
  struct BinaryTreeNode* left;
  struct BinaryTreeNode* right;
} BTNode;

BTNode* BuyNode(char x) {
  BTNode* newnode = (BTNode*)malloc(sizeof(BTNode));
  newnode->ch = x;
  newnode->left = newnode->right = NULL;
  return newnode;
}
//建树
BTNode* CreatTree(char* arr, int* pi) {
  if (arr[*(pi)] == '#') {
      (*pi)++;
      return NULL;
  }
  BTNode* root = BuyNode(arr[(*pi)++]);
  root->left = CreatTree(arr, pi);
  root->right = CreatTree(arr, pi);
  return root;
}
//中序遍历
void InOrder(BTNode* root) {
  if (root == NULL) {
      return;
  }

  InOrder(root->left);
  printf("%c ", root->ch);
  InOrder(root->right);


}
int main() {
  char* arr[100];
  scanf("%s", arr);
  int i = 0;
  InOrder(CreatTree(arr, &i));
  return 0;
}

总结

以上就是我们树相关的一下巩固强化刷题,主要是对我们二叉树遍历的强化,如果大家有什么问题和建议,可以评论留言,希望大家可以多多支持,感谢

后面会更新排序,和C++还有Lunix相关的文章,大家可以关注一下

相关推荐
墨染点香4 小时前
LeetCode 刷题【135. 分发糖果】
算法·leetcode·职场和发展
秋风战士4 小时前
通信算法之336 :3GPPMixed Mode Turbo Decoder
算法·matlab·fpga开发·信息与通信·基带工程
是那盏灯塔4 小时前
【算法】——动态规划之01背包问题
数据结构·c++·算法·动态规划
im_AMBER4 小时前
Leetcode 41
笔记·学习·算法·leetcode
jinmo_C++5 小时前
数据结构_深入理解堆(大根堆 小根堆)与优先队列:从理论到手撕实现
java·数据结构·算法
IT19955 小时前
OpenSSL3.5.2实现SM3数据摘要生成
算法·哈希算法·散列表
Excuse_lighttime5 小时前
排序数组(快速排序算法)
java·数据结构·算法·leetcode·eclipse·排序算法
潘小安6 小时前
『译』迄今为止最强的 RAG 技术?Anthropic 的上下文检索与混合搜索
算法·llm·claude
kessy16 小时前
安全与续航兼备的“国密芯”——LKT6810U
算法