zoukankan      html  css  js  c++  java
  • 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)
  • 相关阅读:
    C/C++ 公有函数无法返回私有的类对象解决方案
    C/C++ ShowWindow()
    Windows 隐藏控制台
    Windows 关闭win32 控制台
    Windows 开启win32 控制台
    CSS中可以和不可以继承的属性
    css3实现炫酷的文字效果_空心/立体/发光/彩色/浮雕/纹理等文字特效
    CSS position 属性_css中常用position定位属性介绍
    无间歇文字滚动_ 原生js实现新闻无间歇性上下滚动
    好看css搜索框样式_分享8款纯CSS搜索框
  • 原文地址:https://www.cnblogs.com/tristatl/p/13152342.html
Copyright © 2011-2022 走看看