题目描述
请实现两个函数,分别用来序列化和反序列化二叉树。
您需要确保二叉树可以序列化为字符串,并且可以将此字符串反序列化为原始树结构。
样例
你可以序列化如下的二叉树
8
/ \
12 2
/ \
6 4
为:"[8, 12, 2, null, null, 6, 4, null, null, null, null]"
算法
(二叉树,序列化反序列化) $O(n)$
序列化:按照某种规定将树的节点序列化为字符串,反序列化:根据序列化得到的字符串反序列化建出一棵树
序列化:这里按照前序遍历的顺序将树的节点序列化为字符串,其中空节点用字符串 null
代替,每个节点用空格隔开
反序列化:将序列化得到的字符串进行拆解
- u 指向当前节点,k 指向当前节点的下一个位置即空格,k + 1 是下一个节点
- 把当前节点转换为数字,如果是负数,需要先过滤掉
-
号,然后值*-1
- 新建当前节点,指向它的左右儿子
- 递归处理,直到字符串处理完毕,返回根节点
时间复杂度
序列化和反序列化每个节点仅被遍历一次,所以时间复杂度为 $O(n)$
C++ 代码
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
void dfs_s(TreeNode* root, string &res)
{
if (!root)
{
res += "null ";
return;
}
res += to_string(root->val) + ' ';
dfs_s(root->left, res);
dfs_s(root->right, res);
}
// Encodes a tree to a single string.
string serialize(TreeNode* root) {
string res;
if (!root) return res;
dfs_s(root, res);
return res;
}
TreeNode* dfs_d(string data, int &u)
{
if (u == data.size()) return NULL;
int k = u;
while (data[k] != ' ') k ++ ;
if (data[u] == 'n')
{
u = k + 1;
return NULL;
}
int val = 0, sign = 1;
while (u < k && data[u] == '-') sign = -1, u ++ ;
for (int i = u; i < k; i ++ ) val = val * 10 + data[i] - '0';
val *= sign;
u = k + 1;
TreeNode* root = new TreeNode(val);
root->left = dfs_d(data, u);
root->right = dfs_d(data, u);
return root;
}
// Decodes your encoded data to tree.
TreeNode* deserialize(string data) {
int u = 0;
return dfs_d(data, u);
}
};