Binary tree serialization and deserialization of data structures (including code implementation)

content

1. Rebuild the binary tree 

2. Binary tree serialization and deserialization


1. Rebuild the binary tree 

Binary tree traversal

Topic description:

 Problem solving ideas:

1. Since the empty node of the preorder traversal sequence has been represented by '#', we can recursively restore the binary tree. If '#' is encountered, return nullptr, otherwise, create a new head node, and then recursively construct its left subtree and The right subtree, after the construction is complete, return the head node.

Take the sequence abc##d### as an example (sorry the last # can't be put down)

1. First come to the head node and find that it is not empty to create a node:

Then recursively create its left subtree, and then recursively create its right subtree. Come to b is not #create node b. (I wrote one less #sorry)

 

Go to the next node and find that it is not empty to create node c:

When I came to the next node, I found that it was #similarly found that the next node was also # Return to empty, then c is created and returned to the b chain, and in the picture, I linked it in advance for the sake of appearance:

 Then go to the next node to find an empty creation that is not:

Then create an empty space (because I couldn't write down a # before), the same is true for the following:

 

 Corresponding code:

#include<string>
#include<iostream>
using namespace std;
class TreeNode{
  public:
    
   void Inorder(TreeNode*root){
        if(!root)return;
       Inorder(root->_left );
       cout<<root->val<<" ";
       Inorder(root->_right);
    }
    
    TreeNode(char ch)
    :_left(nullptr)
    ,_right(nullptr)
    ,val(ch)
    {}
    TreeNode*_left;
    TreeNode*_right;
    char val;
};

  TreeNode*CreatTree(const string&s,int &i){
              if(s[i]=='#'){//返回空
                  i++;
                  return nullptr;
              }
      
      TreeNode*root=new TreeNode(s[i++]);
      root->_left=CreatTree(s,i);//构建左树
      root->_right=CreatTree(s,i);//构建右树
      return root;//返回根节点
      
  }

int main(){
    string s;
    cin>>s;
    int i=0;
    TreeNode*root=CreatTree(s,i);
    root->Inorder(root);
    
    
}

2. Binary tree serialization and deserialization

297. Serialization and Deserialization of Binary Tree - LeetCode (leetcode-cn.com)

Topic description:

/**
 * 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){
            return "#";
        }
    return to_string(root->val)+" "+serialize(root->left)+" "+serialize(root->right);//转换字符串
    }

    // Decodes your encoded data to tree.
    TreeNode* deserialize(string data){
        istringstream ss(data);//分割字符串
      return buildTree(ss);
    }
    TreeNode*buildTree(istringstream&ss){
        string str;
        ss>>str;//读入字符串
        if(str=="#"){
         return NULL;
        }
        TreeNode*root=new TreeNode(stoi(str));//构建根节点
        root->left=buildTree(ss);//再构建左子树
        root->right=buildTree(ss);//构建右子树
        return root;//返回根节点
    }

};

// Your Codec object will be instantiated and called as such:
// Codec ser, deser;
// TreeNode* ans = deser.deserialize(ser.serialize(root));

Problem solving ideas:

We can first convert the string into the form of the above question and then restore it according to the method of the above question.

Corresponding 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){
            return "#";
        }
    return to_string(root->val)+" "+serialize(root->left)+" "+serialize(root->right);//转换字符串
    }

    // Decodes your encoded data to tree.
    TreeNode* deserialize(string data){
        istringstream ss(data);//分割字符串
      return buildTree(ss);
    }
    TreeNode*buildTree(istringstream&ss){
        string str;
        ss>>str;//读入字符串
        if(str=="#"){
         return NULL;
        }
        TreeNode*root=new TreeNode(stoi(str));//构建根节点
        root->left=buildTree(ss);//再构建左子树
        root->right=buildTree(ss);//构建右子树
        return root;//返回根节点
    }

};

// Your Codec object will be instantiated and called as such:
// Codec ser, deser;
// TreeNode* ans = deser.deserialize(ser.serialize(root));

Method Two:

Layer-order traversal: first serialize it into a string according to the method of layer-order traversal. When deserializing: first determine whether the string is # if it is, return empty, and create a head node first after it is not empty

And put it into the queue. Build its left and right children, if the left child is not empty, add it to the queue, if the right child is not empty, add it to the queue, repeat the above process and finally add it The root node can be returned.

Corresponding 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) {
         string ans;
        if(root==NULL){
          return "#";
        }
    
        queue<TreeNode*>q;
        ans+=to_string(root->val);
        ans+=" ";//以空格作为分隔
        q.push(root);//将节点放入队列中
        while(!q.empty()){
           TreeNode*node=q.front();//取出头部数据
           q.pop();
           if(node->left){//左不为空
               q.push(node->left);//入站
               ans+=to_string(node->left->val);//将左孩子的值加入到字符串中
               ans+=" ";//以空格分隔
           }

           else{//空用#代表
               ans+="#";
               ans+=" ";
           }

           if(node->right){//右树不为空同理
               q.push(node->right);
               ans+=to_string(node->right->val);
               ans+=" ";
           }

           else{
               ans+="#";
               ans+=" ";
           }

        }

          return ans;//将字符串返回

    }

    // Decodes your encoded data to tree.
    TreeNode* deserialize(string data) {
        if(data=="#")return NULL;//如果确定是空树直接返回
    
        istringstream ss(data);//将字符串以空格分割
        vector<string>ans;
        string tmp;
        while(ss>>tmp){//将字符串放入容器中
            ans.push_back(tmp);
        }
        int i=0;
        TreeNode*root=new TreeNode(stoi(ans[i++]));//构建头节点
        queue<TreeNode*>q;
        q.push(root);//放入队列中
        while(!q.empty()){
            auto node=q.front();//取出头节点
            q.pop();
              if(ans[i]!="#")//如果不为空
             node->left=new TreeNode(stoi(ans[i]));//构建左子树
             else
             node->left=NULL;//否则就指向空
             i++;//i往后面走
            if(ans[i]!="#")//构建右子树
            node->right=new TreeNode(stoi(ans[i]));
            else
            node->right=NULL;
              i++;
            if(node->left){//不为空则继续放入队列中
                q.push(node->left);
            }
            if(node->right){
                q.push(node->right);
            }

        }
        return root;
    }
};

// Your Codec object will be instantiated and called as such:
// Codec ser, deser;
// TreeNode* ans = deser.deserialize(ser.serialize(root));

Convert between binary tree and N-ary tree

431. Encode N-ary tree into binary tree - LeetCode (leetcode-cn.com)

Problem solving ideas:

Put all the child nodes of the n-ary tree on the right boundary of the left tree. When converting back, first build the current node and recursively build its child nodes. For details, see the code:

TreeNode* encode(Node* root) {
    if (root == NULL)
        return NULL;
    TreeNode* head = new TreeNode(root->val);
    head->left = en(root->children);
    return head;
}
TreeNode* en(vector<Node*>child) {
    TreeNode* head = nullptr;
    TreeNode* cur = nullptr;
    for (auto x : child) {
        TreeNode* tNode = new TreeNode(x->val);
        if (head == nullptr)
            head = tNode;
        else
            cur->right = tNode;
        
        cur = tNode;
        cur->left = en(x->children);//将左树右边界的头返回
    }
    return head;
}

Node* decode(TreeNode* root) {
    if (root == nullptr)
        return nullptr;
    return new Node(root->val, de(root->left));
}
vector<Node*>de(TreeNode* root) {
    vector<Node*>child;
    while (root) {
        Node* cur = new Node(root->val, de(root->left));//构建其孩子节点
        child.push_back(cur);
        root = root->right;
    }
    return child;
}

Guess you like

Origin blog.csdn.net/qq_56999918/article/details/123468355