• lintcode : 二叉树的序列化和反序列化


    题目

    二叉树的序列化和反序列化

    设计一个算法,并编写代码来序列化和反序列化二叉树。将树写入一个文件被称为“序列化”,读取文件后重建同样的二叉树被称为“反序列化”。

    如何反序列化或序列化二叉树是没有限制的,你只需要确保可以将二叉树序列化为一个字符串,并且可以将字符串反序列化为原来的树结构。

    样例

    给出一个测试数据样例, 二叉树{3,9,20,#,#,15,7},表示如下的树结构:

      3
     / 
    9  20
      /  
     15   7
    

    我们的数据是进行BFS遍历得到的。当你测试结果wrong answer时,你可以作为输入调试你的代码。

    你可以采用其他的方法进行序列化和反序列化。

    解题

    参考九章程序

    看看注释就理解了,但是我表示自己想不出来Java

    /**
     * Definition of TreeNode:
     * public class TreeNode {
     *     public int val;
     *     public TreeNode left, right;
     *     public TreeNode(int val) {
     *         this.val = val;
     *         this.left = this.right = null;
     *     }
     * }
     */
    class Solution {
        /**
         * This method will be invoked first, you should design your own algorithm 
         * to serialize a binary tree which denote by a root node to a string which
         * can be easily deserialized by your own "deserialize" method later.
         */
        public String serialize(TreeNode root) {
            // write your code here
            if( root == null)
                return "{}";
            ArrayList<TreeNode> queue = new ArrayList<TreeNode>();
            queue.add(root);
            // 将二叉树的个节点按照从上到下、从左到有的存储在queue中
            for(int i=0;i<queue.size();i++){
                TreeNode q = queue.get(i);
                if(q== null)
                    continue;
                queue.add(q.left);
                queue.add(q.right);
            }
            // 去除叶子节点的左右孩子,这个孩子是空值
            while(queue.get(queue.size() - 1) == null){
                queue.remove(queue.size() - 1);
            }
            // 遍历queue把转换成字符串
            StringBuilder sb = new StringBuilder();
            sb.append("{");
            sb.append(queue.get(0).val);
            for(int i=1;i<queue.size(); i++){
                TreeNode q = queue.get(i);
                if(q!= null){
                    sb.append(",");
                    sb.append(q.val);
                }else{
                    sb.append(",#");
                }
            }
            sb.append("}");
            return sb.toString();
        }
        
        /**
         * This method will be invoked second, the argument data is what exactly
         * you serialized at method "serialize", that means the data is not given by
         * system, it's given by your own serialize method. So the format of data is
         * designed by yourself, and deserialize it here as you serialize it in 
         * "serialize" method.
         */
        public TreeNode deserialize(String data) {
            // write your code here
            if(data == "{}")
                return null;
            // 以逗号分割
            String[] vals = data.substring(1,data.length()-1).split(",");
            ArrayList<TreeNode> queue = new ArrayList<TreeNode>();
            // 根节点 
            TreeNode root = new TreeNode(Integer.parseInt(vals[0]));
            queue.add(root);
            int index = 0;
            boolean isLeftChild = true;
            for (int i = 1; i < vals.length; i++) {
                if (!vals[i].equals("#")) {
                    TreeNode node = new TreeNode(Integer.parseInt(vals[i]));
                    if (isLeftChild) {
                        queue.get(index).left = node;
                    } else {
                        queue.get(index).right = node;
                    }
                    queue.add(node);
                }
                if (!isLeftChild) {
                    index++;
                }
                isLeftChild = !isLeftChild;
            }
            return root;
        }
    }
  • 相关阅读:
    windows上传代码到Gitee
    gitee推送报错error: failed to push some refs to
    socket和http区别
    腿姐考前叮嘱
    20数学真题答案
    windows下如何查看磁盘IO性能 复制于网络上
    初识WCF异常 1
    WCF中DBNull序列化的问题
    在SQL Server数据库之间进行数据导入导出
    在Silverlight中打开网页的几种方法
  • 原文地址:https://www.cnblogs.com/theskulls/p/5114359.html
Copyright © 2020-2023  润新知