61.序列化二叉树

拥有回忆 提交于 2020-02-15 16:43:14

题目

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

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

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

思路

  • 思路一
    • 非递归用按层序列化和反序列化。代码贼长。
    • 序列化:用队列,结点进队列。每次一个结点处队列,将结点的左右孩子序列化,如果孩子不为空,将数字和!加入到字符串中,同时让孩子进队列。如果为空,把‘#’加入到字符串中。
    • 反序列化,也要用到一个队列。先构建根结点,如果字符串中当前字符为‘#’,则跟节点的孩子为空。反之构造新结点,同时将新创建的孩子结点放入队列中,在下一次循环开始时,出队列一个结点,继续确定并左右孩子,然后将非空结点放入队列中…
    • 循环直到队列为空。
  • 思路二
    • 用递归的方法,代码较短。
    • 使用前序遍历

代码一

/*
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 == nullptr ) return nullptr;
            
        string str = "";
        SerializeCore( root, str ); // 序列化为一个string变量。
        
        char* res = new char[str.size()+1];
        for ( int i = 0; i < str.size(); ++i ) {
            res[i] = str[i];
        }
        
        res[str.size()] = '\0';
        
        return res;
    }
    
    void SerializeCore( TreeNode* root, string& str ) {
        queue<TreeNode*> q;
        q.push( root );
        str += to_string( root->val ) + '!';
        
        while ( !q.empty() ) {
            TreeNode* node = q.front();
            q.pop();
            
            if ( !node->left ) { str += '#'; }
            else {
                str += to_string( node->left->val ) + '!';
                q.push( node->left );
            }
            
            if ( !node->right ) { str += '#'; }
            else {
                str += to_string( node->right->val ) + '!';
                q.push( node->right );
            }
        }
        
        return;
    }
    
    
    TreeNode* Deserialize(char *str) {
        if ( str == nullptr ) return nullptr;
        
        int rootNum = getNum( &str );
        TreeNode* root = new TreeNode( rootNum );
        queue<TreeNode*> q;
        q.push( root );
        
        while ( !q.empty() ) {
            TreeNode* node = q.front();
            q.pop();
            
            if ( *str == '#' ) { 
                node->left = nullptr; 
                ++str;
            }
            else {
                int nodeNum = getNum( &str );
                node->left = new TreeNode( nodeNum );
                q.push( node->left );
            }
            
            if ( *str == '#' ) { 
                node->right = nullptr; 
                ++str;
            }
            else {
                int nodeNum = getNum( &str );
                node->right = new TreeNode( nodeNum );
                q.push( node->right );
            }
        }
        
        return root;
    }
    
    int getNum( char** str ) {
        int res = 0;
        
        while ( **str != '!' ) {
            res = res * 10 + ( **str - '0' );
            ++(*str);
        }
        
        ++(*str);
        
        return res;
    }
};

代码二

// 前序遍历序列化和反序列化二叉树
/*
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 == nullptr ) return nullptr;
        
        string str = "";
        SerializeCore( root, str );
        
        char* res = new char[str.size()+1];
        
        for ( int i = 0; i < str.size(); ++i )
            res[i] = str[i];
        
        res[str.size()] == '\0';
        
        return res;

    }
    
    void SerializeCore( TreeNode* node, string& str ) {
        if ( node == nullptr ) {
            str += '#';
            
            return;
        }
            
        str += to_string( node->val ) + '!';
        
        SerializeCore( node->left, str );
        SerializeCore( node->right, str );
        
        return;
    }
    
    TreeNode* Deserialize(char *str) {
        if ( str == nullptr ) return nullptr;
        
        return DeserializeCore( &str );
    }
    
    TreeNode* DeserializeCore( char** str ) {
        if ( **str == '#' ) {
            ++(*str);
            
            return nullptr;
        }
        
        int nodeNum = 0;
        while ( **str != '!' ) {
            nodeNum = nodeNum * 10 + ( **str - '0' );
            ++(*str);
        }
        
        ++(*str);
        TreeNode* node = new TreeNode( nodeNum );
        
        node->left = DeserializeCore( str );
        node->right = DeserializeCore( str );
        
        return node;
    }
};
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!