力扣 297. 二叉树的序列化与反序列化

【题目】
传送门
【思路】
序列化:

二叉树的序列化本质上是对其值进行编码,更重要的是对其结构进行编码。可以遍历树来完成上述任务。
我们可以先序遍历这颗二叉树,遇到空子树的时候序列化成 None,否则继续递归序列化。

反序列化:

首先我们需要根据 , 把原先的序列分割开来得到先序遍历的元素列表,然后从左向右遍历这个序列:

如果当前的元素为 None,则当前为空树
否则先解析这棵树的左子树,再解析它的右子树

https://leetcode-cn.com/problems/serialize-and-deserialize-binary-tree/solution/er-cha-shu-de-xu-lie-hua-yu-fan-xu-lie-hua-by-le-2/

【BFS非递归解法】

class Codec {
public:

    // Encodes a tree to a single string.
    string serialize(TreeNode* root) {               
        string res;
        queue<TreeNode*> que;
        que.push(root);//根入队列
        while(!que.empty()){           
            int siz=que.size();   //记录当前层的节点数     
            while(siz--){
                TreeNode* cur=que.front();//出队列
                que.pop();
                if(cur==nullptr){//为空则标记null
                    res+="nullptr,";
                }else{
                    string str_val=to_string(cur->val)+",";
                    res+=str_val;        //不为空则将其转化为字符串插入res中,左右节点入队列            
                    que.push(cur->left);
                    que.push(cur->right);            
                }                                
            }            
        }
        return res;
    }

    // Decodes your encoded data to tree.
    TreeNode* deserialize(string data) {
        stringstream s(data);
        string str_node;
        queue<TreeNode*> que;
        getline(s,str_node,',');//获得根节点
        TreeNode* root;
        if(str_node=="nullptr"){
            return nullptr;
        }else{
            int inte_node=stoi(str_node);
            root=new TreeNode(inte_node);//创建根节点,节点入队列
            que.push(root);
        }
        while(!que.empty()){
            int siz=que.size();//获得当前层的节点个数
            while(siz--){
                TreeNode* cur=que.front();
                que.pop();                           
                if(cur!=nullptr){//当前节点的左孩子存在,不为空,则创建一个树节点
                    string str_left,str_right;                                       
                    if(getline(s,str_left,',') && str_left!="nullptr"){
                        TreeNode* l=new TreeNode(stoi(str_left));
                        que.push(l);//入队列
                        cur->left=l;
                    }                    
                    if(getline(s,str_right,',') && str_right!="nullptr"){   
                        TreeNode* r=new TreeNode(stoi(str_right));
                        que.push(r);
                        cur->right=r;
                    }                      
                }
            }            
        }
        return root;
    }
};

【递归解法】

class Codec {
public:

    // Encodes a tree to a single string.
    string serialize(TreeNode* root) {
        string res;
        dfs_s(root, res);
        return res;
    }

    // 前序遍历序列转化为字符串
    void dfs_s(TreeNode* root, string& res) {
        if (!root) {
            res += "null ";
            return;
        }
        res += to_string(root->val) + ' ';
        dfs_s(root->left, res);
        dfs_s(root->right, res);
    }



// Decodes your encoded data to tree.
    TreeNode* deserialize(string data) {
        // 开始遍历索引
        int u = 0;
        return dfs_d(data, u);
    }

    TreeNode* dfs_d(string& data, int& u) {
        if (u >= data.size()) return NULL;//索引大于字符串长度则退出
        if (data[u] == 'n') {//当前为null
            u = u + 5;
            return NULL;
        }
        int val = 0, sign = 1;
        if (data[u] == '-') sign = -1, u ++ ;//标记负数的符号位
        while(data[u] != ' '){
        val = val * 10 + data[u] - '0'; u++;}
        val *= sign;
        u = u + 1 ;

        auto root = new TreeNode(val);//创建节点
        root->left = dfs_d(data, u);
        root->right = dfs_d(data, u);
        return root;
    }
};


// Your Codec object will be instantiated and called as such:
// Codec codec;
// codec.deserialize(codec.serialize(root));


链接:https://leetcode-cn.com/problems/serialize-and-deserialize-binary-tree/solution/jian-dan-yi-dong-c-by-forgetthing/

你可能感兴趣的:(LeetCode,二叉树,leetcode,队列,数据结构)