序列化
递归法
思路
如果子节点为空,用null表示。如果不用null表示会无法确定位置!
序列化的时候和遍历的时候差不多,也是用递归。这里只写一种方法,因为前序,中序,后序只不过是顺序不一样而已,调换一下ans.add
的顺序即可。
代码
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);
}else {
ans.add(String.valueOf(head.val));
pres(head.left,ans);
pres(head.right,ans);
}
}
非递归法
思路
思路是用bfs的思想。
我们使用队列queue保存节点,使用ans保存序列化。首先头节点若为空就只序列化,如果不为空就再入队。然后判断子节点,先判断左子节点,为空就只入队不序列化,不为空就都加,然后判断右子节点,最后循环完要poll给head。如此反复判断直至队列为空.
代码
```//非递归序列化
public static Queue<String> levelSerial(Node head){
Queue<String>ans=new LinkedList<>();
if(head==null) {
ans.add(null);
}else {
ans.add(String.valueOf(head.val));
Queue<Node>queue=new LinkedList<>();
queue.add(head);
while(!queue.isEmpty()) {
head=queue.poll();
if(head==null) continue;
if(head.left!=null) {
ans.add(String.valueOf(head.left.val));
queue.add(head.left);
}else {
queue.add(null);
}
if(head.right!=null) {
ans.add(String.valueOf(head.right.val));
queue.add(head.right);
}else {
ans.add(null);
}
}
}
return 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;
}
非递归法
思路
bfs按层建立节点
代码
//非递归反序列化
public static Node buildByLevelQueue(Queue<String> levelList) {
if(levelList==null||levelList.size()==0) {
return null;
}
Node head = generateNode(levelList.poll());
Queue<Node> queue=new LinkedList<>();
if(head!=null) {
queue.add(head);
}
Node node=null;
while(!queue.isEmpty()) {
node=queue.poll();
node.left=generateNode(levelList.poll());
node.right=generateNode(levelList.poll());
if(node.left!=null) {
queue.add(node.left);
}
if(node.right!=null) {
queue.add(node.right);
}
}
return head;
}
public static Node generateNode(String val) {
if(val==null) {
return null;
}
return new Node(Integer.valueOf(val));
}
注意点以及别的
- 序列化与反序列化是严格对应的! 意思就是如果使用前序序列化,那么就必须使用前序反序列化建立节点,这个是严格对应的,否则会出现错误!还有,中序遍历不能够序列化,因为可能会出现歧义。
- 朋友可以想一下,其实bfs按层遍历(从上到下,从左到右)其实就是先序遍历,不论是打印还是序列化反序列化,都是相通的。
说实话,理解的还不是很透彻,最多只能理解一些,但是自己写应该写不出,以后多看看、