题目如下
我们常常说单独先序遍历不能完整的表示一棵树是有前提条件的。
为什么?先序遍历是按 根节点 左子树 右子树的方向遍历树且遇到空子树直接返回,这样会造成我们并不知道某个节点的左右子树存在与否,故我们无法确定树的形状。但是如果我们在遍历的时候加入该子树为空的标记不就知道某个节点后面跟的是左子树还是右子树了吗?好了,把这个思想用到本题就迎刃而解了。
通过代码
/**
* 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:
string ans = "";
void pre(TreeNode* root) {
if (root == nullptr){
ans += "n,";//用n表示该子树为空
return;
}
ans += to_string(root->val);
ans += ",";
pre(root->left);
pre(root->right);
}
// Encodes a tree to a single string.
string serialize(TreeNode* root) {
if (root == nullptr)
return ans;
pre(root);
return ans;
}
TreeNode* build(list<string> &pre){
if(pre.size() == 0)return nullptr;
if(pre.front() == "n"){//没有左子树或者右子树
pre.erase(pre.begin());
return nullptr;
}
TreeNode *a = new TreeNode(stoi(pre.front()));
pre.erase(pre.begin());
a -> left = build(pre);
a -> right = build(pre);
return a;
}
// Decodes your encoded data to tree.
TreeNode* deserialize(string data) {
if (data.size() == 0)
return nullptr;
int n = data.size();
// cout << data << endl;
int s = 0,end = 0;
list<string> vs;
while(true){
end = data.find(',',s);
vs.emplace_back(data.substr(s,end - s));
s = end + 1;
if(end == n - 1)break;
}
TreeNode *a = build(vs);
return a;
}
};
// Your Codec object will be instantiated and called as such:
// Codec ser, deser;
// TreeNode* ans = deser.deserialize(ser.serialize(root));