每日一题 0220
(2022.02.20) 每日一题 二叉树的序列化和反序列化
序列化其实就是把结构化的数据展平,那么就是你去对树进行遍历而已,你把树的遍历结果定下来,那么不就是这个树的结构就出来了吗?
这个地方光用一种遍历就可以确定一棵树是因为,我们在序列化的时候会把空指针都给表示出来,那么我们就可以区分是左子树还是右子树了呀!
拿先序遍历做例子就是,整体结构符合根—左—右的结构,每一颗子树也是保持这样的子结构,序列的第一个一定是根节点,根节点的下一个一定是左子树的根节点,那么下一个也是左子子树的根节点咯,但是如果是空指针,那不就说明左子树结束了,所以遇到空指针一定就代表了左子树或右子树的递归结束。
所以性质就是,当我们的遍历列表的第一个元素就是一棵树的根节点,我们每遍历一个当前根节点就把节点弹出,让递归函数去处理剩下的节点,当遇到空指针时,代表了一个小分支的结束,切换到另一分支,如若另一分支也是空指针,那么就会返回上层递归,继续递归上一层的另一分支,直到结束。
- 使用stoi可以将字符串转为int数字。
/**
* 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 {
private:
queue<string> word_dict;
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);
string ans = to_string(root->val) + ","+left+"," + right;
return ans;
}
queue<string> split(string &data){
int start=0; //初始查找位置
queue<string> res; //保存分割结果
std::string::size_type pos; //find()函数的返回值类型
while(1){
pos = data.find(',',start);
if(pos==string::npos)break; //如果没有找到,pos==string::npos,直接break
res.push(data.substr(start,pos-start)); //substr(pos, n)为获取子串,pos为起始位置(默认为0),n为结束位置(默认为npos)
start=pos+1; //更新下一次查找位置
}
return res;
}
TreeNode* deserialize(queue<string>& data) {
if(data.size()==0){
return NULL;
}
string first = data.front();
data.pop();
if(first == "#") return nullptr;
TreeNode* root = new TreeNode(stoi(first));
root->left = deserialize(word_dict);
root->right = deserialize(word_dict);
return root;
}
// Decodes your encoded data to tree.
TreeNode* deserialize(string data) {
word_dict = split(data);
TreeNode* res = deserialize(word_dict);
return res;
}
};
// Your Codec object will be instantiated and called as such:
// Codec ser, deser;
// TreeNode* ans = deser.deserialize(ser.serialize(root));

浙公网安备 33010602011771号