2023.9.4 序列化和反序列化二叉搜索树
上来的思路是序列化按照先序遍历构建字符串,空节点就用"#",每个节点之间用","进行分割。
比如示例1,就可以分割为2,1,#,#,3,#,#
然后反序列化只需要再按照这个字符串先序遍历一次即可。
代码如下:
class Codec {
public:
string serialize_helper(TreeNode *u, string &str) {
if (!u) { return ""; }
str += to_string(u->val);
str += ",";
if (u->left) {
serialize_helper(u->left, str);
} else {
str += "#,";
}
if (u->right) {
serialize_helper(u->right, str);
} else {
str += "#,";
}
return str;
}
// Encodes a tree to a single string.
string serialize(TreeNode* root) {
if (!root) { return {}; }
string str;
auto res = serialize_helper(root, str);
return res;
}
TreeNode* deserialize_helper(const vector<string> &nodes, uint32_t &idx) {
if (idx >= nodes.size() || nodes[idx] == "#") {
return nullptr;
}
TreeNode *u = new TreeNode();
u->val = stoi(nodes[idx]);
u->left = deserialize_helper(nodes, ++idx);
u->right = deserialize_helper(nodes, ++idx);
return u;
}
// Decodes your encoded data to tree.
TreeNode* deserialize(string data) {
if (data.empty()) {
return nullptr;
}
vector<string> nodes;
string tmp;
for (char c : data) {
if (c == ',') {
nodes.push_back(tmp);
tmp.clear();
} else {
tmp += c;
}
}
uint32_t idx = 0;
return deserialize_helper(nodes, idx);
}
};
但是这样实际上完成的是序列化和反序列化二叉树,没有用到BST的性质。
BST有左边比根节点小,右边比根节点大的性质,所以我们可以保存先序遍历的结果,不需要添加"#"来表示空节点。我们反序列化的时候判断当前节点是否比父亲节点小,如果不是,说明它必然是在根节点右边,反之亦然。