题目描述:
序列化是将数据结构或对象转换为一系列位的过程,以便它可以存储在文件或内存缓冲区中,或通过网络连接链路传输,以便稍后在同一个或另一个计算机环境中重建。
设计一个算法来序列化和反序列化二叉搜索树。 对序列化/反序列化算法的工作方式没有限制。 您只需确保二叉搜索树可以序列化为字符串,并且可以将该字符串反序列化为最初的二叉搜索树。
编码的字符串应尽可能紧凑。
注意:不要使用类成员/全局/静态变量来存储状态。 你的序列化和反序列化算法应该是无状态的。
解题思路:
- 按层序遍历进行序列化,空节点存储为#,对于非空节点值在后面加一个 ‘.’ 作为分割。比如[2,1,3],存储为 “2.1.3.####”。
- 反序列化时也是按层序构建,根据 ‘.’ 将节点值分隔出来,#则建立空节点,实现起来也不难
代码实现:
class Codec {
public:
// Encodes a tree to a single string.
string serialize(TreeNode* root) {
string str;
if (root == nullptr)
return str;
queue<TreeNode*> nodes; //层序遍历辅助队列
nodes.push(root);
while (!nodes.empty())
{
int count = nodes.size();
while (count--) {
TreeNode* cur = nodes.front();
nodes.pop();
if (cur == nullptr) {
str += '#';
}
else {
str += to_string(cur->val) + '.';
nodes.push(cur->left);
nodes.push(cur->right);
}
}
}
return str;
}
// Decodes your encoded data to tree.
TreeNode* deserialize(string data) {
if (data.empty())
return nullptr;
int i = 0, j = 0;
while (j < data.size() && data[++j] != '.'); // data[i, j)为节点值
TreeNode* root = new TreeNode(stoi(data.substr(i, j - i)));
queue<TreeNode*> nodes; //反序列化辅助队列
nodes.push(root);
while (!nodes.empty())
{
TreeNode* cur = nodes.front();
nodes.pop();
if (cur == nullptr)
continue;
//构造cur左子节点
i = ++j;
if (data[i] == '#') {
cur->left = nullptr;
}
else {
while (j < data.size() && data[++j] != '.'); // data[i, j)为节点值
cur->left = new TreeNode(stoi(data.substr(i, j - i)));
}
nodes.push(cur->left);
//构造cur右子节点
i = ++j;
if (data[i] == '#') {
cur->right = nullptr;
}
else {
while (j < data.size() && data[++j] != '.'); // data[i, j)为节点值
cur->right = new TreeNode(stoi(data.substr(i, j - i)));
}
nodes.push(cur->right);
}
return root;
}
};