题目描述
请实现两个函数,分别用来序列化和反序列化二叉树
二叉树的序列化是指:把一棵二叉树按照某种遍历方式的结果以某种格式保存为字符串,从而使得内存中建立起来的二叉树可以持久保存。序列化可以基于先序、中序、后序、层序的二叉树遍历方式来进行修改,序列化的结果是一个字符串,序列化时通过 某种符号表示空节点(#),以 ! 表示一个结点值的结束(value!)。
二叉树的反序列化是指:根据某种遍历顺序得到的序列化字符串结果str,重构二叉树。
思路:
(1)序列化比较简单,就是将二叉树进行一个前序遍历,存储在一个string中,每个空节点存成“#!”,非空节点存成“value!”,最后将string类型复制到char*数组中。
(2)反序列化相对而言麻烦点:
1》计算每个节点的长度len,若str[idx]是‘#’代表空节点返回NULL,将索引号后移len+1,调到后一个节点;
2》对于非空节点,判断其正负,赋值给value,创建树节点,下面就是对左右节点递归赋值操作。
代码段:
前序遍历序列化,反序列化。
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 tmp;
dfs1(root, tmp);
char* res=new char[tmp.size()+1];
strcpy(res, tmp.c_str());
return res;
}
void dfs1(TreeNode* root,string & tmp) {
if (root == nullptr) {
tmp += "#!";
return;
}
tmp += to_string(root->val) + '!';
dfs1(root->left, tmp);
dfs1(root->right, tmp);
}
//反序列化//
TreeNode* Deserialize(char* str) {
int idx = 0;
return dfs2(str,idx);
}
TreeNode* dfs2(char* str, int& idx) {
int len = idx;
while (str[len] != '!') len++;//计算每个节点的数值长度
//(1)对于空节点直接跳过
if (str[idx] == '#') {
idx=len+1;
return nullptr;
}
//(2)对于非空节点,计算数值,转化成二叉树val值
int tag = 1;//标签值,若为正则为1,若为负,则为-1;
if (str[idx] == '-' && idx < len) {//判断节点数值是否为负数?
tag = -1;
idx++;
}
int value = 0;//计算节点的值;
for (int i = idx; i < len; ++i) {
value = value * 10 + str[i] - '0';
}
value *= tag;
idx=len+1;//idx移到下一个节点。
TreeNode* root = new TreeNode(value);
root->left = dfs2(str, idx);
root->right = dfs2(str, idx);
return root;
}
};