297. 二叉树的序列化与反序列化+449. 序列化和反序列化二叉搜索树

 

297. 二叉树的序列化与反序列化

Q:

在这里插入图片描述

A:

可以层次遍历、前序、中序。

层次遍历,空节点存个特殊符号标记一下就好,重建树也是按层次BFS重建树。

 1 class Codec {
 2 public:
 3 
 4     // Encodes a tree to a single string.
 5     string serialize(TreeNode* root) 
 6     {
 7         string res("");
 8         queue<TreeNode*> my_queue;
 9         my_queue.push(root);
10         vector<string> vec;
11         while(!my_queue.empty())
12         {
13             TreeNode *cur=my_queue.front();
14             my_queue.pop();
15             if(cur==nullptr)
16             {
17                 vec.push_back("null");
18             }
19             else
20             {
21                 vec.push_back(to_string(cur->val));
22                 my_queue.push(cur->left);
23                 my_queue.push(cur->right);
24             }
25         }
26         while(!vec.empty() and vec.back()=="null")
27         {
28             vec.erase(vec.end()-1);
29         }
30         for (auto s:vec)
31         {
32             res+=s;
33             res+=",";
34         }
35         return res;
36     }
37 
38     // Decodes your encoded data to tree.
39     TreeNode* deserialize(string data) 
40     {
41         if(data.empty())
42         {
43             return nullptr;
44         }
45         queue<TreeNode *> my_queue;
46         int le=0,ri=data.find(',',le); //le是节点信息开始位置,ri是紧接着的逗号位置
47         if(ri==-1)
48         {
49             return nullptr;
50         }
51         TreeNode *root=new TreeNode(stoi(data.substr(le,ri-le)));
52         my_queue.push(root);
53         le=ri+1;
54         ri=data.find(',',le);
55         while (ri!=-1)
56         {
57             TreeNode *cur_node=my_queue.front();
58             my_queue.pop();
59             //左孩子
60             string p=data.substr(le,ri-le);
61             if(p!="null")
62             {
63                 TreeNode *left=new TreeNode(stoi(p));
64                 cur_node->left=left;
65                 my_queue.push(left);
66             }
67             //右孩子
68             le=ri+1;
69             ri=data.find(',',le);
70             if(ri==-1)
71             {
72                 break;
73             }
74             p=data.substr(le,ri-le);
75             if(p!="null")
76             {
77                 TreeNode* right=new TreeNode(stoi(p));
78                 cur_node->right=right;
79                 my_queue.push(right);
80             }
81             le=ri+1;
82             ri=data.find(',',le);
83         }
84         return root;
85     }
86 };

 

中序遍历递归:

 1 class Codec {
 2 public:
 3 
 4     // Encodes a tree to a single string.
 5     string serialize(TreeNode* root) {
 6         if(root==nullptr){
 7             return "# ";
 8         }
 9         string str=to_string(root->val)+" ";
10         str+=serialize(root->left);
11         str+=serialize(root->right);
12         return str;
13     }
14 
15     // Decodes your encoded data to tree.
16     TreeNode* deserialize(string data) {
17         // cout<<data;
18         int pos=0;
19         return func(data,pos);
20     }
21     TreeNode* func(const string& data,int& pos){
22         if(data[pos]=='#'){
23             pos+=2;
24             return nullptr;
25         }
26         int p=data.find(' ',pos);
27         int num=stoi(data.substr(pos,p-pos));
28         pos=p+1;
29         TreeNode* cur=new TreeNode(num);
30         cur->left=func(data,pos);
31         cur->right=func(data,pos);
32         return cur;
33     }
34 };

 


中序遍历用栈,比递归快一点:

 1 class Codec {
 2 public:
 3 
 4     // Encodes a tree to a single string.
 5     string serialize(TreeNode* root) {
 6         string str="";
 7         decltype(root) cur=root;
 8         stack<TreeNode*> sta;
 9         while(cur or not sta.empty()){
10             if(cur){
11                 str+=to_string(cur->val)+" ";
12                 sta.push(cur);
13                 cur=cur->left;
14             }
15             else{
16                 str+="# ";
17                 cur=sta.top()->right;
18                 sta.pop();
19             }
20         }
21         str+="# ";
22         return str;
23     }
24 
25     // Decodes your encoded data to tree.
26     TreeNode* deserialize(string data) {
27         // cout<<data;
28         int pos=0;
29         return func(data,pos);
30     }
31     TreeNode* func(const string& data,int& pos){
32         if(data[pos]=='#'){
33             pos+=2;
34             return nullptr;
35         }
36         int p=data.find(' ',pos);
37         int num=stoi(data.substr(pos,p-pos));
38         pos=p+1;
39         TreeNode* cur=new TreeNode(num);
40         cur->left=func(data,pos);
41         cur->right=func(data,pos);
42         return cur;
43     }
44 };

 

 

449. 序列化和反序列化二叉搜索树

Q:

在这里插入图片描述

A:

这题首先可以用297的代码去套,速度也差不多,但是没有利用二叉搜索树的性质,下面是一个利用搜索树性质的方法。
正常二叉树如果序列化为字符串,想再转化为原二叉树的话,除了按层次建树,需要中序、前序、后序中的至少两个,从而重建二叉树。但对于二叉搜索树,它的中序遍历序列是单调递增的,那么我们可以求出前序或者后序序列任意一个,对其排序就得到了中序序列。这样我们只需要一个前序or后序序列就可以完成二叉搜索树的重建。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Codec {
public:

    // Encodes a tree to a single string.
    string serialize(TreeNode* root) {
        string res;
        stack<TreeNode*> sta;
        TreeNode *p=root;
        while(p or !sta.empty()){   //先序遍历
            if(p){
                res+=to_string(p->val);
                res+="#";
                sta.push(p);
                p=p->left;
            }
            else{
                p=sta.top()->right;
                sta.pop();
            }
        }
        return res;
    }
    // Decodes your encoded data to tree.
    TreeNode* deserialize(string data) {
        vector<int> preorder,midorder;
        int i=0,j;
        while(i<data.size()){
            j=data.find('#',i);
            preorder.push_back(stoi(data.substr(i,j-i)));
            i=j+1;
        }
        midorder=preorder;
        sort(midorder.begin(),midorder.end());
        return helper(preorder,0,preorder.size()-1,midorder,0,midorder.size()-1);
    }
    TreeNode* helper(vector<int>& pre,int le_pre,int ri_pre,vector<int>& mid,int le_mid,int ri_mid){
        if(le_pre>ri_pre or ri_pre>=pre.size() or ri_mid>=mid.size()){
            return 0;
        }
        TreeNode* root=new TreeNode(pre[le_pre]);
        int p=find(mid.begin()+le_mid,mid.begin()+ri_mid,pre[le_pre])-mid.begin();
        //p是中序序列中根节点的下标
        root->left=helper(pre,le_pre+1,le_pre+p-le_mid,mid,le_mid,p-1);
        root->right=helper(pre,le_pre+1+p-le_mid,ri_pre,mid,p+1,ri_mid);
        return root;
    }
};

// Your Codec object will be instantiated and called as such:
// Codec codec;
// codec.deserialize(codec.serialize(root));
posted @ 2019-11-09 20:18  NeoZy  阅读(187)  评论(0编辑  收藏  举报