递归与非递归实现二叉树的序列化与反序列化

序列化

递归法

思路

如果子节点为空,用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按层遍历(从上到下,从左到右)其实就是先序遍历,不论是打印还是序列化反序列化,都是相通的。

说实话,理解的还不是很透彻,最多只能理解一些,但是自己写应该写不出,以后多看看、

猜你喜欢

转载自blog.csdn.net/VanGotoBilibili/article/details/115046768
今日推荐