Serialize and Deserialize Binary Tree
Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in the same or another computer environment.
Design an algorithm to serialize and deserialize a binary tree. There is no restriction on how your serialization/deserialization algorithm should work. You just need to ensure that a binary tree can be serialized to a string and this string can be deserialized to the original tree structure.
Example:
You may serialize the following tree:
1
/ \
2 3
/ \
4 5
as "[1,2,3,null,null,4,5]"
Clarification: The above format is the same as how LeetCode serializes a binary tree. You do not necessarily need to follow this format, so please be creative and come up with different approaches yourself.
Note: Do not use class member/global/static variables to store states. Your serialize and deserialize algorithms should be stateless.
分析:
递归:
利用先序遍历,空节点用特殊符号如"#"代替,为了在反序列时找到每个节点,序列间节点间可以用' , '隔开。
class Codec {
public:
// Encodes a tree to a single string.
string serialize(TreeNode* root) {
if (root == nullptr) return "#";
return to_string(root->val)+","+serialize(root->left)+","+serialize(root->right);
}
// Decodes your encoded data to tree.
TreeNode* deserialize(string data) {
return mydeserialize(data);
}
TreeNode* mydeserialize(string& data) {
if (data[0]=='#') {
if(data.size() > 1) data = data.substr(2);
return nullptr;
} else {
TreeNode* node = new TreeNode(helper(data));
node->left = mydeserialize(data);
node->right = mydeserialize(data);
return node;
}
}
private:
int helper(string& data) {
int pos = data.find(',');
int val = stoi(data.substr(0,pos));
data = data.substr(pos+1);
return val;
}
};
在剑指offer中,函数的返回类型为char*,因此需要与字符串进行转换:
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};
*/
class Solution {
public:
char* Serialize(TreeNode *root) {
string s = serializeHelper(root);
char *str = new char[s.length() + 1];
strcpy(str, s.c_str());
return str;
}
string serializeHelper(TreeNode *node) {
if (node == NULL) return "#";
return to_string(node->val) + "," + serializeHelper(node->left) + "," + serializeHelper(node->right);
}
TreeNode* Deserialize(char *str) {
string s(str);
return myDeserialize(s);
}
TreeNode* myDeserialize(string &s) {
if (s[0] == '#') {
if (s.size() > 1) s= s.substr(2);
return nullptr;
} else {
TreeNode *node = new TreeNode(helper(s));
node->left = myDeserialize(s);
node->right = myDeserialize(s);
return node;
}
}
private:
int helper(string &s) {
int pos = s.find(',');
int val = stoi(s.substr(0, pos));
s = s.substr(pos + 1);
return val;
}
};
但是,手动进行string与char*之间的转换效率很低:
*Runtime:*152ms,*Memory:*534.6MB
因此采用stringstream可以使代码更加简洁并且效率更高:
*Runtime:*36ms,Memory: 34.3MB
class Codec {
public:
// Encodes a tree to a single string.
string serialize(TreeNode* root) {
if (root == NULL) return "#";
return to_string(root->val) + "," + serialize(root->left) + "," + serialize(root->right);
}
TreeNode* deserialize(string data) {
if (data == "#") return NULL;
stringstream s(data);
return makeDeserialize(s);
}
TreeNode* makeDeserialize(stringstream& s) {
string str;
getline(s, str, ',');
if (str == "#") {
return NULL;
} else {
TreeNode* root = new TreeNode(stoi(str));
root->left = makeDeserialize(s);
root->right = makeDeserialize(s);
return root;
}
}
};