# 【LeetCode & 剑指offer刷题】树题11：37 序列化二叉树（297. Serialize and Deserialize Binary Tree）

【LeetCode & 剑指offer 刷题笔记】目录（持续更新中...）

297. Serialize and Deserialize Binary Tree

Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in the same or another computer environment.
Design an algorithm to serialize and deserialize a binary tree. There is no restriction on how your serialization/deserialization algorithm should work. You just need to ensure that a binary tree can be serialized to a string and this string can be deserialized to the original tree structure.
Example:
You may serialize the following tree:

1
/ \
2   3
/ \
4  5

as "[1,2,3,null,null,4,5]"
Clarification: Just the same as how LeetCode OJ serializes a binary tree. You do not necessarily need to follow this format, so please be creative and come up with different approaches yourself.
Note: Do not use class member/global/static variables to store states. Your serialize and deserialize algorithms should be stateless.

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

*/
#include <string>
#include <sstream>
class Codec
{
public:
// Encodes a tree to a single string.
string serialize(TreeNode* root)
{
ostringstream out//构造字符串流
seri(root, out);
return out.str(); //out变为字符串返回
}
// Decodes your encoded data to tree.
TreeNode* deserialize(string data)
{
istringstream in(data); //构造字符串流
return deseri(in);
}
private:
//序列化，树 -> 序列
void seri(TreeNode *root, ostringstream &out)
{
if (root)
{
out << root->val << ' '; //处理根结点，用空格分隔（把序列当做树序列化时输出的容器），联系cout,将变量输出到cout
seri(root->left, out); //递归左子树
seri(root->right, out); //递归右子树
}
else //空结点时，置为'# '（注意#号后有空格）
{
out << "# ";
}
}

//反序列化，序列 ->
TreeNode* deseri(istringstream &in)
{
string val;   //有可能数字为多位数，故不能设定为char
in >> val;    //反序列化，将序列中的值读出，联系cin,将输入值传给变量(分隔符为空格，可以直接用,若用其他分隔，可用getline函数)

if (val == "#")
return nullptr;
else
{
TreeNode *root = new TreeNode(stoi(val)); //处理根结点
root->left = deseri(in);   //递归左子树
root->right = deseri(in);  //递归右子树
return root;
}
}
};
// Your Codec object will be instantiated and called as such:
// Codec codec;
// codec.deserialize(codec.serialize(root));

/**
* Definition for a binary tree node.
* struct TreeNode {
*     int val;
*     TreeNode *left;
*     TreeNode *right;
*     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
//掌握
//利用前序遍历方式 序列化与反序列化
//由于有表示空结点的符号存在，故可以唯一确定二叉树，而不需要与中序遍历序列相结合
#include <string>
#include <sstream>
class Codec
{
public:
// Encodes a tree to a single string.
string serialize(TreeNode* root)
{
if(root == nullptr) return "#";
}
// Decodes your encoded data to tree.
TreeNode* deserialize(string data)
{
if(data == "#") return nullptr;
stringstream s(data); //构造字符串流
return deseri(s);
}
private:
/*  void seri(TreeNode* root, string& result)
{
if(root == nullptr)
{
result.push_back("#,"); //#表示空指针
return;
}

result.push_back(to_string(root->val) + ','); //，为分隔符
seri(root->left, result);
seri(root->right, result);
}*/

TreeNode* deseri(stringstream& s)
{
string str; //有可能数字为多位数，故不能设定为char
getline(s, str, ','); //getline 从输入流读取字符并将它们放进 string,默认分隔符是换行符,这里设置为分隔符为, (用getline可以逐步读取流中字符串，操作方便，相当于string容器每次访问后pop，流中字符会越来越少)
if(str == "#") return nullptr;
else
{
TreeNode* root = new TreeNode(stoi(str)); //stoi函数将整数转为字符串
root->left = deseri(s);
root->right = deseri(s);
return root;
}

}
};
// Your Codec object will be instantiated and called as such:
// Codec codec;
// codec.deserialize(codec.serialize(root));

posted @ 2019-01-05 19:47  wikiwen  阅读(292)  评论(0编辑  收藏