设计一个算法,并编写代码来序列化和反序列化二叉树。将树写入一个文件被称为“序列化”,读取文件后重建同样的二叉树被称为“反序列化”。
如何反序列化或序列化二叉树是没有限制的,你只需要确保可以将二叉树序列化为一个字符串,并且可以将字符串反序列化为原来的树结构。
样例
给出一个测试数据样例, 二叉树{3,9,20,#,#,15,7},表示如下的树结构:
3
/ \
9 20
/ \
15 7
我们的数据是进行BFS遍历得到的。当你测试结果wrong answer时,你可以作为输入调试你的代码。
你可以采用其他的方法进行序列化和反序列化。
思路:二叉树的广度优先遍历
C++:
/**
* 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) {
// write your code here
string data = "";
if(root == NULL)
{
return data;
}
std::vector<TreeNode*> queue;
queue.push_back(root);
for(int i=0;i<queue.size();i++)
{
TreeNode *q = queue[i];
if(q == NULL)
continue;
queue.push_back(q->left);
queue.push_back(q->right);
}
for (int i = 0; i<queue.size(); i++)
{
TreeNode* tem = queue[i];
if (tem != NULL)
{
char t[256];
string s;
sprintf(t, "%d", tem->val);
s = t;
data += (s + ",");
}
else
{
data += "#,";
}
}
return data;
}
/**
* 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) {
// write your code here
if (data == "")
return NULL;
vector<string> tree = split(data, ","); //分割得到每一个节点
queue<TreeNode*> execute; //待插入子树的节点队列
TreeNode * root = (TreeNode*)malloc(sizeof(TreeNode));//创建根节点
root->left = root->right = NULL;
root->val = atoi(tree[0].c_str());
tree.erase(tree.begin());
TreeNode* p = root;
execute.push(p);
while (execute.size() != 0)
{
if (tree.size()<2)
break;
TreeNode* cur = execute.front();
execute.pop();
if (tree[0] != "#") //处理左子树
{
TreeNode* tem = (TreeNode*)malloc(sizeof(TreeNode));
tem->val = atoi(tree[0].c_str());
tem->left = tem->right = NULL;
cur->left = tem;
execute.push(tem); //左节点不是NULL,所以需要插入到队列中,准备插入其自己的左右子节点
tree.erase(tree.begin()); //删除tree中该节点表示该节点已经处理过了
}
else
{
tree.erase(tree.begin()); //如果cur的左节点是NULL,直接删除Tree中的该节点表示已经处理就好了。
}
if (tree[0] != "#") //处理右子树
{
TreeNode* tem = (TreeNode*)malloc(sizeof(TreeNode));
tem->val = atoi(tree[0].c_str());
tem->left = tem->right = NULL;
cur->right = tem;
execute.push(tem);
tree.erase(tree.begin());
}
else
{
tree.erase(tree.begin());
}
}
return root;
}
};
Py3:
"""
Definition of TreeNode:
class TreeNode:
def __init__(self, val):
self.val = val
self.left, self.right = None, None
"""
class Solution:
"""
@param root: An object of TreeNode, denote the root of the binary tree.
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.
"""
def serialize(self, root):
# write your code here
tree,ch = [root],[]
while len(tree)>0:
temp = tree.pop(0)
if temp is None:
ch.append('#')
else:
ch.append(str(temp.val))
tree.append(temp.left)
tree.append(temp.right)
return ','.join(ch)
"""
@param data: A string serialized by your serialize method.
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.
"""
def deserialize(self, data):
# write your code here
s, i = data.split(','), 0
if s[i] == '#':
return None
root = TreeNode(int(s[i]))
tree = [root]
while len(tree) > 0:
te = tree.pop(0)
i += 1
if s[i] != '#':
k = TreeNode(int(s[i]))
te.left = k
tree.append(k)
i += 1
if s[i] != '#':
k = TreeNode(int(s[i]))
te.right = k
tree.append(k)
return root