[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)。

在深度優先中,你有又能夠使用前序,中序和後序搜索方法,你能夠使用遞歸或者非遞歸算法實現。對於廣度優先算法,通常都會採用非遞歸的實現方法進行實現。

相關文章
相關標籤/搜索