链接:https://leetcode-cn.com/problems/xu-lie-hua-er-cha-shu-lcof/
描述:提供两个函数分别实现同一策略下的二叉树的序列化和反序列化
序列化,在于利用null结点进行占位后的结果无歧义
方法一:前序遍历序列化
思路:对二叉树进行前序遍历,如果使用字符串进行拼接,需要在每个字符后面添加分隔符,如',',便于后面进行分割。如果使用容器,如Queue,直接poll就行
序列化代码:
public static String serialize(TreeNode root) {
if (root == null) {
return "#";
}
// 按照前序遍历规则,保存数据就行
StringBuilder sb = new StringBuilder();
sb.append(root.val + ",");
sb.append(serialize(root.left) + ",");
sb.append(serialize(root.right) + ",");
return sb.toString();
}
反序列化:
public static TreeNode deserialize(String data) {
String[] split = data.split(",");
Queue<String> q = new LinkedList<>();
for (int i = 0; i < split.length; i++) {
q.add(split[i]);
}
return deserializeHelp(q);
}
public static TreeNode deserializeHelp(Queue<String> queue) {
String ch = queue.poll();
// 这里注意字符串的比较要用equals()
if (ch == null || "#".equals(ch)) return null;
// 建立头结点,从全局来看,最初创建的head也是最后返回,因此就是整个树头
// 建树过程满足前序遍历
TreeNode head = new TreeNode(Integer.valueOf(ch));
head.left = deserializeHelp(queue);
head.right = deserializeHelp(queue);
return head;
}
方法二:层次遍历序列化
依照层进行遍历,将节点转成字符串,并用","分割。 LinkedList就是BFS中需要涉及的队列。
序列化:
public String serialize(TreeNode root) {
if (root == null) {
return "#,";
}
// 用于层次遍历的队列
Queue<TreeNode> q = new LinkedList<>();
q.add(root);
StringBuilder sb = new StringBuilder();
sb.append(root.val + ",");
while (!q.isEmpty()) {
TreeNode head = q.poll();
// 看左右孩子是否为空,然后分别放入不同的值;如果不为空,加入队列便于下次循环
if (head.left != null) {
q.add(head.left);
sb.append(head.left.val + ",");
} else {
sb.append("#,");
}
if (head.right != null) {
q.add(head.right);
sb.append(head.right.val + ",");
} else {
sb.append("#,");
}
}
return sb.toString();
}
反序列化:
public TreeNode deserialize(String data) {
String[] splits = data.split(",");
Queue<String> q = new LinkedList<>();
for (int i = 0; i < splits.length; i++) {
q.add(splits[i]);
}
return deserializeHelp(q);
}
// 反序列化的时候注意字符是否为#,因为会涉及Integer.valueOf()
public TreeNode deserializeHelp(Queue<String> queue) {
String ch = queue.poll();
TreeNode node = ("#".equals(ch)) ? null : new TreeNode(Integer.valueOf(ch));
Queue<TreeNode> list = new LinkedList<>();
if (node != null) list.add(node);
while (!list.isEmpty()) {
TreeNode tmp = list.poll();
tmp.left = ("#".equals(ch = queue.poll())) ? null : new TreeNode(Integer.valueOf(ch));
tmp.right = ("#".equals(ch = queue.poll())) ? null : new TreeNode(Integer.valueOf(ch));
// 如果某一个结点为Null,说明后面肯定没有子树了,不用添加了
if (tmp.left != null) {
list.add(tmp.left);
}
if (tmp.right != null) {
list.add(tmp.right);
}
}
return node;
}