原题链接:二叉树的序列化与反序列化
题解
DFS
思路:
前序遍历二叉树,遇到空则将空表示为null,然后构造的时候再按照字符串进行前序构造。
时间复杂度: O ( n ) O(n) O(n)
代码:
/**
* 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:
void preOrder(TreeNode *root, string &s) {
if(root == NULL) {
s += " null";
return;
}
s += " " + to_string(root->val);
preOrder(root->left, s);
preOrder(root->right, s);
}
vector<string> split(string &s, char delim) {
stringstream ss(s);
string item;
vector<string> res;
while(getline(ss, item, delim)) {
if(!item.empty())
res.push_back(item);
}
return res;
}
// Encodes a tree to a single string.
string serialize(TreeNode* root) {
string res;
preOrder(root, res);
return res;
}
int cur = 0;
TreeNode *build(vector<string> &v) {
if(v[cur] == "null") {
cur ++;
return NULL;
}
TreeNode *root = new TreeNode(atoi(v[cur ++].c_str()));
root->left = build(v);
root->right = build(v);
return root;
}
// Decodes your encoded data to tree.
TreeNode* deserialize(string data) {
vector<string> v = split(data, ' ');
cur = 0;
return build(v);
}
};
// Your Codec object will be instantiated and called as such:
// Codec ser, deser;
// TreeNode* ans = deser.deserialize(ser.serialize(root));
LL(1)型文法 + 递归下降解析
思路:
我们可以构造二叉树序列化为 (leftTree)num(rightTree)
,其中num
root的值。若子树为空,则用'#'
表示。
那么该文法为
T -> (T) num (T)
| #
其无左递归也不存在二义性,故为LL(1)型文法,那么我用LL(1)型文法的手工解析,递归下降法进行解析。
时间复杂度: O ( n ) O(n) O(n)
代码:
/**
* 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 == NULL) return "#";
string left = "(" + serialize(root->left) + ")";
string right = "(" + serialize(root->right) + ")";
return left + to_string(root->val) + right;
}
TreeNode *parse(string &data, int &cur) {
if(data[cur] == '#') {
cur ++;
return NULL;
}
TreeNode *root = new TreeNode();
root->left = parseSub(data, cur);
root->val = parseInt(data, cur);
root->right = parseSub(data, cur);
return root;
}
TreeNode *parseSub(string &data, int &cur) {
cur ++;
TreeNode *root = parse(data, cur);
cur ++;
return root;
}
int parseInt(string &data, int &cur) {
int x = 0, sign = 1;
if(!isdigit(data[cur])) {
cur ++;
sign = -1;
}
while(isdigit(data[cur])) {
x = x * 10 + (data[cur ++] - '0');
}
return x * sign;
}
// Decodes your encoded data to tree.
TreeNode* deserialize(string data) {
int cur = 0;
return parse(data, cur);
}
};
// Your Codec object will be instantiated and called as such:
// Codec ser, deser;
// TreeNode* ans = deser.deserialize(ser.serialize(root));