【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 "#";
return to_string(root->val) + ',' + serialize(root->left) + ',' + serialize(root->right);
}
// 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));