序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据。
请设计一个算法来实现二叉树的序列化与反序列化。这里不限定你的序列 / 反序列化算法执行逻辑,你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序列化为原始的树结构。
提示: 输入输出格式与 LeetCode 目前使用的方式一致,详情请参阅 LeetCode 序列化二叉树的格式。你并非必须采取这种方式,你也可以采用其他的方法解决这个问题。
思路:广度优先 + 迭代法。
其实题目的意思就是写一个函数将二叉树转成字符串(字符串的形式随你定,可以是题目所给的"[1,2,3,null,null,4,5]",也可以是本文代码中"1 2 3 null null 4 5"的形式)。然后再写一个函数将字符串成功转回一开始的二叉树,此时最后返回的二叉树必须与题目给的一模一样。
先放C++代码,思路清晰明了,基本注释已写好在代码中。
/**
* 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) {
if(!root){
return ""; // 判空
}
ostringstream out;//处理字符串 字符集操作模板类
queue<TreeNode*> bfs;
bfs.push(root);
while(!bfs.empty()){
// 迭代法
TreeNode* temp = bfs.front();
bfs.pop();
if(temp){
out<< temp -> val << " ";
bfs.push(temp -> left);
bfs.push(temp -> right);
}
else{
out<< "null "; // 注意 null 后面有空格
}
}
return out.str(); // out 用来将树转成字符串,元素之间用空格分隔
}
// Decodes your encoded data to tree.
TreeNode* deserialize(string data) {
if(data.empty()){
return nullptr; // 判空
}
istringstream input(data);
string info;
vector<TreeNode*> res; // res 用来将字符串里每个元素转成 TreeNode* 形式的元素
while(input >> info){
if(info == "null"){ // 注意 null 后面没空格(因为空格是用来分隔字符串的,不属于字符串)
res.push_back(nullptr);
}
else{
res.push_back(new TreeNode(stoi(info)));//stoi(info) info string转换成int
}
}
int pos = 1;
for(int i = 0; pos < res.size(); ++i){
// 本循环将 res 中的所有元素连起来,变成一棵二叉树
if(!res[i]){
continue;
}
res[i] -> left = res[pos++]; // pos 此时指向左子树,++后指向右子树 因为序列化时,out<< temp -> val << " ";
//bfs.push(temp -> left);
//bfs.push(temp -> right);
if(pos < res.size()){
res[i] -> right = res[pos++]; // pos 此时指向右子树,++后指向下一个节点的左子树
}
}
return res[0];
}
};