题目
请实现两个函数,分别用来序列化和反序列化二叉树
二叉树的序列化是指:把一棵二叉树按照某种遍历方式的结果以某种格式保存为字符串,从而使得内存中建立起来的二叉树可以持久保存。序列化可以基于先序、中序、后序、层序的二叉树遍历方式来进行修改,序列化的结果是一个字符串,序列化时通过 某种符号表示空节点(#),以 ! 表示一个结点值的结束(value!)。
二叉树的反序列化是指:根据某种遍历顺序得到的序列化字符串结果str,重构二叉树。
思路
- 思路一
- 非递归用按层序列化和反序列化。代码贼长。
- 序列化:用队列,结点进队列。每次一个结点处队列,将结点的左右孩子序列化,如果孩子不为空,将数字和!加入到字符串中,同时让孩子进队列。如果为空,把‘#’加入到字符串中。
- 反序列化,也要用到一个队列。先构建根结点,如果字符串中当前字符为‘#’,则跟节点的孩子为空。反之构造新结点,同时将新创建的孩子结点放入队列中,在下一次循环开始时,出队列一个结点,继续确定并左右孩子,然后将非空结点放入队列中…
- 循环直到队列为空。
- 思路二
- 用递归的方法,代码较短。
- 使用前序遍历
代码一
/*
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) {
if ( root == nullptr ) return nullptr;
string str = "";
SerializeCore( root, str ); // 序列化为一个string变量。
char* res = new char[str.size()+1];
for ( int i = 0; i < str.size(); ++i ) {
res[i] = str[i];
}
res[str.size()] = '\0';
return res;
}
void SerializeCore( TreeNode* root, string& str ) {
queue<TreeNode*> q;
q.push( root );
str += to_string( root->val ) + '!';
while ( !q.empty() ) {
TreeNode* node = q.front();
q.pop();
if ( !node->left ) { str += '#'; }
else {
str += to_string( node->left->val ) + '!';
q.push( node->left );
}
if ( !node->right ) { str += '#'; }
else {
str += to_string( node->right->val ) + '!';
q.push( node->right );
}
}
return;
}
TreeNode* Deserialize(char *str) {
if ( str == nullptr ) return nullptr;
int rootNum = getNum( &str );
TreeNode* root = new TreeNode( rootNum );
queue<TreeNode*> q;
q.push( root );
while ( !q.empty() ) {
TreeNode* node = q.front();
q.pop();
if ( *str == '#' ) {
node->left = nullptr;
++str;
}
else {
int nodeNum = getNum( &str );
node->left = new TreeNode( nodeNum );
q.push( node->left );
}
if ( *str == '#' ) {
node->right = nullptr;
++str;
}
else {
int nodeNum = getNum( &str );
node->right = new TreeNode( nodeNum );
q.push( node->right );
}
}
return root;
}
int getNum( char** str ) {
int res = 0;
while ( **str != '!' ) {
res = res * 10 + ( **str - '0' );
++(*str);
}
++(*str);
return res;
}
};
代码二
// 前序遍历序列化和反序列化二叉树
/*
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) {
if ( root == nullptr ) return nullptr;
string str = "";
SerializeCore( root, str );
char* res = new char[str.size()+1];
for ( int i = 0; i < str.size(); ++i )
res[i] = str[i];
res[str.size()] == '\0';
return res;
}
void SerializeCore( TreeNode* node, string& str ) {
if ( node == nullptr ) {
str += '#';
return;
}
str += to_string( node->val ) + '!';
SerializeCore( node->left, str );
SerializeCore( node->right, str );
return;
}
TreeNode* Deserialize(char *str) {
if ( str == nullptr ) return nullptr;
return DeserializeCore( &str );
}
TreeNode* DeserializeCore( char** str ) {
if ( **str == '#' ) {
++(*str);
return nullptr;
}
int nodeNum = 0;
while ( **str != '!' ) {
nodeNum = nodeNum * 10 + ( **str - '0' );
++(*str);
}
++(*str);
TreeNode* node = new TreeNode( nodeNum );
node->left = DeserializeCore( str );
node->right = DeserializeCore( str );
return node;
}
};
来源:CSDN
作者:PandaDou
链接:https://blog.csdn.net/m0_37822685/article/details/104308832