二叉树习题

文章目录

  • 1.单值二叉树
  • 2.相同的树
  • 3.对称二叉树
  • 4.二叉树的最大深度
  • 5.二叉树的前序遍历
  • 6.翻转二叉树
  • 7.对称二叉树
  • 8.另一棵树的子树
  • 9.二叉树的遍历
  • 10.平衡二叉树

1.单值二叉树

二叉树习题_第1张图片

bool isUnivalTree(struct TreeNode* root)
{
    if(root==NULL)//判空 如果root为空指针那么也就是说比较结束了,所以返回true
    {
        return true;
    }
    if(root->left&&root->left->val!=root->val)
    //判断root->left不为空并且值不相等返回false
    {
        return false;
    }
    if(root->right&&root->right->val!=root->val)
    //同上
    {
        return false;
    }
    return isUnivalTree(root->right)&&isUnivalTree(root->left);
    //若左右孩子有一个值为false则整个函数结果返回false
}

2.相同的树

二叉树习题_第2张图片

bool isSameTree(struct TreeNode* p, struct TreeNode* q){
    if(p==NULL&&q==NULL)//如果两个节点都同时为空则意味着走到尾了,完全相同
    {
        return true;
    }
   
    else if(p==NULL||q==NULL)//反之排除上面的情况如果有一个节点为空则返回false
    {
        return false;
    }
    if(p->val!=q->val)//递归要写判定结束条件,不相等返回false
    {
        return false;
    }
  
    return isSameTree(p->left,q->left)&&isSameTree(p->right,q->right);
    //若有一个不成立则返回false
}

3.对称二叉树

二叉树习题_第3张图片
这道题的话就转载一段话吧 出自这道题的评论区,我的解法和上道题有异曲同工之妙

递归的难点在于:找到可以递归的点 为什么很多人觉得递归一看就会,一写就废。 或者说是自己写无法写出来,关键就是你对递归理解的深不深。

对于此题: 递归的点怎么找?从拿到题的第一时间开始,思路如下:

1.怎么判断一棵树是不是对称二叉树? 答案:如果所给根节点,为空,那么是对称。如果不为空的话,当他的左子树与右子树对称时,他对称

2.那么怎么知道左子树与右子树对不对称呢?在这我直接叫为左树和右树 答案:如果左树的左孩子与右树的右孩子对称,左树的右孩子与右树的左孩子对称,那么这个左树和右树就对称。

仔细读这句话,是不是有点绕?怎么感觉有一个功能A我想实现,但我去实现A的时候又要用到A实现后的功能呢?

当你思考到这里的时候,递归点已经出现了: 递归点:我在尝试判断左树与右树对称的条件时,发现其跟两树的孩子的对称情况有关系。

想到这里,你不必有太多疑问,上手去按思路写代码,函数A(左树,右树)功能是返回是否对称

def 函数A(左树,右树): 左树节点值等于右树节点值 且
函数A(左树的左子树,右树的右子树),函数A(左树的右子树,右树的左子树)均为真 才返回真

实现完毕。。。

写着写着。。。你就发现你写出来了。。。。。。

bool issame(struct TreeNode*p,struct TreeNode*q)
{
    if(p==NULL&&q==NULL)
    {
        return true;
    }
    else if(p==NULL||q==NULL)
    {
        return false;
    }
    if(p->val!=q->val)
    {
        return false;

    }
    return issame(p->left,q->right)&&issame(p->right,q->left);
}
bool isSymmetric(struct TreeNode* root){
    return issame(root,root);

}

4.二叉树的最大深度

二叉树习题_第4张图片

int maxDepth(struct TreeNode* root){
    if(root==NULL)
    {
        return 0;
    }
    int leftdeep=maxDepth(root->left);
    int rightdeep=maxDepth(root->right);
    return leftdeep>rightdeep? leftdeep+1:rightdeep+1;

}

5.二叉树的前序遍历

二叉树习题_第5张图片

 void preorder(struct TreeNode* root, int* returnSize,int*ret)
 {
     if(root==NULL)
     {
         return;
     }
     //记录根节点数值
     ret[(* returnSize)++]=root->val;
     //记录左孩子数值
     preorder(root->left,returnSize,ret);
     //记录右孩子数值
    preorder(root->right,returnSize,ret);

 }
