二叉树OJ练习题
单值二叉树
思路:
bool isUnivalTree(struct TreeNode* root){
if(root==NULL)
return true;
//需判断其左节点和右节点是否为NULL,若为NULL,直接跳过,开始下一次的递归
if(root->left&&root->val!=root->left->val)
return false;
if(root->right&&root->val!=root->right->val)
return false;
return isUnivalTree(root->left)&&isUnivalTree(root->right);
}
翻转二叉树
翻转二叉树OJ链接
思路:
struct TreeNode* invertTree(struct TreeNode* root){
if(root==NULL)
return NULL;
//交换两个结点
struct TreeNode*tmp=root->left;
root->left=root->right;
root->right=tmp;
//递归分治
invertTree(root->left);
invertTree(root->right);
return root;
}
检查两棵树是否相同
检查两棵树是否相同OJ链接
思路:
bool isSameTree(struct TreeNode* p, struct TreeNode* q){
//两个为NULL也表示相同
if(p==NULL&&q==NULL)
return true;
//当遍历到的结点有一个不为空,一个为空时,说明两树的结构不同,直接返回false
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);
}
对称二叉树
对称二叉树OJ链接
思路:
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->right)&&isSameTree(p->right,q->left);
}
bool isSymmetric(struct TreeNode* root){
//将树的左子树和右子树比较
return isSameTree(root->left,root->right);
}
另一颗树的子树
另一颗树的子树OJ链接
思路:
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;
//相同就返回true
if(isSameTree(root,subRoot))
return true;
//左子树中找到了,或者右子树中找到了都代表subroot是root的子树
//故为 或
return isSubtree(root->left,subRoot)||isSubtree(root->right,subRoot);
}
判断一颗二叉树是否是平衡二叉树
int BinaryTreeDepth(struct TreeNode* root)
{
if (root==NULL)
{
return 0;
}
//求树的高度
int leftdepth = BinaryTreeDepth(root->left);
int rightdepth = BinaryTreeDepth(root->right);
return leftdepth > rightdepth ? leftdepth + 1 : rightdepth + 1;
}
bool isBalanced(struct TreeNode* root){
//当树中没有节点或者只有一个节点时,也是平衡树
if(root==NULL||root->left==NULL&&root->right==NULL)
return true;
//比较左右子树的高度,看差值是否大于等于1
if(BinaryTreeDepth(root->left)-BinaryTreeDepth(root->right)>1||BinaryTreeDepth(root->right)- BinaryTreeDepth(root->left)>1)
{
return false;
}
//递归分治
return isBalanced(root->left)&&isBalanced(root->right);
}
二叉树的构建及遍历
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
struct Treenode
{
char data;
struct Treenode*left;
struct Treenode*right;
};
//根据数组中的字符来创建节点
struct Treenode* CreatTree(char* a,int* pi)
{
if (a[*pi]=='#'||a[*pi]=='\0') {
(*pi)++;
return NULL;
}
struct Treenode* node=(struct Treenode*)malloc(sizeof(struct Treenode));
assert(node);
node->data=a[(*pi)++];
node->left=CreatTree(a,pi);
node->right=CreatTree(a,pi);
return node;
}
//中序遍历
void inorder(struct Treenode*root)
{
if (root==NULL) {
return;
}
inorder(root->left);
printf("%c ",root->data);
inorder(root->right);
}
int main()
{
char arr[100];
scanf("%s",arr);
int i=0;
//数组中的元素是前序遍历的的方式输入进去的,即第一个元素就是根节点
struct Treenode*root=CreatTree(arr,&i);
inorder(root);
return 0;
}
总结
这些题难度都是简单,但是要自己单独做出来还是会有困难的,对二叉树的理解没有那么深刻,递归用的也是不熟悉。做过一遍后,再回过头来看一遍,发现逻辑还是不难的,核心还是要掌握递归的分治思想。