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)

 

posted @ 2020-06-17 14:40  萌新的学习之路  阅读(580)  评论(0编辑  收藏  举报