Problem Description:
Serialization is to convert a data structure or object consecutive bits in operation, further data may be stored in a converted file or memory, but may also be transmitted to another computer through a network environment, to take the opposite way Reconstruction get the original data.
Please design an algorithm to implement serialization and de-serialization binary tree. Herein is not limited to your serial / deserialization algorithm execution logic, you only need to ensure that a binary tree can be serialized into a string and the string deserialize the original tree structure.
Example:
You can use the following binary tree:
1
/ \
23
/ \
45
sequence into"[1,2,3,null,null,4,5]"
Tip: a consistent manner which LeetCode currently used, please refer to LeetCode serialized binary format . You do not have to take this approach, you can also employ other methods to solve this problem.
Description: members not to use the class / global / static variables to store state, your serialization and de-serialization algorithm should be stateless.
The basic idea:
This I am also referring to someone else's blog, and later had wanted to work in accordance with the relevant provisions of the company to serialization and de-serialization binary tree.
I did not expect to do problems behind when she ran. Block so you have to force yourself to learn serialization and de-serialization really is amazing. Now I will talk about specific ideas:
First, we should think about - what kind of string can represent a full tree .
We all know that one of the preamble and the subsequent sequence can be constructed in both + binary tree. But we really can not store a string of so much information. then what should we do?
Here introduces a tip: by recording the node behind the empty leaf node, can be completely constructed by inorder traversal of a tree .
The principle is that we encountered when an empty node branch has been determined we finished ; Similarly we can handle another branch in this way.
Comprehensive look at the use of recursion can be expressed complete a tree up.
This is almost the easiest way I've found.
Use [] and to the difference between the left and right sub-tree sub-tree data structure of the book I am. So that our codecs are very troublesome.
The codec used here, as long as a normal "," to separate the information for each node. Simply do not record redundant information about sub-tree.
Because we can judge by the root node. It can be described as the easiest way.
Coding is very simple. The key is to decode.
My approach is:
- Queue a structure, used to store remove "," element of a.
- # Encounter when traversing representatives completed, POP queue (which is the reason why I chose to queue) , then returns NULL
- Normal processing can look at the code, the more clear.
AC Code:
/**
* 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 == NULL) return "#";
return to_string(root->val) + "," + serialize(root->left)
+ "," + serialize(root->right);
}
// Decodes your encoded data to tree.
TreeNode* deserialize(string data) {
// 获得关于val的队列
queue<string> q;
int i = 0;
while (i != data.size()) {
string temp; // 存储两个,之间的字符串
while (i != data.size() && data[i] != ',') {
temp += data[i++];
}
q.push(temp);
if (data[i] == ',') ++i;
}
return Deserialize(q);
}
TreeNode *Deserialize(queue<string> &q) {
if (q.size() == 0) return NULL;
if (q.front() == "#") {
q.pop();
return NULL;
}
auto root = new TreeNode(stoi(q.front()));
q.pop();
root->left = Deserialize(q);
root->right = Deserialize(q);
return root;
}
};
// Your Codec object will be instantiated and called as such:
// Codec codec;
// codec.deserialize(codec.serialize(root));