Sérialisation d'arbres binaires et désérialisation de structures de données (y compris implémentation de code)

contenu

1. Reconstruire l'arbre binaire 

2. Sérialisation et désérialisation de l'arbre binaire


1. Reconstruire l'arbre binaire 

Parcours d'arbre binaire

Description du sujet:

 Idées de résolution de problèmes :

1. Puisque le nœud vide de la séquence de parcours de préordre a été représenté par '#', nous pouvons restaurer récursivement l'arbre binaire. Si '#' est rencontré, renvoyez nullptr, sinon, créez un nouveau nœud principal, puis construisez récursivement son le sous-arbre gauche et le sous-arbre droit, une fois la construction terminée, renvoient le nœud principal.

Prenez la séquence abc##d### comme exemple (désolé, le dernier # ne peut pas être écrit)

1. Allez d'abord au nœud principal et constatez qu'il n'est pas vide pour créer un nœud :

Créez ensuite récursivement son sous-arbre gauche, puis créez récursivement son sous-arbre droit. Venir à b n'est pas #créer un nœud b. (j'en ai écrit un de moins #désolé)

 

Allez au nœud suivant et constatez qu'il n'est pas vide pour créer le nœud c :

Quand je suis arrivé au nœud suivant, j'ai trouvé qu'il était # similaire trouvé que le nœud suivant était également # Retour à vide, puis c est créé et renvoyé à la chaîne b, et dans l'image, je l'ai lié à l'avance pour le souci d'apparence:

 Passez ensuite au nœud suivant pour trouver une création vide qui n'est pas :

Créez ensuite un espace vide (car je ne pouvais pas écrire de # avant), il en va de même pour les éléments suivants :

 

 Code correspondant :

#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. Sérialisation et désérialisation de l'arbre binaire

297. Sérialisation et désérialisation de l'arbre binaire - LeetCode (leetcode-cn.com)

Description du sujet:

/**
 * 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));

Idées de résolution de problèmes :

Nous pouvons d'abord convertir la chaîne sous la forme de la question ci-dessus, puis la restaurer selon la méthode de la question ci-dessus.

Code correspondant :

/**
 * 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));

Deuxième méthode :

Traversée de l'ordre des couches : sérialisez-la d'abord dans une chaîne selon la méthode de traversée de l'ordre des couches. Lors de la désérialisation : déterminez d'abord si la chaîne est # si elle l'est, retournez vide et créez d'abord un nœud principal après qu'il ne soit pas vide

Et mettez-le dans la file d'attente. Construisez ses enfants gauche et droit, si l'enfant de gauche n'est pas vide, ajoutez-le à la file d'attente, si l'enfant de droite n'est pas vide, ajoutez-le à la file d'attente, répétez le processus ci-dessus et ajoutez-le enfin Le nœud racine peut être retourné.

Code correspondant :

/**
 * 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));

Convertir entre arbre binaire et arbre N-aire

431. Encoder l'arbre N-aire en arbre binaire - LeetCode (leetcode-cn.com)

Idées de résolution de problèmes :

Placez tous les nœuds enfants de l'arbre n-aire sur la limite droite de l'arbre de gauche. Lors de la reconversion, construisez d'abord le nœud actuel et construisez de manière récursive ses nœuds enfants. Pour plus de détails, consultez le 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;
}

Je suppose que tu aimes

Origine blog.csdn.net/qq_56999918/article/details/123468355
conseillé
Classement