int* preorderTraversal(struct TreeNode* root, int* returnSize)
//returnsize在这里的作用是返回数组的大小
{
    int*ret=(int*)malloc(1000*sizeof(int));
    *returnSize=0;
    preorder( root,returnSize,ret);
    return ret;
}

6.翻转二叉树

二叉树习题_第6张图片
二叉树习题_第7张图片我刚开始拿到这道题,我是用相同的树的思路,创建一个函数依次指向节点再交换数值,最后发现无法通过…然后换了这种思路

struct TreeNode* invertTree(struct TreeNode* root){
    if(root==NULL)
    {
        return root;
    }
    struct TreeNode* tmp=root->left;//交换节点
    root->left=root->right;
    root->right=tmp;
    invertTree(root->left);
    invertTree(root->right);
    return root;
}

7.对称二叉树

二叉树习题_第8张图片

bool issame(struct TreeNode*p,struct TreeNode*q)
{
    if(p==NULL&&q==NULL)
    {
        return true;
    }
    else if(p==NULL||q==NULL)
    {
        return false;
    }
    if(p->val!=q->val)
    {
        return false;

    }
    return issame(p->left,q->right)&&issame(p->right,q->left);
}
bool isSymmetric(struct TreeNode* root){
    return issame(root,root);//我们用相同的树的思路就可以轻松解决,只不过把比较的节点改成左节点和右节点就好了

}

8.另一棵树的子树

二叉树习题_第9张图片

 bool issame(struct TreeNode*p,struct TreeNode*q)
 {
     if(p==NULL&&q==NULL)
     {
         return true;
     }
      else if(p==NULL||q==NULL)
     {
         return false;
     }
     if(p->val!=q->val)
     {
         return false;
     }
     return issame(p->left,q->left)&&issame(p->right,q->right);
 }
bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot){
    if(root==NULL)//如果root节点为空自然就返回false
    {
        return false;
    }
    if(issame(root,subRoot))//如果找到一个节点分支和subroot相同就返回true
    {
        return true;
    }
    return isSubtree(root->left,subRoot)||isSubtree(root->right,subRoot);//这里要注意||,有一个节点相同就返回true;
}

9.二叉树的遍历

二叉树习题_第10张图片

#include
#include
typedef struct TreeNode
{
	int val;
	struct TreeNode* left;
	struct TreeNode* right;
}TNode;
TNode* rebuildtree(char*str,int*i)
{
	if (str[*i] == '#')
	{
		(*i)++;
		return NULL;
		
	}
	TNode* newnode = (TNode*)malloc(sizeof(TNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}
	newnode->val = str[(*i)++];
	newnode->left=rebuildtree(str, i);
	newnode->right = rebuildtree(str, i);
	return newnode;

}
void Inorder(TNode*root)
{
	if (root == NULL)
	{
		return;
	}
	
	Inorder(root->left);
	printf("%c ", root->val);
	Inorder(root->right);
	printf("\n");
	
}
int main()
{
	char str[100];
	scanf("%s", str);
	//用于递归记录数组下标
	int i = 0;
	TNode* node = rebuildtree(str, &i);
	Inorder(node);
}

10.平衡二叉树

二叉树习题_第11张图片

int maxDepth(struct TreeNode*root)//参考二叉树的最大深度
{
    if(root==NULL)
    {
        return 0;
    }
    int leftdeep=maxDepth(root->left);
    int rightdeep=maxDepth(root->right);
    return leftdeep>rightdeep? leftdeep+1:rightdeep+1;
}
bool isBalanced(struct TreeNode* root){
    if(root==NULL||(root->left==NULL&&root->right==NULL))
    //节点为空或者左右节点都为空,前者是结束,后者是到树叶
    {
        return true;
    }
    if(abs(maxDepth(root->left)- maxDepth(root->right))>1)
    //两边节点做差的绝对值大于1则返回false
    {
        return false;
    }
    return isBalanced(root->left)&&isBalanced(root->right);
   
   

}

你可能感兴趣的:(数据结构初阶,数据结构,leetcode)