LeetCode297. Serialize and Deserialize Binary Tree

本文探讨如何实现二叉树的序列化和反序列化,包括不同的方法,如深度优先搜索(DFS)、广度优先搜索(BFS)以及使用stringstream等。在序列化过程中,空节点可以用'#'表示,节点间用空格分隔。在反序列化时,要确保与序列化方法对应,以确保结果唯一。此外,文章还讨论了C++的IO库,如atoi、stoi等字符串转换函数,以及如何将string转换为char*。
摘要由CSDN通过智能技术生成

题目 

序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据。

请设计一个算法来实现二叉树的序列化与反序列化。这里不限定你的序列 / 反序列化算法执行逻辑,你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序列化为原始的树结构。

示例: 

你可以将以下二叉树:

    1
   / \
  2   3
     / \
    4   5

序列化为 "[1,2,3,null,null,4,5]"

提示: 这与 LeetCode 目前使用的方式一致,详情请参阅 LeetCode 序列化二叉树的格式。你并非必须采取这种方式,你也可以采用其他的方法解决这个问题。

说明: 不要使用类的成员 / 全局 / 静态变量来存储状态,你的序列化和反序列化算法应该是无状态的。


Tag

IO库,stringstream的读取。

两个方法:stringstream in(str) :string往流里存。in.str() 从流返回string。 dfs。string -> int :stoi(val)。 


法1.

1.序列化:dfs前中后、bfs层次。反序列化要和序列化方法对应,结果唯一。

2.空节点:‘#’ 

3.每个节点结束标志:‘ ’,作用是防止歧义

4.用std的string流来对string进行分割,in>>val;每次遇到空格就停止,流的状态改变。

//dfs:preOrder
class Codec {
public:

    // Encodes a tree to a single string.
    string serialize(TreeNode* root) {
         ostringstream out;
         serialize(root,out);
         return out.str();
    }

    // Decodes your encoded data to tree.
    TreeNode* deserialize(string data) 
    {
        istringstream in(data);
        return deserialize(in);
    }

private:
    //  root - left - right 
    void serialize(TreeNode *root,ostringstream &out)
    {
        if(root)
        {
            out<<root->val<<' ';//‘ ’为结束符
            serialize(root->left,out);
            serialize(root->right,out);
        }
        else
        {
            out<<"# ";//#代表空节点,后面还有一个结束符' '
        }        
    }


    TreeNode* deserialize(istringstream &in)
    {
        string val;
        in >> val; //一个单词作为独立元素。用string流把string分割了
        if(val=="#") 
            return nullptr;
        TreeNode* root=new TreeNode(stoi(val));
        root->left=deserialize(in);
        root->right=deserialize(in);
        return root;
    }
};  

法2.BFS.队列。根节点入queue。检查根不为空。将根的左右节点入queue。

//BFS
class Codec {
public:

    // Encodes a tree to a single string.
    string serialize(TreeNode* root) {
        
        if(!root)
        return "";

        queue<TreeNode*> q;
        q.push(root);
        stringstream out;//string 流,初始化接受string定义,int输入用<<
 
        while(!q.empty())
        {
            TreeNode* t = q.front();
            q.pop();
            if(t)//bfs如果根节点存在,把左右孩子依次压入队列
            {
                out<< t->val <<" ";
                q.push(t->left);
                q.push(t->right);
            }
            else
            {
                out<<"# ";
            }
        }
        cout<<out.str();
        return out.str();
    }

    // Decodes your encoded data to tree.
    TreeNode* deserialize(string data) {
        if(data=="")
        return nullptr;
        queue<TreeNode*> myque;
        stringstream in(data);
        string val;
        in>>val;
        //第一个单词一定存在,压入队列,且是根节点
        TreeNode* root=new TreeNode(stoi(val));
        TreeNode* cur=root;
        myque.push(root);

        while(!myque.empty()) 
        {
            cur=myque.front();myque.pop(); 
            in>>val;
            if(val!="#")
            {
                cur->left=new TreeNode(stoi(val));
                myque.push(cur->left);
            }

            in>>val;
            if(val!="#")
            {
                cur->right=new TreeNode(stoi(val));
                myque.push(cur->right);
            } 
            
        } 
        return root;
    }
}; 

法3 返回char* 的做法。 strdup(out.str().c_str()); 将string 转为char *. 反之可以直接转换。

//bfs
#include <string.h>
class Solution {
public:
    char* Serialize(TreeNode *root) {
        if(!root)
            return nullptr;
        stringstream out;
        queue<TreeNode*> myque;
        myque.push(root);
         
        while(!myque.empty())
        {
            root=myque.front();myque.pop();
            if(root)
            {
                out<<root->val<<" ";
                myque.push(root->left);
                myque.push(root->right);
            }
            else
            {
                out<<"# ";
            }
        }        
        return  strdup(out.str().c_str());
    }
     
    TreeNode* Deserialize(char *str) {
        if(!str)
            return nullptr;
        string s=str;
        stringstream in(s);
        queue<TreeNode*> myque;
        string val;
        in>>val;
        TreeNode* ret = new TreeNode(stoi(val));
        TreeNode* root =ret;
        myque.push(root);       
        while(!myque.empty())
        {
            root= myque.front();
            myque.pop();           
            in>>val;
            if(val!="#")
            {
                root->left = new TreeNode(stoi(val));
                myque.push(root->left);
            }
            in>>val;
            if(val!="#")
            {
                root->right = new TreeNode(stoi(val));
                myque.push(root->right);
            }           
        }       
        return ret;   
    }
};

问题

1.atoi/stoi/strtoi/stoui区别

 2.C++ IO库

 

 

 

3.string 转 char*

头文件:#include <string.h>

定义函数:char * strdup(const char *s);

函数说明:strdup()会先用maolloc()配置与参数s 字符串相同的空间大小,然后将参数s 字符串的内容复制到该内存地址,然后把该地址返回。该地址最后可以利用free()来释放。

返回值:返回一字符串指针,该指针指向复制后的新字符串地址。若返回NULL 表示内存不足。

#include <string.h>
main(){
    char a[] = "strdup";
    char *b;
    b = strdup(a);
    printf("b[]=\"%s\"\n", b);
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值