• C++二叉树的序列化与反序列化


    LeetCode 297 https://leetcode-cn.com/problems/serialize-and-deserialize-binary-tree/

    方法1:队列实现广度优先搜索

     1 /**
     2  * Definition for a binary tree node.
     3  * struct TreeNode {
     4  *     int val;
     5  *     TreeNode *left;
     6  *     TreeNode *right;
     7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     8  * };
     9  */
    10 class Codec {
    11 public:
    12 
    13     // Encodes a tree to a single string.
    14     string serialize(TreeNode* root) {
    15         if(root == NULL) return "n";
    16         queue<TreeNode*> Q;
    17         Q.push(root);
    18         string s;
    19         while(!Q.empty()){
    20             TreeNode* node = Q.front();
    21             Q.pop();
    22             if(node){
    23                 s += to_string(node->val);
    24                 s += " ";
    25                 Q.push(node->left);
    26                 Q.push(node->right);
    27             }
    28             else{
    29                 s += "n ";
    30             }
    31         }
    32         return s;
    33     }
    34 
    35     // Decodes your encoded data to tree.
    36     TreeNode* deserialize(string data) {
    37         if(data[0] == 'n') return nullptr;
    38         string s = "";
    39         vector<string> ans;
    40         for(int i = 0; i < data.size(); i++){
    41             if(data[i] == ' '){
    42                 ans.push_back(s);
    43                 s = "";
    44             }
    45             else{
    46                 s += data[i];
    47             }
    48         }
    49         if(s != "") ans.push_back(s);
    50         //for(auto x : ans) cout << x << " ";
    51         //cout << endl;
    52 
    53         queue<TreeNode*> Q;
    54         TreeNode* root = new TreeNode(stoi(ans[0]));
    55         Q.push(root);
    56         int cur = 1;
    57         while(!Q.empty() && cur < ans.size()){
    58             TreeNode* node = Q.front();
    59             Q.pop();
    60             if(cur < ans.size()){
    61                 if(ans[cur] == "n") node->left = NULL;
    62                 else{
    63                     node->left = new TreeNode(stoi(ans[cur]));
    64                     Q.push(node->left);    
    65                 }
    66                 cur++;
    67             } 
    68             if(cur < ans.size()){
    69                 if(ans[cur] == "n") node->right = NULL;
    70                 else{
    71                     node->right = new TreeNode(atoi(ans[cur].c_str()));
    72                     Q.push(node->right);
    73                 }
    74                 cur++;
    75             } 
    76         }
    77         return root;
    78     }
    79 };

    方法2:bfs使用stringstream处理字符串

     1 class Codec {
     2 public:
     3 
     4     // Encodes a tree to a single string.
     5     string serialize(TreeNode* root) {
     6         if(root == NULL) return "null";
     7         queue<TreeNode*> Q;
     8         Q.push(root);
     9         stringstream ss;
    10         while(!Q.empty()){
    11             TreeNode* node = Q.front();
    12             Q.pop();
    13             if(node == NULL) ss << "null ";
    14             else{
    15                  ss << node->val << " ";
    16                  Q.push(node->left);
    17                  Q.push(node->right);
    18             } 
    19         }
    20         //cout << ss.str() << endl;
    21         return ss.str();
    22     } 
    23 
    24     // Decodes your encoded data to tree.
    25     TreeNode* deserialize(string data) {
    26         if(data[0] == 'n') return NULL;
    27         stringstream ss(data);
    28         queue<TreeNode*> Q;
    29         string tmp;
    30         ss >> tmp;
    31         TreeNode* root = new TreeNode(atoi(tmp.c_str()));
    32         Q.push(root);
    33         while(!Q.empty()){
    34             TreeNode* node = Q.front();
    35             //cout << node->val << " ";
    36             Q.pop();
    37             if(ss >> tmp){
    38                 //cout << tmp << " ";
    39                 if(tmp == "null") node->left = NULL;
    40                 else{
    41                     node->left = new TreeNode(atoi(tmp.c_str()));
    42                     Q.push(node->left);
    43                 }
    44             }
    45             if(ss >> tmp){
    46                 //cout << tmp << endl;
    47                 if(tmp == "null") node->right = NULL;
    48                 else{
    49                     node->right = new TreeNode(atoi(tmp.c_str()));
    50                     Q.push(node->right);
    51                 }
    52             }
    53         }
    54         return root;
    55     }
    56 };

    方法3:前序遍历,递归实现的深度优先搜索

     1 class Codec {
     2 public:
     3 
     4     // Encodes a tree to a single string.
     5     string serialize(TreeNode* root) {
     6         if(root == NULL) return "null";
     7         return to_string(root->val) + " " + serialize(root->left) + " " + serialize(root->right) + " ";
     8     }
     9 
    10     // Decodes your encoded data to tree.
    11     TreeNode* deserialize(string data) {
    12         if(data[0] == 'n') return NULL;
    13         istringstream is(data);
    14         return mydeserialize(is); 
    15     }
    16 private:
    17     TreeNode* mydeserialize(istringstream& is){
    18         string tmp;
    19         if(!(is >> tmp) || tmp == "null") return NULL; //考察当前节点是否为null
    20         TreeNode* node = new TreeNode(atoi(tmp.c_str())); 
    21         node->left = mydeserialize(is); //dfs左子树
    22         node->right = mydeserialize(is); //dfs右子树
    23         return node;
    24     }
    25 };

    补充笔记:

    • 使用stringstream处理字符串:
    #include <ssteam>
    stringstream ss;
    string data, tmp;
    ss(data); //将字符串保存到字符流中
    ss.str(); //输出字符串
    getline(ss, tmp, ',') //以 ‘,’为分隔符读取ss中的字符到字符串tmp中
    ss >> tmp; //如果字符流中的字符串以空格分隔,则可以使用重载操作符 >>字符串读取流中的字符串
    //stringstream可以很容易实现字符串与其他数据类型的装换:
    string data;
    stringstram ss(data);
    int a;
    double b;
    ss >> a;
    ss >> b;
    • stringstream 和 istringstream 和 ostringstream的区别
    stringstream可以用来处理输入和输出流,既可以使用“<<”来向字符串流插入信息,也可以使用“>>”来从流中提取信息。
    ostringstream,用输出操作符,只使用“<<”来插入信息,主要用于从code中获取信息。
    istringsreeam,用输入操作符,只使用“>>”来从流中提取信息输入到code中。
    
    p.s. it very rare that for someone to perform streaming into and out of the same string stream. 
    It's better to use 'istringstream' and 'ostringstream' expresses your intent and
    gives you some checking against silly mistakes such as accidental use of
    '<<' vs '>>'.
    (from stack overflow)
  • 相关阅读:
    第二阶段个人博客八
    第二阶段个人博客七
    第二阶段个人博客六
    第二阶段个人博客五
    第二阶段个人博客四
    第十五周学习进度表
    如何选择合适的图表类型
    参加技术会议的一些小窍门
    提高Scrum站会效率的一个小工具
    用6个字符写出任意的Javascript代码
  • 原文地址:https://www.cnblogs.com/tristatl/p/13152342.html
Copyright © 2020-2023  润新知