LeetCode No.297 Serialize and Deserialize Binary Tree

Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in the same or another computer environment.

Design an algorithm to serialize and deserialize a binary tree. There is no restriction on how your serialization/deserialization algorithm should work. You just need to ensure that a binary tree can be serialized to a string and this string can be deserialized to the original tree structure.

For example, you may serialize the following tree

    1
   / \
  2   3
     / \
    4   5
as  "[1,2,3,null,null,4,5]" , just the same as  how LeetCode OJ serializes a binary tree . You do not necessarily need to follow this format, so please be creative and come up with different approaches yourself.

Note: Do not use class member/global/static variables to store states. Your serialize and deserialize algorithms should be stateless.

====================================================================================
题目链接:https://leetcode.com/problems/serialize-and-deserialize-binary-tree/

题目大意:编写一个类,对一个二叉树进行序列化和反序列化,两个函数都只能使用其参数来构建。(序列化的意思就是:使用字符串储存二叉树,反序列化的意思是:使用你存储的字符串来构建原来的二叉树)

思路:序列化的做法有很多种,但是序列化和反序列化要选择一样的构建格式,就跟编码和译码的意思一样。

一般的做法有两种:

1、前序遍历

2、中序遍历

3、层次遍历

一般不会选择后续遍历,因为后序遍历的步骤比较复杂。

我这里选了我感觉最简单的那一种:层次遍历。

具体做法如下:

序列化:

1、用queue实现层次遍历

2、访问当前节点不为空时将该节点的值转成string放入结果中,用逗号‘,’隔开

3、如果当前节点左(右)子树不存在,则用‘n’表示,如果存在,则将该节点左(右)子树push进队列

反序列化:

1、同样用queue实现层次遍历

2、我们已知string中的数值是用逗号‘,’隔开的,而且‘n’表示空,因为每个节点有两个孩子(左右子树),所以我们每次从队列中取出一个节点都要计算它的左右子树。对每一次取值,首先判断当前字符是否为n,如果是n则下一节点(左或右子树)值为空,否则生成下一节点并push进队列

参考代码:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Codec {
public:

    // Encodes a tree to a single string.
    string serialize(TreeNode* root) {
        string ans = "" ;
        if ( root == NULL )
            return ans ;
        ans += intToStr ( root -> val ) ;
        queue <TreeNode*> q ;
        q.push ( root ) ;
        while ( !q.empty() )
        {
            TreeNode* temp = q.front() ;
            q.pop() ;            
            if ( temp -> left )
            {
            	q.push ( temp -> left ) ;
            	ans += "," ;
            	ans += intToStr ( temp -> left -> val ) ;
			}
            else
            {
            	ans += ",n" ;
            }
                
            if ( temp -> right )
            {
            	q.push ( temp -> right ) ;
            	ans += "," ;
            	ans += intToStr ( temp -> right -> val ) ;
			}
            else
            {
            	ans += ",n" ;
            }
                
        }
        return ans ;
    }

    // Decodes your encoded data to tree.
    TreeNode* deserialize(string data) {
        int n = data.size() ;
        if ( n == 0 )
            return NULL ;
        TreeNode* root = new TreeNode ( strToInt ( data ) ) ;
        queue <TreeNode*> q ;
        q.push ( root ) ;
        while ( data.size() )
        {
            TreeNode* temp = q.front() ;
            q.pop() ;
            if ( data[0] == 'n' )
            {
                temp -> left = NULL ;
                data.erase ( 0 , 1 ) ;
                if ( data.size() && data[0] == ',' )
                    data.erase ( 0 , 1 ) ;
            }
            else
            {
                temp -> left = new TreeNode ( strToInt ( data ) ) ;
                q.push( temp -> left ) ; 
            }
            if ( data.size() == 0 )
                break ;
            if ( data[0] == 'n' )
            {
                temp -> right = NULL ;
                data.erase ( 0 , 1 ) ;
                if ( data.size() && data[0] == ',' )
                    data.erase ( 0 , 1 ) ;
            }
            else
            {
                temp -> right = new TreeNode ( strToInt ( data ) ) ;
                q.push( temp -> right ) ; 
            }
        }
        return root ;
    }
private :
    string intToStr ( int n )  
    { 
        if ( n == 0 )  
            return "0" ;  
        if ( n < 0 )  
            return "-" + intToStr ( -n ) ;  
        string ans = "" ;  
        while ( n )  
        {  
            ans = char ( n % 10 + '0' ) + ans ;  
            n /= 10 ;  
        }
        return ans ;
    }
    
    int strToInt ( string& s )
    {
        int n = s.size() , ans = 0 ;
        if ( n == 0 )
            return 0 ;
        if ( s[0] == '-' )
        {
            s.erase ( 0 , 1 ) ;
            return - strToInt ( s ) ;
        }
        for ( int i = 0 ; i < n ; i ++ )
        {
            if ( s[i] == ',' )
            {
                s.erase ( 0 , i + 1 ) ;
                return ans ;
            }
            else
                ans = ans * 10 + s[i] - '0' ;
        }
        s = "" ;
        return ans ;
    }
};

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


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值