本文已参与「新人创作礼」活动,一起开启掘金创作之路。
思路
我们先了解什么是序列化和反序列化,就是我们要去保存一棵树的时候,我们会把它变成一个字符串,之后要用的时候,我们就可以按照之前的字符串再复原树
我们可以用先序来序列化。
我们在遇到一个节点的时候先打印,然后打个分隔符,当我们遇到null的时候我们可以用一个字符来辨别。这个是我们的序列化
在我们反序列化的时候我们要知道是怎么序列化的,然后用同样的方式反序列化。
代码
节点代码
public static class Node {
public int value;
public Node left;
public Node right;
public Node(int data) {
this.value = data;
}
}
先序序列化
调用函数
public static Queue<String> preSerial(Node head) {
Queue<String> ans = new LinkedList<>();
pres(head , ans);
return ans;
}
我们用一个队列来保存序列化的结果,然后调用了递归。
递归遍历
public static void pres(Node head, Queue<String> ans) {
if(head == null){
ans.add(null);
return;
}else{
ans.add(String.valueOf(head));
pres(head.left , ans);
pres(head.right , ans);
}
}
如果大家熟悉先序遍历的话对这个代码肯定是有了解的。后面的后序序列化其实都一样的大家可以举一反三的来操作。
不过大家要注意的是,中序是不能序列化和反序列化的。
先序反序列化
调用函数
public static Node buildByPreQueue(Queue<String> prelist) {
if (prelist == null || prelist.size() == 0) {
return null;
}
return preb(prelist);
}
我们首先还是要判空的,之后我们就可以直接调用递归了。
递归复原
public static Node preb(Queue<String> prelist) {
String value = prelist.poll();
if (value == null) {
return null;
}
Node head = new Node(Integer.valueOf(value));
head.left = preb(prelist);
head.right = preb(prelist);
return head;
}
我们可以看出递归的代码其实还是差不多的。就是创建一个节点,然后让递归返回自己的孩子,然后自己连上就可以了。
上面就是序列化和反序列化。