[LintCode] Serialize and Deserialize Binary Tree(二叉樹的序列化和反序列化)
阿新 • • 發佈:2018-12-17
描述
設計一個演算法,並編寫程式碼來序列化和反序列化二叉樹。將樹寫入一個檔案被稱為“序列化”,讀取檔案後重建同樣的二叉樹被稱為“反序列化”。
如何反序列化或序列化二叉樹是沒有限制的,你只需要確保可以將二叉樹序列化為一個字串,並且可以將字串反序列化為原來的樹結構。
對二進位制樹進行反序列化或序列化的方式沒有限制,LintCode將您的serialize
輸出作為deserialize
的輸入,它不會檢查序列化的結果。
樣例
給出一個測試資料樣例, 二叉樹{3,9,20,#,#,15,7}
,表示如下的樹結構:
3 / \ 9 20 / \ 15 7
我們的資料是進行 BFS 遍歷得到的。當你測試結果 wrong answer時,你可以作為輸入除錯你的程式碼。
你可以採用其他的方法進行序列化和反序列化。
程式碼
GitHub 的原始碼,請訪問下面的連結:
package com.ossez.lang.tutorial.tests.lintcode; import java.util.ArrayList; 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)。
在深度優先中,你有又可以使用前序,中序和後序搜尋方法,你可以使用遞迴或者非遞迴演算法實現。對於廣度優先演算法,一般都會採用非遞迴的實現方法進行實現。