题目
序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据。
请设计一个算法来实现二叉树的序列化与反序列化。这里不限定你的序列 / 反序列化算法执行逻辑,你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序列化为原始的树结构。
示例
你可以将以下二叉树:
1
/ \
2 3
/ \
4 5
序列化为 "[1,2,3,null,null,4,5]"
思路
- 序列化
- 用一个string保存序列。
- 使用先序遍历,遇到空结点,字符串保存‘#’。否则,当前节点的数字保存为字符串,用’!'号结尾。比如上面的例子,序列化后为“1!2!3!##4!5!”。
- 反序列化
- 遍历字符串,如果遇到‘#’,返回nullptr。否则根据’!'号,找到节点的数字字符串,转化为数字,创建新的节点。然后左右节点递归调用。
代码
/**
* 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 ans = "";
serializeCore( root, ans );
return ans;
}
void serializeCore( TreeNode* node, string& seq ) {
if ( node == nullptr ) {
seq += '#';
return;
}
seq += to_string( node->val ) + '!';
serializeCore( node->left, seq );
serializeCore( node->right, seq );
return;
}
// Decodes your encoded data to tree.
TreeNode* deserialize(string data) {
if ( data == "" )
return nullptr;
int index = 0;
return deserializeCore( data, index );
}
TreeNode* deserializeCore( string& str, int& index ) {
if ( str[index] == '#' ) {
++index;
return nullptr;
}
int left = index;
while ( str[index] != '!' )
++index;
string temp = str.substr( left, index - left );
TreeNode* node = new TreeNode( stoi( temp ) );
++index;
node->left = deserializeCore( str, index );
node->right = deserializeCore( str, index );
return node;
}
int stoi( string& str ) {
int res = 0;
int sign = 1;
int i = 0;
if ( str[0] == '-' ) {
sign = -1;
i = 1;
}
while ( i < str.size() )
res = res * 10 + ( str[i++] - '0' );
return sign * res;
}
};
// Your Codec object will be instantiated and called as such:
// Codec codec;
// codec.deserialize(codec.serialize(root));