励志冰檗:形容在清苦的生活环境中激励自己的意志。💓💓💓
目录
说在前面
题目一:单值二叉树
题目二:相同的树
题目三:对称二叉树
题目四:二叉树的前序遍历
题目五:另一棵树的子树
题目六:二叉树的构建及遍历
SUMUP结尾
说在前面
dear朋友们大家好!💖💖💖我们又见面了,又到了我们数据结构的刷题时间了。我们上次刚学完了二叉树的知识,现在就让我们来练练手~
👇👇👇
友友们!🎉🎉🎉点击这里进入力扣leetcode学习🎉🎉🎉
以下是leetcode题库界面:
👇👇👇
🎉🎉🎉点击这里进入牛客网NowCoder刷题学习🎉🎉🎉
以下是NowCoder题库界面:
题目一:单值二叉树
题目链接:965. 单值二叉树 - 力扣(LeetCode)
题目描述:
题目分析:
思路:对于二叉树的OJ练习我们一定要多利用递归的思想,即将大问题拆成子问题。首先我们考虑,如果树为空,显然也是单值二叉树,返回true;如果节点中的值与它左右子树根节点的值不同,那肯定返回false;如果和它左右子树根节点的值都相同,就递归到左右子树,按照同样的逻辑即可。
代码如下:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
bool isUnivalTree(struct TreeNode* root) {
if(root == NULL)
return true;
if(root->left && root->val != root->left->val || root->right && root->val != root->right->val)
return false;
return isUnivalTree(root->left) && isUnivalTree(root->right);
}
题目二:相同的树
题目链接:100. 相同的树 - 力扣(LeetCode)
题目描述:
题目分析:
思路:首先,我们需要判断这两棵树是否为空,如果都为空,那么也是相同的树,如果其中有一个为空,另一个不为空,那就不是相同的树;如果第一棵树和第二棵树的值不相等,那肯定不是相同的树;如果它们的值相等,就需要递归到左右子树,如果左右子树都满足,自然最终会回到第一种情况,再将true回归。
代码如下:
/**
* 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 && !q)
return true;
if(!p || !q)
return false;
return p->val != q->val ? false :
isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
}
题目三:对称二叉树
题目链接:101. 对称二叉树 - 力扣(LeetCode)
题目描述:
题目分析:
思路:这道题的思路和题目二有些许类似,题目二是判断两棵树的左右子树是否相同,而这道题是判断你的左子树和我的右子树是否相同即可,也就是我们把二叉树分为root->left和root->right,利用和题目二相同的逻辑就可以了。
代码如下:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
bool _isSymmetric(struct TreeNode* p, struct TreeNode* q) {
if(!p && !q)
return true;
if(!p || !q)
return false;
return p->val != q->val ? false :
_isSymmetric(p->left, q->right) && _isSymmetric(p->right, q->left);
}
bool isSymmetric(struct TreeNode* root) {
return _isSymmetric(root->left, root->right);
}
题目四:二叉树的前序遍历
题目链接:144. 二叉树的前序遍历 - 力扣(LeetCode)
题目描述:
题目分析:
思路:我们再上一章二叉树的部分学习过二叉树的前序遍历,但我们之前的前序遍历在遍历过程中的操作是打印节点的值,我们现在的操作是把它存在一个数组arr中。那数组的大小*returnSize是多少呢?显然就是树的节点,所以我们也需要TreeSize函数来计算树的节点。
代码如下:
/**
* 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().
*/
typedef struct TreeNode TreeNode;
//树的节点个数
int TreeSize(TreeNode* root)
{
if(root == NULL)
return 0;
return TreeSize(root->left) + TreeSize(root->right) + 1;
}
//前序遍历
void PrevOrder(TreeNode* root, int* arr, int* pi)
{
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 = TreeSize(root);
int* arr = (int*)malloc((*returnSize) * sizeof(int));
int i = 0;
PrevOrder(root, arr, &i);
return arr;
}
注意:i作为数组arr的下标,会随着递归的深度而进行改变,所以需要传址调用。
题目五:另一棵树的子树
题目链接:572. 另一棵树的子树 - 力扣(LeetCode)
题目描述:
题目分析:
思路:这道题我们首先判断root本身是否为空,如果本身为空,显然subRoot不可能是root的子树。如果root不为空,我们判断root和subRoot是否是相同的树(相同的树也算true),如果是就返回true,如果不是,就递归到它的左右子树即可。所以我们还需要用到题目二中的相关代码。
代码如下:
/**
* 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 && !q)
return true;
if(!p || !q)
return false;
return p->val != q->val ? false :
isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
}
bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot){
if(root == NULL)
return false;
return isSameTree(root, subRoot) ? true :
isSubtree(root->left, subRoot) || isSubtree(root->right, subRoot);
}
题目六:二叉树的构建及遍历
题目链接:二叉树遍历_牛客题霸_牛客网 (nowcoder.com)
题目描述:
题目分析:
思路:这道题依旧用到了我们上一章中前序和中序遍历的思想,首先构建二叉树我们需要将前序遍历存放在数组arr中,用i作为下标。和题目五类似,i也需要传地址调用。
代码如下:
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 100
typedef char BTDataType;
typedef struct BinaryTreeNode
{
BTDataType data;
struct BinaryTreeNode* left;
struct BinaryTreeNode* right;
}BTNode;
//二叉树的构建
BTNode* CreateTree(char* arr, int* pi)
{
BTNode* root = (BTNode*)malloc(sizeof(BTNode));
if(arr[*pi] == '#')
{
(*pi)++;
return NULL;
}
root->data = arr[(*pi)++];
root->left = CreateTree(arr, pi);
root->right = CreateTree(arr, pi);
return root;
}
//中序遍历
void InOrder(BTNode* root)
{
if(root == NULL)
return;
InOrder(root->left);
printf("%c ", root->data);
InOrder(root->right);
}
int main()
{
char arr[MAXSIZE];
scanf("%s",arr);
int i = 0;
BTNode* root = CreateTree(arr, &i);
InOrder(root);
return 0;
}
SUMUP结尾
数据结构就像数学题,需要刷题才能对它有感觉。之后还会更新数据结构相关的练习题、面试题,希望大家一起学习,共同进步~
如果大家觉得有帮助,麻烦大家点点赞,如果有错误的地方也欢迎大家指出~