根据前序遍历和中序遍历重建二叉树

来源:互联网 发布:mysql join as 编辑:程序博客网 时间:2024/05/16 05:20

1. 非递归方式

/**
 * 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) {
        TreeNode* head=new TreeNode(pre[0]);//前序遍历的第一个元素一定是根
        //对于每个pre中的元素,如果他的下一个元素在vin中位于他的左边,就是他的左孩子;
        //如果在vin中位于他的右边,就是他的右孩子
        int size=pre.size();
        TreeNode* cur=head;
        TreeNode* left;
        TreeNode* right;
        TreeNode* temp;
        stack<TreeNode*> s;
        s.push(cur);
        for(int i=1;i<size;i++){
            if(decideleft(vin,pre[i],cur->val)){
                left=new TreeNode(pre[i]);
                cur->left=left;
                cur=left;
                s.push(cur);
            }else{
                s.pop();
                while(!s.empty()){
                     temp=s.top();
                if(decideleft(vin,pre[i],temp->val)){
                    right=new TreeNode(pre[i]);
                    cur->right=right;
                    cur=right;
                    s.push(cur);
                    break;
                }else{
                    cur=s.top();
                    s.pop();
                }
                }
                if(s.empty()){
                right=new TreeNode(pre[i]);
                cur->right=right;
                cur=right;
                s.push(cur); 
                }
            }     
        }
        return head; 
    }
    bool decideleft(vector<int>& vin,int temp,int root){
        //判断temp在root的左边吗?是返回true
        int size=vin.size();
        bool flag;
        for(int i=0;i<size;i++){
            if(vin[i]!=temp&&vin[i]!=root)
                continue;
            else if(vin[i]==temp){
                flag= true;
                break;
            }else{
                flag= false;
                break;
            }
        }
        return flag;
    }
};


2. 递归方式

利用递归的方式进行二叉树重建的时候,需要注意的就是在中序遍历序列中找到分界点的时候,需要立刻计算出分界点左边的节点的数量,左边节点的数量就是分界点左子树中

节点的总数量;分界点右边的节点的数量,就是分界点右子树中节点的数量。利用这些数量,可以在前序遍历中找到分界点的右子树中的节点起始位置。

/**
 * 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) {
        int size=vin.size();                                                          
        TreeNode* head=rebuild(0,0,size-1, pre, vin);
        return head;
                                                                      


    }
    TreeNode* rebuild(int preindex,int vinstart,int vinend,vector<int>& pre,vector<int>& vin){
        TreeNode* head=new TreeNode(pre[preindex]);
        if(vinstart>=vinend)
            return head;
        int i;
        for( i=vinstart;i<=vinend;i++){
            if(pre[preindex]==vin[i])
                break;
        }
        int leftnum=i-vinstart;//这里计算分界点左边的节点数量是非常重要的,利用这个数量可以找到建立右子树时的preindex!!!!
        int rightnum=vinend-i;
        if(leftnum>0)
           head->left=rebuild(preindex+1,vinstart,vinstart+leftnum-1, pre,vin);
        if(rightnum>0)
           head->right=rebuild(preindex+leftnum+1,vinstart+leftnum+1, vinend,pre,vin);
        return head; 
   }
};

阅读全文
0 0
原创粉丝点击