根据中序和先序重建二叉树+二叉树的镜像+二叉树的深度+判断后序序列+判断子树

题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。

思路:递归。首先先序的第一个元素一定是根节点,然后在中序中以根节点为分界,左边的为左子树的所有节点,右边的为右子树的所有节点,相应地也将先序划分为左右子树,这样就分别得到了左右子树的先序和中序,递归地继续调用该函数即可

/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
        if(pre.size()==0||vin.size()==0) return NULL;

        TreeNode* root=new TreeNode(pre[0]);//先序的第一个节点为根节点
        int rootIndex=0;
        for(int i=0;i<vin.size();i++){
            if (vin[i]==pre[0])
                rootIndex=i;//找到根节点在中序中的位置
        }
        vector<int> temppre1;
        vector<int> tempvin1;
        for(int i=0;i<rootIndex;i++){
            tempvin1.push_back(vin[i]);
            temppre1.push_back(pre[i+1]);//得到左子树的先序和中序
        }
        vector<int> temppre2;
        vector<int> tempvin2;
        for(int i=rootIndex+1;i<vin.size();i++){
            tempvin2.push_back(vin[i]);
            temppre2.push_back(pre[i]);//得到右子树的先序和中序
        }
        root->left=reConstructBinaryTree(temppre1,tempvin1);//左子树递归,结果为根节点的左节点
        root->right=reConstructBinaryTree(temppre2,tempvin2);  //右子树递归,结果为根节点的右节点 
        return root;
    }   
};

题目描述
操作给定的二叉树,将其变换为源二叉树的镜像。
输入描述:
二叉树的镜像定义:源二叉树
8
/ \
6 10
/ \ / \
5 7 9 11
镜像二叉树
8
/ \
10 6
/ \ / \
11 9 7 5

class Solution {
public:
    void Mirror(TreeNode *pRoot) {
        if(pRoot==NULL||(pRoot->left==NULL&&pRoot->right==NULL)) return;
        TreeNode* left=pRoot->left;
        TreeNode* right=pRoot->right;
        pRoot->left=right;
        pRoot->right=left;//交换左右子树
        Mirror(pRoot->left);//递归左子树
        Mirror(pRoot->right); //递归右子树   
    }
};

题目描述
输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。

class Solution {
public:
    int TreeDepth(TreeNode* pRoot)
    {
        if (pRoot==NULL) return 0;
        if(pRoot->left==NULL&&pRoot->right==NULL) return 1;
        int l=0;
        int r=0;
        if (pRoot->left!=NULL){
            l=TreeDepth(pRoot->left);//左子树的深度
        }
        if(pRoot->right!=NULL){
            r=TreeDepth(pRoot->right);//右子树的深度
        }
        return max(l,r)+1; //树的深度为左右子树的最大值+1
    }
};

题目描述
输入一棵二叉树,判断该二叉树是否是平衡二叉树。
思路:分别求出左右子树的深度,判断深度之差绝对值小于2,且左右子树为平衡二叉树

class Solution {
public:
    int TreeDepth(TreeNode*pRoot){
        if (pRoot==NULL) return 0;
        if(pRoot->left==NULL&&pRoot->right==NULL) return 1;
        int l=0;
        int r=0;
        if (pRoot->left!=NULL){
            l=TreeDepth(pRoot->left);//左子树的深度
        }
        if(pRoot->right!=NULL){
            r=TreeDepth(pRoot->right);//右子树的深度
        }
        return max(l,r)+1; //树的深度为左右子树的最大值+1
    }

    bool IsBalanced_Solution(TreeNode* pRoot) {
        if(pRoot==NULL||(pRoot->left==NULL&&pRoot->right==NULL)) return true;
        int l=0;
        int r=0;
        if(pRoot->left!=NULL) l=TreeDepth(pRoot->left);
        if(pRoot->right!=NULL) r=TreeDepth(pRoot->right);
        if(IsBalanced_Solution(pRoot->left)&&IsBalanced_Solution(pRoot->right)&&abs(l-r)<2) return true;        return false;


    }
};

题目描述
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。

class Solution {
public:
    bool VerifySquenceOfBST(vector<int> sequence) {
        int l=sequence.size();
        if(l==0) return false;
        if(l<=2) return true;
        int num=sequence[l-1]; //最后一个元素num作为分界线
        int i=0;
        int j=l-2; //要先将最后一个元素排除
        while(i<l&&sequence[i]<num) i++; //找到比num小的连续序列
        while(j>=0&&sequence[j]>num) j--;//找到比num大的连续序列
        vector<int> left;
        vector<int> right;
        for(int k=0;k<i;k++) left.push_back(sequence[k]);
        for(int k=j+1;k<l-1;k++) right.push_back(sequence[k]); //注意此处为k<l-1        
        return ((left.empty()&&VerifySquenceOfBST(right)&&i==j+1)||(right.empty()&&VerifySquenceOfBST(left)&&i==j+1)||(i==j+1&&VerifySquenceOfBST(left)&&VerifySquenceOfBST(right))); //首先根据最后一个元素可以将vector完全分为两部分(即i=j+1),之后有三种情况:(1)左边为空,右边为后序序列;(2)右边为空,左边为后序序列;(3)左右均为后序序列
    }
};

题目描述
输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
思路:使用递归算法,首先在1树中找与2树的根节点值相同的节点,然后判断以该节点为根的子树是否与2树相同。

class Solution {
public:
    bool IsSubTree(TreeNode* pRoot1, TreeNode* pRoot2){
        if(pRoot2==NULL) return true;
        if(pRoot1==NULL) return false;
        if(pRoot1->val!=pRoot2->val) return false;
        return (pRoot1->val==pRoot2->val&&IsSubTree(pRoot1->left,pRoot2->left)&&IsSubTree(pRoot1->right,pRoot2->right));//节点值相等且左右子树都相同
    }
    bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2)
    {
        bool result=false;
        if(pRoot2==NULL||pRoot1==NULL) return false;
        if(pRoot1->val==pRoot2->val){
            result=IsSubTree(pRoot1,pRoot2);//如果节点的值相等,就判断是否是相同树
        }
        if(!result&&pRoot1->left!=NULL){
            return HasSubtree(pRoot1->left,pRoot2);//如果节点值不相等,就判断左子树中有没有pRoot2的子结构
        }
        if(!result&&pRoot1->right!=NULL){
            return HasSubtree(pRoot1->right,pRoot2);
        }
        return result;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章