序列化二叉树(多种方式实现)

请实现两个函数,分别用来序列化和反序列化二叉树。

您需要确保二叉树可以序列化为字符串,并且可以将此字符串反序列化为原始树结构。

样例

你可以序列化如下的二叉树
    8
   / \
  12  2
     / \
    6   4

为:"[8, 12, 2, null, null, 6, 4, null, null, null, null]"

注意:

  • 以上的格式是AcWing序列化二叉树的方式,你不必一定按照此格式,所以可以设计出一些新的构造方式。

层序遍历建树:

class Solution {
public:
    string serialize(TreeNode* root) {
        if(!root) return "";
        queue<TreeNode*> q;
        q.push(root);
        string res = "";
        while(q.size()){
            auto t = q.front();
            q.pop();
            if(t) {
                res += to_string(t->val) + " ";
                q.push(t->left);
                q.push(t->right);
            }
            else res += ". ";
        }
        return res;
    }

    // Decodes your encoded data to tree.
    TreeNode* deserialize(string data) {
        int u = 0;
        TreeNode* root = get_node(data,u);
        queue<TreeNode*> q;
        if(root) q.push(root);
        while(q.size()){
            auto t = q.front();
            q.pop();
            t->left = get_node(data,u);
            t->right = get_node(data,u);
            if(t->left) q.push(t->left);
            if(t->right) q.push(t->right);
        }
        return root;
    }
    
    TreeNode* get_node(string num,int &u){
        int f = 1,res = 0;
        int k = u;
        while(k < num.size() && num[k] != ' ') k++;
        if(u == num.size() || num[u] == '.'){
            u = k + 1;
            return NULL;
        }
        if(u < k && num[u] == '-') {
            f = -1;
            u++;
        }
        for(int i = u; i < k; i++)
            res = res * 10 + num[i] - '0';
        u = k + 1;
        return new TreeNode(f*res);
    }
};

前序遍历建树:

class Solution {
public:
    string serialize(TreeNode* root) {
        string res;
        dfs_s(root,res);
        return res;
    }

    // Decodes your encoded data to tree.
    TreeNode* deserialize(string data) {
        int u = 0;
        return build(data,u);
    }
    
    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);
    }
    
    TreeNode* build(string data,int &u){
        if (u == data.size()) return NULL;
        int k = u;
        while (data[k] != ' ') k ++ ;
        if (data[u] == 'n') {
            u = k + 1;
            return NULL;
        }
        int val = 0, sign = 1;
        if (u < k && data[u] == '-') sign = -1, u ++ ;
        for (int i = u; i < k; i ++ ) val = val * 10 + data[i] - '0';
        val *= sign;
        u = k + 1;
        auto root = new TreeNode(val);
        root->left = build(data, u);
        root->right = build(data, u);
        return root;
    }
};

后序遍历建树,跟前序反着来就行了

class Solution {
public:
    string serialize(TreeNode* root) {
        string res;
        dfs_s(root,res);
        return res;
    }

    // Decodes your encoded data to tree.
    TreeNode* deserialize(string data) {
        int u = data.size() - 1;
        return build(data,u);
    }
    
    void dfs_s(TreeNode* root,string &res){
        if(!root){
            res += " null";
            return;
        }
        dfs_s(root->left,res);
        dfs_s(root->right,res);
        res += " " + to_string(root->val);
    }
    
    TreeNode* build(string data,int &u){
        if (u < 0) return NULL;
        int k = u;
        while (data[k] != ' ') k -- ;
        if (data[u] == 'l') {
            u = k - 1;
            return NULL;
        }
        int val = 0, sign = 1;
        if (u > k && data[k+1] == '-') sign = -1;
        for (int i = k + 1 + (sign == -1); i <= u; i ++ ) val = val * 10 + data[i] - '0';
        val *= sign;
        u = k - 1;
        auto root = new TreeNode(val);
        root->right = build(data, u);
        root->left = build(data, u);
        return root;
    }
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值