[LintCode] Serialize and Deserialize Binary Tree(二叉树的序列化和反序列化)

描述

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

如何反序列化或序列化二叉树是没有限制的,你只须要确保能够将二叉树序列化为一个字符串,而且能够将字符串反序列化为原来的树结构。node

对二进制树进行反序列化或序列化的方式没有限制,LintCode将您的serialize输出做为deserialize的输入,它不会检查序列化的结果。git

样例

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

3
 / \
9  20
  /  \
 15   7

咱们的数据是进行 BFS 遍历获得的。当你测试结果 wrong answer时,你能够做为输入调试你的代码。算法

你能够采用其余的方法进行序列化和反序列化。app

代码

GitHub 的源代码,请访问下面的连接:测试

https://github.com/cwiki-us/java-tutorial/blob/master/src/test/java/com/ossez/lang/tutorial/tests/lintcode/LintCode0007SerializeAndDeserialize.javaui

package com.ossez.lang.tutorial.tests.lintcode;spa

import java.util.ArrayList;.net

import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ossez.lang.tutorial.models.TreeNode;

/**
 * <p>
 * 7
 * <ul>
 * <li>@see <a href=
 * "https://www.cwiki.us/display/ITCLASSIFICATION/Serialize+and+Deserialize+Binary+Tree">https://www.cwiki.us/display/ITCLASSIFICATION/Serialize+and+Deserialize+Binary+Tree</a>
 * <li>@see<a href=
 * "https://www.lintcode.com/problem/serialize-and-deserialize-binary-tree">https://www.lintcode.com/problem/serialize-and-deserialize-binary-tree</a>
 * </ul>
 * </p>
 * 
 * @author YuCheng
 *
 */
public class LintCode0007SerializeAndDeserialize {

    private final static Logger logger = LoggerFactory.getLogger(LintCode0007SerializeAndDeserialize.class);

    /**
     * 
     */
    @Test
    public void testMain() {
        logger.debug("BEGIN");
        String data = "{3,9,20,#,#,15,7}";

        System.out.println(serialize(deserialize(data)));

    }

    /**
     * Deserialize from array to tree
     * 
     * @param data
     * @return
     */
    private TreeNode deserialize(String data) {
        // NULL CHECK
        if (data.equals("{}")) {
            return null;
        }

        ArrayList<TreeNode> treeList = new ArrayList<TreeNode>();

        data = data.replace("{", "");
        data = data.replace("}", "");
        String[] vals = data.split(",");

        // INSERT ROOT
        TreeNode root = new TreeNode(Integer.parseInt(vals[0]));
        treeList.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) {
                    treeList.get(index).left = node;
                } else {
                    treeList.get(index).right = node;
                }
                treeList.add(node);
            }

            // LEVEL
            if (!isLeftChild) {
                index++;
            }

            // MOVE TO RIGHT OR NEXT LEVEL
            isLeftChild = !isLeftChild;
        }

        return root;

    }

    /**
     * 
     * @param root
     * @return
     */
    public String serialize(TreeNode root) {
        // write your code here
        if (root == null) {
            return "{}";
        }

        ArrayList<TreeNode> queue = new ArrayList<TreeNode>();
        queue.add(root);

        for (int i = 0; i < queue.size(); i++) {
            TreeNode node = queue.get(i);
            if (node == null) {
                continue;
            }
            queue.add(node.left);
            queue.add(node.right);
        }

        while (queue.get(queue.size() - 1) == null) {
            queue.remove(queue.size() - 1);
        }

        StringBuilder sb = new StringBuilder();
        sb.append("{");
        sb.append(queue.get(0).val);
        for (int i = 1; i < queue.size(); i++) {
            if (queue.get(i) == null) {
                sb.append(",#");
            } else {
                sb.append(",");
                sb.append(queue.get(i).val);
            }
        }
        sb.append("}");
        return sb.toString();
    }

}
 

 

点评

本题目主要须要你对二叉树的遍历方法有所了解。

遍历二叉树主要有 2 类方法,分别为深度优先(DFS)和广度优先(BFS)。

在深度优先中,你有又能够使用前序,中序和后序搜索方法,你能够使用递归或者非递归算法实现。对于广度优先算法,通常都会采用非递归的实现方法进行实现。

相关文章
相关标签/搜索