序列化二叉树

剑指OFFER题56------按牛客网通过率排序

时间:2019.1.13
作者:Waitt

题目

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

时间限制:1秒 空间限制:32768K 热度指数:126232

解答

序列化:把对象转换为字节序列;
反序列化:把字节序列恢复为原对象。

序列化的主要用途:

  1. 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中
  2. 在网络上传送对象的字节序列
思路1:

将该二叉树进行前序遍历、中序遍历进行序列化和反序列化。

用该方法反序列化时的缺点
若二叉树中有重复值的结点,则该方法不可使用,并且必须从数据流中读完所有的数据才可进行反序列化

思路2

单纯的利用前序遍历,从根节点开始,左子树前加‘L’,右子树前加’R’,空子树则加’N’,这样仅单纯的利用前序遍历即可完成序列化与反序列化。

注意:对于指针所指向的数据类型,从无到有时,必须先用new来申请空间。
在序列化时,由于题目返回类型为char*,所以先用string进行序列化,最后在转化为char*,这样可以仅再最后申请char的动态空间,而无需再序列化过程中实时申请。

strcat()与strcpy()需要有足够大的空间容量才可使用,否则会出现bug。
int转string:to_string(),详见:https://www.cnblogs.com/smile233/p/8379802.html
char*转int:atoi(),详见:https://blog.csdn.net/zmqblog/article/details/20069103

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};
*/
class Solution {
public:
    void xian(TreeNode *root,string &c)//前序遍历实现序列化
    {
        if(!root)//空结点判断
        {
            c=c+"N";//空结点再序列化中用'N'表示
            return ;
        }
        string a=to_string(root->val);//int转string
        c=c+a;
        c.push_back('L');//左子树前加'L'
        xian(root->left,c);
        c.append("R");//右子树前加'R'
        xian(root->right,c);
    }
    char* Serialize(TreeNode *root) {    
        if(!root)//特殊情况判断
            return NULL;
        string c;
        xian(root,c);//前序遍历
        char *a=new char[c.size()];//动态申请char类型数组,必须满足容量大小
        strcpy(a,c.c_str());//用strcpy()进行转化
        return a;
    }
    TreeNode* Deser(char *&str)//反序列化
    {
        if(!str||*str=='N')//空结点判断
        {
            str++;
            return NULL;
        }
        int t=atoi(str);//char*转换为int 
        TreeNode* ro=new TreeNode(t);//申请树结点
        while(str[0]!='L')//查找左子树所在处
            str++;
        str++;
        ro->left=Deser(str);
        while(*str!='R')//查找左子树所在处
            str++;
        str++;
        ro->right=Deser(str);
        return ro;
    }
    TreeNode* Deserialize(char *str) {
        return Deser(str);
    }
};

该实例的int转string、char *转int均使用内置函数实现,亦可自己些代码实现,要注意正负号。

string后接字符:使用’+'号,使用push_back(),使用append().

char *的当前字符:*str或str[0]

TIPS

C++ strcat():https://zhidao.baidu.com/question/129439773.html
extern char *strcat(char *dest,char *src);
功能:把src所指字符串添加到dest结尾处(覆盖dest结尾处的’\0’)并添加’\0’。
说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。返回指向dest的指针。

c++中 string转char*:建议先用new申请空间,再用strcpy。
详见:https://www.cnblogs.com/mdumpling/p/8179167.html

C++中string的用法https://www.cnblogs.com/X-Do-Better/p/8628492.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值