描述
設計一個算法,並編寫代碼來序列化和反序列化二叉樹。將樹寫入一個文件被稱爲“序列化”,讀取文件後重建同樣的二叉樹被稱爲“反序列化”。
如何反序列化或序列化二叉樹是沒有限制的,你只需要確保可以將二叉樹序列化爲一個字符串,並且可以將字符串反序列化爲原來的樹結構。
對二進制樹進行反序列化或序列化的方式沒有限制,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)。
在深度優先中,你有又可以使用前序,中序和後序搜索方法,你可以使用遞歸或者非遞歸算法實現。對於廣度優先算法,一般都會採用非遞歸的實現方法進行實現。