目录
一、相同的树
给你两棵二叉树的根节点
p
和q
,编写一个函数来检验这两棵树是否相同。如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
leetcode链接:100. 相同的树 - 力扣(LeetCode)
/**
* 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) //p和q同时为NULL返回true
return true;
if(p == NULL || q == NULL) //p和q一个为NULL返回false
return false;
if(p->val != q->val) //p->val和q->val不相等时返回false
{
return false;
}
//使用递归对p和q的左结点判断 && 对p和q的右节点判断
return isSameTree(p->left,q->left) && isSameTree(p->right,q->right);
}
二、翻转二叉树
给你一棵二叉树的根节点
root
,翻转这棵二叉树,并返回其根节点。leetcode链接:226. 翻转二叉树 - 力扣(LeetCode)
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
struct TreeNode* invertTree(struct TreeNode* root)
{
if(!root)
return NULL;
//首先将右侧结点保存至tmp
struct TreeNode* tmp = root->right;
//将左侧子树结点赋值给右侧子树结点
root->right = invertTree(root->left);
//将右侧子树结点赋值给左侧子树结点
root->left = invertTree(tmp);
return root;
}
三、对称二叉树
给你一个二叉树的根节点
root
, 检查它是否轴对称。leetcode链接:101. 对称二叉树 - 力扣(LeetCode)
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
bool isSame(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;
}
//和问题一判断相同的树类似,只需要将最后一步的 q -> left 和 p -> right 交换位置
return isSame(p->left,q->right) && isSame(p->right,q->left);
}
bool isSymmetric(struct TreeNode* root)
{
return isSame(root,root);
}
四、另一颗树的子树
给你两棵二叉树 root 和 subRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。如果存在,返回 true ;否则,返回 false 。
二叉树 tree 的一棵子树包括 tree 的某个节点和这个节点的所有后代节点。tree 也可以看做它自身的一棵子树。
leetcode链接:572. 另一棵树的子树 - 力扣(LeetCode)
/**
* 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->left,q->left) && isSameTree(p->right,q->right);
}
bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot)
{
//根结点 == NULL 返回false
if(root == NULL)
{
return false;
}
//使用问题一代码判断结点和子结点是否相同
if(isSameTree(root,subRoot))
{
return true;
}
//若存在一个子树和树相同,则返回True
return isSubtree(root->left,subRoot) || isSubtree(root->right,subRoot);
}
五、二叉树遍历
编一个程序,读入用户输入的一串先序遍历字符串,根据此字符串建立一个二叉树(以指针方式存储)。 例如如下的先序遍历字符串: ABC##DE#G##F### 其中“#”表示的是空格,空格字符代表空树。建立起此二叉树以后,再对二叉树进行中序遍历,输出遍历结果。
#include <stdio.h>
#include <stdlib.h>
//定义树结点 char类型数据
typedef struct TreeNode
{
char data;
struct Tree* left;
struct Tree* right;
} Tree;
//构建出原树结构
//传入str指针,并且需要计数,
//在递归过程需要保证count的值为同一个,所以传入count的指针
Tree* createTree(char* str, int* count)
{
//#代表NULL,将其读取为NULL,并且(*count)++
if (str[*count] == '#')
{
(*count)++;
return NULL;
}
//malloc新结点来保存非NULL结点
Tree* newnode = (Tree*)malloc(sizeof(Tree));
//将当前char值保存至newnode->data,并且(*count)++
newnode->data = str[*count];
(*count)++;
//根据左子树和右子树分别递归建立子树
newnode->left = createTree(str,count);
newnode->right = createTree(str,count);
return newnode;
}
//DFS中序遍历
void InOrder(Tree* root)
{
if(root == NULL)
return ;
InOrder(root->left);
printf("%c ",root->data);
InOrder(root->right);
}
//main函数
int main()
{
char str[100];
scanf("%s", str);
int count = 0;
Tree* root = createTree(str,&count);
InOrder(root);
return 0;
}