's sword refers to Offer - serialized binary tree

Topic description

Please implement two functions to serialize and deserialize binary trees respectively

Topic analysis: The requirements of the title do not seem to be very clear. Serialization means to convert some specific data structures into strings with format information. For example, for a linked list, 1->2->3->4->NULL can be serialized as "1,2,3,4". For the serialization algorithm, deserialization must be supported, that is, in the agreed format, the string that meets the format requirements can be reconstructed into the original structural form. In fact, a sequence is used to represent a binary tree, and then the binary tree can be reconstructed based on this sequence. There is no serialization method specified here, no matter what string it is serialized into, as long as the binary tree can be restored and reconstructed.

Problem solving ideas:

According to the previous interview questions to reconstruct the binary tree , we know that a binary tree can be constructed from preorder traversal and inorder traversal. Inspired by this, we can first serialize a binary tree into a combination of a preorder traversal sequence and an inorder sequence, and then reconstruct the original binary tree through these two sequences during deserialization.

But this approach has two drawbacks. One disadvantage is that this method requires that nodes with repeated values ​​cannot be used in the binary tree. In addition, deserialization can only start after all data in both sequences has been read. If the data of the two traversal sequences are read from a stream, it may take a long time.

In fact, if the serialization of the binary tree starts from the root node, then the corresponding deserialization can start when the value of the root node is read. So we can serialize the binary tree according to the order of the preorder traversal, because the preorder traversal starts from the root node. When traversing a binary tree and encountering NULL pointers, these NULL pointers are serialized into a special character (eg '$'). In addition, the values ​​of the nodes should be separated by a special character (such as ','). Take the binary tree in the following figure as an example:

1                 1
2                / \
3               2   3
4              /   / \
5             4   5   6

  • Serialization: For the tree in the above figure, when performing preorder traversal, first visit 1, then 2, then the left and right child nodes of 4 and 4 are empty, which can be replaced by a special character, such as $, so the above The preorder traversal of the binary tree in the figure is "1,2,4,$,$,$,3,5,$,$,6,$,$".
  • Deserialization: When rebuilding, the first node visited is the root node, and the next number is 2, which is the left child of the root node. Next is 4, which is the left child of 2. Then encounter two $, indicating that the left and right child nodes of 4 are all NULL. Next, the node rolls back and visits the parent node 2 of 4, which is $ again, indicating that the right child node of 2 is NULL. Returning to the root node, it is time to establish its right child node. The next value is 3, indicating that 3 is the right child node of the root node. The remaining steps are similar to the left subtree.

After the traversal of the binary tree is done too much, it should not be difficult to recursively implement the pre-order traversal and rebuild the binary tree according to the sequence obtained by the pre-order traversal. For me, the main problem of this problem is the control of the input stream, which has not been used very well. Instead of misleading people with your own code, look for someone else's code to look at.


struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
class Solution {
    TreeNode* decode(char *&str) {
            return NULL;
        int num = 0;
        while(*str != ',')
            num = num*10 + (*(str++)-'0');
        TreeNode *root = new TreeNode(num);
        root->left = decode(str);
        root->right = decode(str);
        return root;
    char* Serialize(TreeNode *root) {   
        if(!root) return "#";
        string r = to_string(root->val);
        char *left = Serialize(root->left);
        char *right = Serialize(root->right);
        char *ret = new char[strlen(left) + strlen(right) + r.size()];
        strcpy(ret, r.c_str());
        strcat(ret, left);
        strcat(ret, right);
        return ret;
    TreeNode* Deserialize(char *str) {
        return decode(str);

Guess you like