文章目录
前言:
- 在学习完二叉树的基本知识后,主要包括前序遍历以及分治算法的思想,再通过下面几道基础OJ题提高理解
- 题目来源:LeetCode、牛客
- 代码:C语言
1. 单值二叉树
LeetCode链接:单值二叉树
1.1 题目描述及解决思路
- 解决思路1:利用前序遍历,从根结点开始,以根节点的date为标准值,以此和各个结点的date比较,控制返回bool值即可
- 解决思路2:利用前序遍历,从根结点开始,每次都以根节点的date为标准值,以此和它的左右孩子的date比较
1.2 AC代码
- 利用全局变量,不带返回值
bool flag = true;
void PreOrderCompare(struct TreeNode* root, int val)
{
if(root == NULL || flag == false)//优化
return;
if (root->val != val)
{
flag = false;
return;
}
PreOrderCompare(root->left, val);
PreOrderCompare(root->right, val);
}
bool isUnivalTree(struct TreeNode* root){
if(root == NULL)
return true;
flag = true;//全局遍历,每次调用前重置
PreOrderCompare(root, root->val);
return flag;
}
- 带返回值
bool isUnivalTree(struct TreeNode* root){
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);
}
2. 相同的树
LeetCode链接:相同的树
2.1 题目描述及解决思路
- 解决思路:利用前序遍历和分治思想,把每颗树分成根和左子树、右子树,以此进行比较,若根相等,则比较他们的左右子树,左右子树又重新看做一颗新的树,分成根和左右子树,继续重复比较步骤,层层递归下去
2.2 AC代码
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);
}
3. 对称二叉树
LeetCode链接:对称二叉树
3.1 题目描述及解决思路
- 解决思路:利用前序遍历和分治思想,对每一颗树,进行左子树和右子树的比较,对于子树,再继续分划,分成下一个左右子树的比较
3.2 AC代码
bool isSymmetricSubTree(struct TreeNode* root1, struct TreeNode* root2)
{
if(root1 == NULL && root2 == NULL)
return true;
if(root1 == NULL || root2 == NULL)
return false;
if(root1->val != root2->val)
return false;
return isSymmetricSubTree(root1->left, root2->right)
&& isSymmetricSubTree(root1->right, root2->left);
}
bool isSymmetric(struct TreeNode* root){
if(root == NULL)
return true;
return isSymmetricSubTree(root->left, root->right);
}
4. 另一棵树的子树(*)
LeetCode链接:另一棵树的子树
4.1 题目描述及解决思路
- 解决思路:利用前序遍历和分治思想,把原树中所有子树都找出来和subRoot比较一下,就可以了,比较可以调用上面相同的树的代码。这里的问题在于如何找出所有子树。
4.2 AC代码
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. 二叉树的前序遍历
LeetCode链接:二叉树的前序遍历
5.1 题目描述及解决思路
- 解决思路:前序遍历,先求出二叉树的结点个数,malloc一个数组,将有效数据存入,再返回该数组
5.2 AC代码
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. 二叉树的中序遍历
LeetCode链接:二叉树的中序遍历
6.1 题目描述及解决思路
- 解决思路:和前面的前序遍历一样,只是修改遍历的顺序,基本思路是一样的
6.2 AC代码
int TreeSize(struct TreeNode* root)
{
return root == NULL ? 0 : TreeSize(root->left) + TreeSize(root->right) + 1;
}
void inorder(struct TreeNode* root, int* a, int* pi)
{
if(root == NULL)
return;
inorder(root->left, a, pi);
a[(*pi)++] = root->val;
inorder(root->right, a, pi);
}
int* inorderTraversal(struct TreeNode* root, int* returnSize){
*returnSize = TreeSize(root);
int* a = (int*)malloc(*returnSize*sizeof(int));
int i = 0;
inorder(root, a, &i);
return a;
}
7. 二叉树的后序遍历
LeetCode链接:二叉树的后序遍历
7.1 题目描述及解决思路
- 解决思路:和前面的前序遍历一样,只是修改遍历的顺序,基本思路是一样的
7.2 AC代码
int TreeSize(struct TreeNode* root)
{
return root == NULL ? 0 : TreeSize(root->left) + TreeSize(root->right) + 1;
}
void postorder(struct TreeNode* root, int* a, int* pi)
{
if(root == NULL)
return;
postorder(root->left, a, pi);
postorder(root->right, a, pi);
a[(*pi)++] = root->val;
}
int* postorderTraversal(struct TreeNode* root, int* returnSize){
*returnSize = TreeSize(root);
int* a = (int*)malloc(*returnSize*sizeof(int));
int i = 0;
postorder(root, a, &i);
return a;
}
8. 二叉树的构建及遍历
牛客链接:二叉树的构建及遍历
8.1 题目描述及解决思路
- 解决思路:利用前序遍历,逐步构建一个二叉树,然后对二叉树进行中序遍历,输出遍历结果
8.2 AC代码
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef int BTDateType;
typedef struct BinaryTreeNode
{
struct BinaryTreeNode* left;
struct BinaryTreeNode* right;
BTDateType date;
}BTNode;
BTNode* BuyNode(BTDateType x)
{
BTNode* node = (BTNode*)malloc(sizeof(BTNode));
assert(node);
node->date = 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->date);
InOrder(root->right);
}
int main()
{
char str[100];
scanf("%s",str);
int i=0;
//前序构建
BTNode* root = CreateTree(str, &i);
//中序遍历
InOrder(root);
return 0;
}
学习记录:
- 本篇博客整理于2022.7.7
- 请多多指教🌹