牛客网-C++剑指offer-第六十题(序列化二叉树)

题目描述

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

 

二叉树的序列化是指:把一棵二叉树按照某种遍历方式的结果以某种格式保存为字符串,从而使得内存中建立起来的二叉树可以持久保存。序列化可以基于先序、中序、后序、层序的二叉树遍历方式来进行修改,序列化的结果是一个字符串,序列化时通过 某种符号表示空节点(#),以 ! 表示一个结点值的结束(value!)。

二叉树的反序列化是指:根据某种遍历顺序得到的序列化字符串结果str,重构二叉树。

 

解题思路:

根据前序遍历规则完成序列化与反序列化。所谓序列化指的是遍历二叉树为字符串;所谓反序列化指的是依据字符串重新构造成二叉树。依据前序遍历序列来序列化二叉树,因为前序遍历序列是从根结点开始的。当在遍历二叉树时碰到Null指针时,这些Null指针被序列化为一个特殊的字符“#”。另外,结点之间的数值用逗号隔开。

 

参考代码:

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <stack>
#include <queue>
#include <list>
#include <unordered_map>
#include <cstring>

using namespace std;


struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};

class Solution {
public:
    char* Serialize(TreeNode *root) {    
        //如果节点为空直接压入#,返回
        if(root == NULL)
        {
            //这边要注意一定要动态申请内存,否则当函数结束时,内存就释放了
            char* chs = new char[3];
            chs = "#,";
            return chs;
        }
        
        string strs;
        my_Serialize(root,strs);
        char* res = new char[strs.size()];
        strcpy(res, strs.c_str());
        
        return res;
    }
    TreeNode* Deserialize(char *str) {
        if(str == NULL)
            return NULL;
        
        string strs(str);
        return my_Deserialize(strs);
    }
    
    void my_Serialize(TreeNode* root, string& strs)
    {
        //这里使用前序遍历进行序列化
        if(root == NULL)
        {
            strs.push_back('#');
            strs.push_back(',');
            return;
        }
        //这里要使用to_string,如果直接root->val+‘0’会出错
        strs += to_string(root->val);
        strs.push_back(',');
        
        my_Serialize(root->left,strs);
        my_Serialize(root->right,strs);
    }
    
    TreeNode* my_Deserialize(string& strs)
    {
        if(strs.empty())
            return NULL;
        //遇到#,说明为空,把这个从字符串中去掉,然后返回即可
        if(strs[0] == '#')
        {
            strs = strs.substr(2);
            return NULL;
        }
        //这里要使用stoi进行字符串转换到数字,否则使用strs[0]-'0',可能就只转换了一位
        TreeNode* new_node = new TreeNode(stoi(strs));
        strs = strs.substr(strs.find(',')+1);//stoi转换后,字符串并未发生变化
        
        new_node->left = my_Deserialize(strs);
        new_node->right = my_Deserialize(strs);
        
        return new_node;
    }
};

void read(TreeNode* tnode)
{
    if (tnode == NULL)
        return;
    cout<<tnode->val<<" ";
    read(tnode->left);
    read(tnode->right);
}

int main() {

    Solution solution;

    TreeNode TreeNode1(1);
    TreeNode TreeNode2(2);
    TreeNode TreeNode3(3);
    TreeNode TreeNode4(4);
    TreeNode TreeNode5(5);
    TreeNode TreeNode6(6);
    TreeNode TreeNode7(7);

    TreeNode1.left = &TreeNode2;
    TreeNode1.right = &TreeNode3;

    TreeNode2.left = &TreeNode4;
    TreeNode2.right = &TreeNode5;

    TreeNode3.left = &TreeNode6;
    TreeNode3.right = &TreeNode7;

    TreeNode4.left = NULL;
    TreeNode4.right = NULL;

    TreeNode5.left = NULL;
    TreeNode5.right = NULL;

    TreeNode6.left = NULL;
    TreeNode6.right = NULL;

    TreeNode7.left = NULL;
    TreeNode7.right = NULL;

    TreeNode* my_head = &TreeNode1;
    TreeNode* my_res;
    char* my_ch;
    my_ch = solution.Serialize(my_head);
    solution.Deserialize(my_ch);
//    my_res = solution.Deserialize(solution.Serialize(my_head));

//    read(my_res);

    return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值