297. 二叉树的序列化与反序列化

序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据。

请设计一个算法来实现二叉树的序列化与反序列化。这里不限定你的序列 / 反序列化算法执行逻辑,你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序列化为原始的树结构。

提示: 输入输出格式与 LeetCode 目前使用的方式一致,详情请参阅 LeetCode 序列化二叉树的格式。你并非必须采取这种方式,你也可以采用其他的方法解决这个问题。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/serialize-and-deserialize-binary-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路及方法

我用广度优先遍历的方法,将一棵树层次序列化,然后通过序列反推一棵树。用了队列的方法,代码写得很清楚了,可以看看。

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

    // Encodes a tree to a single string.
   public String serialize(TreeNode root) {
        if (root == null) return "";

        StringBuilder res = new StringBuilder();
        // BFS
        Queue<TreeNode> queue = new LinkedList<>();
        // 根结点入队
        queue.offer(root);

        while (!queue.isEmpty()) {
            int size = queue.size();
            // 记录同一层节点的值
            for (int i = 0; i < size; i++) {
                TreeNode cur = queue.poll();
                // 空节点为 #
                if (cur == null) {
                    res.append('#').append(',');
                    continue;
                }
                res.append(cur.val).append(',');
                // 子结点入队
                queue.offer(cur.left);
                queue.offer(cur.right);
            }
        }
        System.out.println(res);

        return res.toString();
    }

    // Decodes your encoded data to tree.
    public TreeNode deserialize(String data) {
        if (data.length() == 0) return null;
        // 获取BFS数组
        String[] dataStr = data.split(",");
        Queue<TreeNode> queue = new LinkedList<>();
        // 序列下标
        int idx = 0;
        // 构造根节点
        TreeNode root = new TreeNode(Integer.parseInt(dataStr[idx++]));
        // 根节点入队
        queue.offer(root);
        while (!queue.isEmpty()) {
            int size = queue.size();
            // 同一层节点出队
            for (int i = 0; i < size; i++) {
                TreeNode cur = queue.poll();
                if (cur == null) continue;
                // 获得当前节点的子节点
                String leftChar = dataStr[idx++];
                String rightChar = dataStr[idx++];
                cur.left = leftChar.equals("#") ? null : new TreeNode(Integer.parseInt(leftChar));
                cur.right = rightChar.equals("#") ? null : new TreeNode(Integer.parseInt(rightChar));
                // 左右子树入队
                queue.offer(cur.left);
                queue.offer(cur.right);
            }
        }

        return root;
    }
}

// Your Codec object will be instantiated and called as such:
// Codec ser = new Codec();
// Codec deser = new Codec();
// TreeNode ans = deser.deserialize(ser.serialize(root));

结果如下:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容