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)
  • 相关阅读:
    Linux删除tunnel的方法
    rpm 强制更新安装
    普通用户使用kubectl
    网络通信过程中mac地址和ip地址的必要性
    Quartz.net开源作业调度框架使用详解
    C# 开源组件--Word操作组件DocX
    用c#创建支持多语言的WinForm应用程序
    使用JavaScript获取日期加随机数生成单号
    C# winform treeView checkbox全选反选
    DevExpress控件的GridControl控件小结
  • 原文地址:https://www.cnblogs.com/tristatl/p/13152342.html
Copyright © 2011-2022 走看看