二叉树的常见问题

二叉树在学习数据结构中的重要性就不言而喻了,这儿简单记录一下自己碰到的一些关于二叉树的常见操作。当然要明确解决这些问题的“根节点思路”了————递归递归recursion。

二叉树的最大深度与最小深度

最大深度是指二叉树根节点到该树叶子节点的最大路径长度。而最小深度自然就是其到叶子节点的最小路径长度了。
**主要思路:**采用二叉树递归的思想,自底向上,当到达叶子节点时,自然达到了“递归边界”,而叶子节点的子节点自然为NULL,也就是深度为0,所以叶子节点的深度自然就是0+1=1了,以此向上累加,并且判断最大值,自然就得到了其最大深度。

最大深度例题

二叉树的最大深度:给定一个二叉树,找出其最大深度。
思路如上,具体实现如下:

int res=1;
int maxDepth(TreeNode* root) {
    if(root==NULL)
        return 0;
    int d1=maxDepth(root->left);
    int d2=maxDepth(root->right);
    return max(d1,d2)+1;
}

最小深度例题

二叉树的最小深度说明:与最大深度类似,无非把max改为min就行了。

判断两个二叉树是否相等,或是否为对称二叉树(翻转)

这一类问题我觉得可以总结为“递归遍历节点并判断”,也是通过递归一个节点一个节点地进行比较。

判断两树是否相等

相同的树:给定两个二叉树,编写一个函数来检验它们是否相同。如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
**思路:**这道题最开始我是求出两个树的前序和中序遍历进行比较判断,但这种方法会有一些例外判断不到。最后还是直接递归地一个点一个点地判断。

bool isSameTree(TreeNode* p, TreeNode* q) {
    if(p!=NULL&&q!=NULL){
        if(p->val!=q->val)
            return false;
        else
            return isSameTree(p->left,q->left)&&isSameTree(p->right,q->right);
    }
    else{
        if(p==NULL&&q==NULL)
            return true;
        else
            return false;
    }
}

对称二叉树

对称二叉树:给定一个二叉树,检查它是否是镜像对称的。
递归向下检查,具体实现如下:

bool isSymmetric(TreeNode* root) {
    if(!root)
        return true;
    return isSymmetric(root->left,root->right);
}
bool isSymmetric(TreeNode *left,TreeNode *right){
    if(!left&&!right)
        return true;
    if((left&&!right)||(!left&&right)||(left->val!=right->val))
        return false;
    return isSymmetric(left->left,right->right)&&isSymmetric(left->right,right->left);
}

翻转二叉树

翻转二叉树:将二叉树翻转(左变右,右变左)。
这个问题也算是出名过头了,参见Google那档子奇闻轶事,也很简单,怎么交换两个数的值就怎么翻转,只不过交换的东西从 int 变成了 Tree 而已。

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

祖先问题

二叉树的最近公共祖先:给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
**思路:**先遍历得到二叉树从根节点到目标节点的路径(形成一个链表),再找到两个链表中最后一个相同节点,即为其最近公共祖先。具体实现如下:

TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
    if(root==NULL)
        return NULL;
    vector pp,qq,tem;
    bool flag=false;
    getList(root,p,tem,pp,flag);
    flag=false;
    getList(root,q,tem,qq,flag);
    int size=pp.size()>qq.size()?qq.size():pp.size();
    int i=0;
    for(i;i &res,vector &path,bool flag){
    if(root==NULL||flag)
        return;
    res.push_back(root);
    if(root==target){
        flag=true;
        path=res;
    }
    getList(root->left,target,res,path,flag);
    getList(root->right,target,res,path,flag);
    res.pop_back();
}

路径问题

路径总和 II :给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径。
**思路:**依然是采用递归的方式,每次判空后用目标和减去该节点的值同时将该节点的值压入tem向量,当目标和为0时,将该tem向量压入结果向量res,完成其过程。

vector> res;
vector tem;
vector> pathSum(TreeNode* root, int sum) {
    if(root==NULL)
        return {};
    int k=sum-root->val;
    tem.push_back(root->val);
    if(root->left==NULL&&root->right==NULL){
        if(k==0){
            res.push_back(tem);
        }
    }
    pathSum(root->left,k);
    pathSum(root->right,k);
    tem.pop_back();
    return res;
}

欢迎访问我的个人blog

你可能感兴趣的:(数据结构学习)