题目:
二叉树被记录成文件的过程叫做二叉树的序列化,通过文件内容重建愿挨二叉树的过程叫做二叉树的反序列化。给定一棵二叉树的头节点head,已知二叉树节点值的类型为32位整型。请设计一种二叉树序列化和反序列化的方案。
方法一:
通过先序遍历实现序列化和反序列化
首先假设序列化的结果字符串为str,初始时 str = ""。先序遍历二叉树,如果遇到null节点,就在str的末尾加上 “#!” ,“#”表示这个节点为空,节点值不存在。“!”表示一个值的结束;如果遇到不为空的节点,假设节点值为3,就在str的末尾加上 “3!”。
先序遍历序列化代码:
public static String serialByPre(Node head) {
if (head == null) {
return "#!";
}
String res = head.value + "!";
res += serialByPre(head.left);
res += serialByPre(head.right);
return res;
}
再根据序列化的结果字符串str,重构二叉树。
先序遍历反序列化代码:
//1!2!4!#!#!5!#!#!3!#!6!#!#!
public static Node reconByPreString(String preStr) {
//按感叹号分割
String[] values = preStr.split("!");
Queue<String> queue = new LinkedList<>();
for (int i = 0; i != values.length; i++) {
//进队
queue.offer(values[i]);
}
return reconPreOrder(queue);
}
public static Node reconPreOrder(Queue<String> queue) {
String value = queue.poll();
if (value.equals("#")) {
return null;
}
Node head = new Node(Integer.valueOf(value));
head.left = reconPreOrder(queue);
head.right = reconPreOrder(queue);
return head;
}
方法二:通过层遍历实现序列化
public static String serialByLevel(Node head) {
if (head == null) {
return "#!";
}
String res = head.value + "!";
Queue<Node> queue = new LinkedList<>();
queue.offer(head);
while (!queue.isEmpty()) {
head = queue.poll();
if (head.left != null) {
res += head.left.value + "!";
queue.offer(head.left);
} else {
res += "#!";
}
if (head.right != null) {
res += head.right.value + "!";
queue.offer(head.right);
} else {
res += "#!";
}
}
return res;
}