二叉树经典oj面试题

作者:[南航科院小张
南航科院小张的博客
学习知识不只是要懂,还要会用;想要找到好的工作,这里给大家介绍一件可以斩获诸多大厂offer的利器–牛客网
点击免费注册和我一起开始刷题之路吧!!!

在这里插入图片描述


一、二叉树的前序遍历

在这里插入图片描述

它要求不是我们直接遍历打印出来,而是malloc一块空间存放节点数据然后返回空间;这个时候先遍历一遍求出二叉树的节点个数,然后malloc相应的空间大小,然后根据前序遍历把节点数据放到数组中,但是如果用下标来放数据的话,传地址来做下标开最简便,要是传值的话会发生错误;最后返回数组;

int BinaryTreeSize(struct TreeNode* root){
    if(root==NULL)
    return 0;
    return BinaryTreeSize(root->left)+BinaryTreeSize(root->right)+1;
}
void BTPrevOrder(struct TreeNode* root,int* a,int* sz){
    if(root==NULL)
    return;
    a[*sz]=root->val;
    (*sz)++;
    BTPrevOrder(root->left,a,sz);
    BTPrevOrder(root->right,a,sz);

}
int* preorderTraversal(struct TreeNode* root, int* returnSize){
int n=0;
n=BinaryTreeSize(root);
*returnSize=n;
int* a=(int*)malloc(sizeof(int)*n);
int sz=0;
BTPrevOrder(root,a,&sz);
return a;
}

二. 单值二叉树

在这里插入图片描述

利用递归思想,分治,分而治之;比较根和左右子树的值,有不相同的就返回false,都相同就继续,让左右子树分别变成根,跟自己的子树比,一直递归下去;

bool isUnivalTree(struct TreeNode* root){
    if(root==NULL)
    return true;
    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);
}

三. 二叉树的最大深度

在这里插入图片描述

这题还是递归,树的高度是自己的高度(1)+左右子树高的子树的高度;
就是看子树那个更高,自己的高度1加上高的子树的高度就是树的高度;
然后子树的高度又分成自己的高度1加上子树的子树那个高的高度,一直分治下去;

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

四. 翻转二叉树

在这里插入图片描述

仔细看一下题目,要是把每个节点的左右子树都交换过来,不就得到答案了吗?又是递归分治问题;

struct TreeNode* invertTree(struct TreeNode* root){
if(root==NULL)
return NULL;
invertTree(root->left);
invertTree(root->right);
struct TreeNode* temp=root->left;
root->left=root->right;
root->right=temp;
return root;
}

五. 相同的树

在这里插入图片描述

一个一个节点遍历对比嘛,但是要记得特殊情况,比如一个节点是空,或者两个节点都是空的情况;

/**
 * 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 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);
}

七. 另一颗树的子树

在这里插入图片描述

把Root树的每一个节点当成一棵二叉树最大的根,一个一个和Subroot比较,判断是否相同,还得用上上题的判断树相等的代码;

/**
 * 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){
if(root==NULL)
return false;
if(isSameTree(root,subRoot))
return true;
return isSubtree(root->left,subRoot)||isSubtree(root->right,subRoot);

}

八. 平衡二叉树

在这里插入图片描述

把每个左右子树当成根节点,然后子树的左右子树的高度是否符合,一一判断嘛,还是用递归;

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

bool isBalanced(struct TreeNode* root){
if(root==NULL)
return true;
int lh=maxDepth(root->left);
int rh=maxDepth(root->right);
if(abs(lh-rh)>1)
return false;
return isBalanced(root->left)&&isBalanced(root->right);
}

九. 二叉树遍历

在这里插入图片描述

先搞一个数组放前序遍历的数据,然后再搞一个创建二叉树的函数,记得传下标要地址哦,创建二叉树的时候要搞前序的递归一个一个链接节点;然后树搞好以后就直接简单的中序遍历了;代码实现可能有点点挑战,但是实际上不太难的哈;

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef char BTDataType;
typedef struct BinaryTreeNode{
    BTDataType data;
    struct BinaryTreeNode* left;struct BinaryTreeNode* right;
    
}BTNode;
BTNode* BinaryTreeCreate(char* a,int* n){
    if(a[*n]=='#'){
        (*n)++;
        return NULL;
    }
    BTNode* root=(BTNode*)malloc(sizeof(BTNode));
    if(root==NULL){
        perror("malloc fail");
        exit(-1);
    }
    root->data=a[*n];
    (*n)++;
    root->left=BinaryTreeCreate(a, n);
    root->right=BinaryTreeCreate(a,n);
    return root;
}
void InOrder(BTNode* root){
    if(root==NULL)
        return;
    InOrder(root->left);
    printf("%c ",root->data);
    InOrder(root->right);
}
int main(){
    char arr[100]={0};
    scanf("%s",arr);
    int n=0;
    BTNode* root=BinaryTreeCreate(arr,&n);
    InOrder(root);
    return 0;
}

总结

刷题对我们的知识点的掌握和思维的锻炼是有较大的帮助的,多刷题对我们有很多好处的哦

在这里插入图片描述

  • 13
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值