题目
序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据。
请设计一个算法来实现二叉树的序列化与反序列化。这里不限定你的序列 / 反序列化算法执行逻辑,你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序列化为原始的树结构。
提示: 输入输出格式与 LeetCode 目前使用的方式一致,详情请参阅 LeetCode 序列化二叉树的格式。你并非必须采取这种方式,你也可以采用其他的方法解决这个问题。
示例
模式
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Codec {
public:
// Encodes a tree to a single string.
string serialize(TreeNode* root) {
}
// Decodes your encoded data to tree.
TreeNode* deserialize(string data) {
}
};
// Your Codec object will be instantiated and called as such:
// Codec ser, deser;
// TreeNode* ans = deser.deserialize(ser.serialize(root));
题解
深度优先
先是官方的深度优先选择
序列化本质是对其值进行编码,正重要的是对结构编码
可以遍历树来完成上述任务。众所周知,我们一般有两个策略:广度优先搜索和深度优先搜索。
广度优先搜索可以按照层次的顺序从上到下遍历所有的节点
深度优先搜索可以从一个根开始,一直延伸到某个叶,然后回到根,到达另一个分支。根据根节点、左节点和右节点之间的相对顺序,可以进一步将深度优先搜索策略区分为:
- 先序遍历
- 中序遍历
- 后序遍历
class Codec {
public:
void rserialize(TreeNode* root,string& str)
{
if(!root) str+="None,";
else{
str+=to_string(root->val) + ","; //将值转为字符型
rserialize(root->left,str); //序列化左
rserialize(root->right,str); //序列化右
}
}
// Encodes a tree to a single string.
string serialize(TreeNode* root) {
string ret; //因为要声明一个共用的,每次都要在他上面增减值,所以可以再写一个函数传地址,用新函数递归,也可以就用此(见下写法2)
rserialize(root,ret);
return ret;
}
/*
string serialize(TreeNode* root) {
string ret;
if(!root) return "None,";
ret += to_string(root->val)+",";
ret+=serialize(root->left);
ret+=serialize(root->right);
return ret;
}
*/
TreeNode* rdeserialize(list<string>& dataArray)
{
if(dataArray.front() == "None"){
dataArray.erase(dataArray.begin());
return nullptr;
}
TreeNode* root = new TreeNode(stoi(dataArray.front()));
dataArray.erase(dataArray.begin());
root->left = rdeserialize(dataArray);
root->right = rdeserialize(dataArray);
return root;
}
// Decodes your encoded data to tree.
TreeNode* deserialize(string data) {
list<string> dataArray; //新了解到,list是stl封装的双向链表
string str;
for(auto& ch:data)
{
if(ch==',') //一直到“,”,取出前面元素
{
dataArray.push_back(str); //将取出来的字符串一个个放到list中
str.clear();
}else
str.push_back(ch);
}
if(!str.empty())
{
dataArray.push_back(str);
str.clear();
}
return rdeserialize(dataArray);
}
};