zoukankan      html  css  js  c++  java
  • [LeetCode] 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.

    Example: 

    You may serialize the following tree:
    
        1
       / 
      2   3
         / 
        4   5
    
    as "[1,2,3,null,null,4,5]"
    

    Clarification: The above format is the same as how LeetCode 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.

    序列化是是指将数据结构或物件状态转换成可取用格式(例如存成档案,存于缓冲,或经由网络中传送),以留待后续在相同或另一台计算机环境中,能恢复原先状态的过程,还原的过程叫做反序列化。比如例子中的把树序列化成数组,还可以由这个数组在反序列化变回树。

    根据题目序列化的形式,可以先序遍历的递归或者层序遍历的非递归:

    需要接入输入和输出字符串流istringstream和ostringstream,对于序列化,从根节点开始,如果节点存在,则将值存入输出字符串流,然后分别对其左右子节点递归调用序列化函数即可。对于反序列化,先读入第一个字符生成一个根节点,然后再对根节点的左右子节点递归调用去序列化函数即可。

    Java:level order traversal

    // Encodes a tree to a single string.
    public String serialize(TreeNode root) {
        if(root==null){
            return "";
        }
     
        StringBuilder sb = new StringBuilder();
     
        LinkedList<TreeNode> queue = new LinkedList<TreeNode>();
     
        queue.add(root);
        while(!queue.isEmpty()){
            TreeNode t = queue.poll();
            if(t!=null){
                sb.append(String.valueOf(t.val) + ",");
                queue.add(t.left);
                queue.add(t.right);
            }else{
                sb.append("#,");
            }
        }
     
        sb.deleteCharAt(sb.length()-1);
        System.out.println(sb.toString());
        return sb.toString();
    }
     
    // Decodes your encoded data to tree.
    public TreeNode deserialize(String data) {
        if(data==null || data.length()==0)
            return null;
     
        String[] arr = data.split(",");
        TreeNode root = new TreeNode(Integer.parseInt(arr[0]));
     
     
        LinkedList<TreeNode> queue = new LinkedList<TreeNode>();
        queue.add(root);
     
        int i=1;
        while(!queue.isEmpty()){
            TreeNode t = queue.poll();
     
            if(t==null)
                continue;
     
            if(!arr[i].equals("#")){
                t.left = new TreeNode(Integer.parseInt(arr[i]));    
                queue.offer(t.left);
     
            }else{
                t.left = null;
                queue.offer(null);
            }
            i++;
     
            if(!arr[i].equals("#")){
                t.right = new TreeNode(Integer.parseInt(arr[i]));    
                queue.offer(t.right);
     
            }else{
                t.right = null;
                queue.offer(null);
            }
            i++;
        }
     
        return root;
    }
    

    Java: Preorder traversal

    // Encodes a tree to a single string.
    public String serialize(TreeNode root) {
        if(root==null)
            return null;
     
        Stack<TreeNode> stack = new Stack<TreeNode>();
        stack.push(root);
        StringBuilder sb = new StringBuilder();
     
        while(!stack.isEmpty()){
            TreeNode h = stack.pop();   
            if(h!=null){
                sb.append(h.val+",");
                stack.push(h.right);
                stack.push(h.left);  
            }else{
                sb.append("#,");
            }
        }
     
        return sb.toString().substring(0, sb.length()-1);
    }
     
    // Decodes your encoded data to tree.
    public TreeNode deserialize(String data) {
        if(data == null)
            return null;
     
        int[] t = {0};
        String[] arr = data.split(",");
     
        return helper(arr, t);
    }
     
    public TreeNode helper(String[] arr, int[] t){
        if(arr[t[0]].equals("#")){
            return null;
        }
     
        TreeNode root = new TreeNode(Integer.parseInt(arr[t[0]]));
     
        t[0]=t[0]+1;
        root.left = helper(arr, t);
        t[0]=t[0]+1;
        root.right = helper(arr, t);
     
        return root;
    }
    

    Java:

    public class Codec {
        private static final String spliter = ",";
        private static final String NN = "X";
    
        // Encodes a tree to a single string.
        public String serialize(TreeNode root) {
            StringBuilder sb = new StringBuilder();
            buildString(root, sb);
            return sb.toString();
        }
    
        private void buildString(TreeNode node, StringBuilder sb) {
            if (node == null) {
                sb.append(NN).append(spliter);
            } else {
                sb.append(node.val).append(spliter);
                buildString(node.left, sb);
                buildString(node.right,sb);
            }
        }
        // Decodes your encoded data to tree.
        public TreeNode deserialize(String data) {
            Deque<String> nodes = new LinkedList<>();
            nodes.addAll(Arrays.asList(data.split(spliter)));
            return buildTree(nodes);
        }
        
        private TreeNode buildTree(Deque<String> nodes) {
            String val = nodes.remove();
            if (val.equals(NN)) return null;
            else {
                TreeNode node = new TreeNode(Integer.valueOf(val));
                node.left = buildTree(nodes);
                node.right = buildTree(nodes);
                return node;
            }
        }
    }  

    Python:

    class Codec:
    
        def serialize(self, root):
            def serializeHelper(node):
                if not node:
                    vals.append('#')
                else:
                    vals.append(str(node.val))
                    serializeHelper(node.left)
                    serializeHelper(node.right)
            vals = []
            serializeHelper(root)
            return ' '.join(vals)
    
    
        def deserialize(self, data):
            def deserializeHelper():
                val = next(vals)
                if val == '#':
                    return None
                else:
                    node = TreeNode(int(val))
                    node.left = deserializeHelper()
                    node.right = deserializeHelper()
                    return node
            def isplit(source, sep):
                sepsize = len(sep)
                start = 0
                while True:
                    idx = source.find(sep, start)
                    if idx == -1:
                        yield source[start:]
                        return
                    yield source[start:idx]
                    start = idx + sepsize
            vals = iter(isplit(data, ' '))
            return deserializeHelper()
    

     Python:

    class Codec:
    
        def serialize(self, root):
            def doit(node):
                if node:
                    vals.append(str(node.val))
                    doit(node.left)
                    doit(node.right)
                else:
                    vals.append('#')
            vals = []
            doit(root)
            return ' '.join(vals)
    
        def deserialize(self, data):
            def doit():
                val = next(vals)
                if val == '#':
                    return None
                node = TreeNode(int(val))
                node.left = doit()
                node.right = doit()
                return node
            vals = iter(data.split())
            return doit()  

    C++:

    class Codec {
    public:
        string serialize(TreeNode* root) {
            ostringstream out;
            serialize(root, out);
            return out.str();
        }
     
        TreeNode* deserialize(string data) {
            istringstream in(data);
            return deserialize(in);
        }
    private:
        void serialize(TreeNode* root, ostringstream& out) {
            if (!root) {
                out << "# ";
                return;
            }        
            out << root->val << " ";
            serialize(root->left, out);
            serialize(root->right, out);
        }
        
        TreeNode* deserialize(istringstream& in) {
            string val;
            in >> val;
            if (val == "#") return nullptr;        
            TreeNode* root = new TreeNode(stoi(val));        
            root->left = deserialize(in);
            root->right = deserialize(in);        
            return root;
        }
    };
    

    C++:

    class Codec {
    public:
     
        string serialize(TreeNode* root) {
            ostringstream out;
            serialize(root, out);
            return out.str();
        }
     
        TreeNode* deserialize(string data) {
            istringstream in(data);
            return deserialize(in);
        }
    private:
        enum STATUS {
            ROOT_NULL = 0x0,
            ROOT = 0x1,
            LEFT = 0x2,
            RIGHT = 0x4
        };
        
        void serialize(TreeNode* root, ostringstream& out) {
            char status = 0;
            if (root) status |= ROOT;
            if (root && root->left) status |= LEFT;
            if (root && root->right) status |= RIGHT;
            out.write(&status, sizeof(char));        
            if (!root) return;
            out.write(reinterpret_cast<char*>(&(root->val)), sizeof(root->val));
            if (root->left) serialize(root->left, out);
            if (root->right) serialize(root->right, out);
        }
        
        TreeNode* deserialize(istringstream& in) {
            char status;
            in.read(&status, sizeof(char));
            if (!status & ROOT) return nullptr;
            auto root = new TreeNode(0);
            in.read(reinterpret_cast<char*>(&root->val), sizeof(root->val));        
            root->left = (status & LEFT) ? deserialize(in) : nullptr;
            root->right = (status & RIGHT) ? deserialize(in) : nullptr;
            return root;
        }
    };
    

     

    Followup: 如果是 n-ary怎么办?

       

    All LeetCode Questions List 题目汇总

      

  • 相关阅读:
    C++学习总结 复习篇2
    C++ 学习总结 复习篇
    Git 安装与使用
    前两周工作总结
    [bzoj1033] [ZJOI2008]杀蚂蚁antbuster
    [bzoj1031] [JSOI2007]字符加密Cipher
    [bzoj1030] [JSOI2007]文本生成器
    [bzoj1029] [JSOI2007]建筑抢修
    [bzoj1028] [JSOI2007]麻将
    [bzoj1026] [SCOI2009]windy数
  • 原文地址:https://www.cnblogs.com/lightwindy/p/8508671.html
Copyright © 2011-2022 走看看