设计一个算法,并编写代码来序列化和反序列化二叉树。将树写入一个文件被称为“序列化”,读取文件后重建同样的二叉树被称为“反序列化”。
如何反序列化或序列化二叉树是没有限制的,你只需要确保可以将二叉树序列化为一个字符串,并且可以将字符串反序列化为原来的树结构。
注意事项
There is no limit of how you deserialize or serialize a binary tree, LintCode will take your output of serialize
as the input of deserialize
, it won't check the result of serialize.
给出一个测试数据样例, 二叉树{3,9,20,#,#,15,7}
,表示如下的树结构:
3
/ \
9 20
/ \
15 7
我们的数据是进行BFS遍历得到的。当你测试结果wrong answer时,你可以作为输入调试你的代码。
你可以采用其他的方法进行序列化和反序列化。
思路:用先序遍历 和 使用"#"来表示NULL的方法来序列化,最后也用先序遍历来反序列化。每个结点用"!"隔开。
二叉树的序列化 即给定二叉树的头指针,按照某种遍历方式将所有结点链接为一个数组或字符串。
二叉树的反序列化即根据给定的序列重新恢复一颗二叉树。
A. 这里给出的序列化按照二叉树的先序遍历方式将所有结点链接为字符串。
遇到空结点追加'#' 遇到非空结点追加结点的值即可。每个结点用"!"隔开。
B. 对于二叉树的反序列化只需要按照序列化的生成次序逆向思考即可。反序列化操作也是递归实现。先解析根结点之后解析左子树 最后解析右子树。
1. 遇到'#'说明是空结点
2. 遇到是数字(假定序列只有'#' 和 数字 和 '!' ) 说明是二叉树的某个结点。
3. 解析完一个结点之后跳过追加的 '!'接着解析下一个结点即可。
/**
* Definition of TreeNode:
* class TreeNode {
* public:
* int val;
* TreeNode *left, *right;
* TreeNode(int val) {
* this->val = val;
* this->left = this->right = NULL;
* }
* }
*/
class Solution {
public:
/**
* This method will be invoked first, you should design your own algorithm
* to serialize a binary tree which denote by a root node to a string which
* can be easily deserialized by your own "deserialize" method later.
*/
string serialize(TreeNode *root) { // 序列化
string str;
preOrderToString(root,str);
return str;
}
void preOrderToString(TreeNode* root,string &str){
if(root==NULL){
str+="#!";
return;
}
str+=to_string(root->val)+"!";
preOrderToString(root->left,str);
preOrderToString(root->right,str);
}
/**
* This method will be invoked second, the argument data is what exactly
* you serialized at method "serialize", that means the data is not given by
* system, it's given by your own serialize method. So the format of data is
* designed by yourself, and deserialize it here as you serialize it in
* "serialize" method.
*/
TreeNode *deserialize(string data) { // 反序列化
int pos = 0;
return preOrderToTree(data, pos);
}
TreeNode* preOrderToTree(string& data, int& pos){
if (data[pos] == '#')// 空树
{
pos += 2;
return NULL;
}
int val = 0;
while (data[pos] != '!')
{
val = val * 10 + (data[pos] - '0');
pos++;
}
pos++;
TreeNode* pNode = new TreeNode(val);
pNode->left = preOrderToTree(data, pos);
pNode->right = preOrderToTree(data, pos);
return pNode;
}
};