Tag
【序列化与反序列化】【二叉搜索树】【二叉树】【2023-09-04】
题目来源
题目解题
设计类的题目,实现二叉搜索树的两个功能:
- 序列化:将二叉树搜索树结构以字符串的形式保存;
- 反序列化:将对应二叉搜索树的字符串形式结果还原回二叉搜索树结构。
对序列化和反序列的工作方式没有限制,保存二叉搜索树通常有前序、中序、后续以及层序遍历保存的形式,因此,序列化/反序列可以使用以上四种遍历保存方式的任意一种。
解题思路
我们使用前序遍历的方式来进行序列化和反序列化。前序遍历的方式是先遍历根节点,再递归遍历左子节点,再递归遍历右子节点,对于每个递归也是按照先遍历根节点,再遍历左子节点,最后再遍历右子节点的顺序进行。
对于序列化,我们进行这样的设计:
- 我们将前序遍历的节点值依次加入到
str
字符串中; - 使用字符
'!'
将各个节点值分隔开; - 在遍历过程中遇到的空节点,我们使用字符
'#'
表示;
最后,输出前序遍历后得到的字符串 str
即为序列化结果。这里的前序遍历是使用递归来实现的,其他几种方式的实现可以参考 二叉树的遍历方式与实现。
反序列化需要根据序列化的方式来进行,序列化使用的是前序遍历的方式,那么发序列化就要按照前序遍历的方式进行,具体地:
- 序列化的结果
str
中首元素是根节点值,根据值建立根节点; - 对剩下的值,递归调用建立左、右子树;
- 将根节点与左、右子树连接起来。
具体实现中,我们可以需要先把字符串 str
按照从左到右的顺序加入到队列 que
中,利用队列特性方便弹出根节点,利用剩下的节点建立子树。
实现代码
/**
* 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 == nullptr) {
return "#!";
}
string res;
res = to_string(root->val) + "!";
res += serialize(root->left);
res += serialize(root->right);
return res;
}
// Decodes your encoded data to tree.
TreeNode* deserialize(queue<string>& que) {
string values = que.front();
que.pop();
if(values == "#") {
return nullptr;
}
TreeNode *root = new TreeNode(stoi(values));
root->left = deserialize(que);
root->right = deserialize(que);
return root;
}
TreeNode* deserialize(string data) {
// 以 ! 为分隔符存入队列
queue<string> que;
string str;
for(int i = 0; i < data.size(); ++i) {
if(data[i] == '!') {
que.push(str);
str = "";
}
else {
str += data[i];
}
}
return deserialize(que);
}
};
// Your Codec object will be instantiated and called as such:
// Codec* ser = new Codec();
// Codec* deser = new Codec();
// string tree = ser->serialize(root);
// TreeNode* ans = deser->deserialize(tree);
// return ans;
复杂度分析
时间复杂度: O ( n ) O(n) O(n), n n n 为二叉搜索树的节点数量,序列化和反序列的最坏时间复杂度都是 O ( n ) O(n) O(n);
空间复杂度:
O
(
2
n
−
n
)
O(2^n-n)
O(2n−n),最坏情况了树的高度为 n
,树的每一层只有一个节点,其余都是空节点,一共要使用
2
n
−
n
−
1
2^n-n-1
2n−n−1 个额外空间,队列使用的空间也是。
关于以上的复杂度分析不知道有没有问题,欢迎大家一起讨论。
写在最后
以上就是本篇文章的内容了,感谢您的阅读。🍗🍗🍗
如果感到有所收获的话可以给博主点一个 👍 哦。
如果文章内容有任何错误或者您对文章有任何疑问,欢迎私信博主或者在评论区指出。💬💬💬