题目链接
思路:层序遍历
分析:普通得情况下,如果单独靠一种遍历序列(前序、中序、后序、层序),想要唯一确定一颗二叉树,是无法确定的。
因为是如果一个节点左孩子没有,而有右孩子,此时,无法构造树的时候,无法区分这个孩子是左孩子还是右孩子。其他的情况也类似。
所以在遍历的时候,如果某个孩子为null,那么我们可以用一个标志来表示。
举例:
如果是上面这种情况。
层序遍历:1,2,3,4
此时无法确定3是不是1的孩子。
但是如果将层序遍历为:1,2,null,3,4,null,null,null,null
这样就可以确定一颗二叉树了。
代码:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Codec {
int index = 0;
// Encodes a tree to a single string.
public String serialize(TreeNode root) {
if(root==null){
return "";
}
StringBuilder sb = new StringBuilder();
levelOrder(root, sb);
return sb.toString();
}
/**
* 层序遍历,将root补全,也就是每个非空节点都一定有两个孩子节点
* @param root
* @param sb
*/
private void levelOrder(TreeNode root, StringBuilder sb){
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while(!queue.isEmpty()){
//取出第一个节点
TreeNode top = queue.poll();
if(top==null){
//如果此时节点为null,那么说明父类没有缺了孩子,那么补一个 值为null得孩子给他
sb.append("null,");
}else{
//否则记录孩子,并且将该节点得左右孩子放入队列,不管是否为null,即使是null,也当作是孩子
sb.append(top.val+",");
queue.offer(top.left);
queue.offer(top.right);
}
}
//去掉最后一个逗号
sb.deleteCharAt(sb.length()-1);
}
// Decodes your encoded data to tree.
public TreeNode deserialize(String data) {
if(data==null || "".equals(data)){
return null;
}
String[] str1 = data.split(",");
Queue<String> queue = new LinkedList<>();
for(String str : str1){
queue.offer(str);
}
TreeNode root = dese(queue);
return root;
}
/**
*
* @param queue 节点值队列
* @return
*/
private TreeNode dese(Queue<String> queue){
//节点队列
Queue<TreeNode> treeNodeQueue = new LinkedList<>();
//第一个肯定是根节点
TreeNode root = new TreeNode(Integer.valueOf(queue.poll()));
//根节点入队
treeNodeQueue.offer(root);
//只要还有节点值,那就没完
while(!queue.isEmpty()){
//取出当前得节点,找他的左右孩子
TreeNode nodeTop = treeNodeQueue.poll();
//取出值
String top = queue.poll();
//左右孩子
TreeNode left = null;
TreeNode right = null;
//只要孩子不为null,那么就构造孩子
if(!top.equals("null")){
left = new TreeNode(Integer.valueOf(top));
}
top = queue.poll();
if(!top.equals("null")){
right = new TreeNode(Integer.valueOf(top));
}
nodeTop.left = left;
nodeTop.right = right;
//只要孩子不为null,那么将孩子放入队列,以便寻找孩子得孩子
if(left!=null){
treeNodeQueue.offer(left);
}
if(right!=null){
treeNodeQueue.offer(right);
}
}
return root;
}
}
// Your Codec object will be instantiated and called as such:
// Codec ser = new Codec();
// Codec deser = new Codec();
// TreeNode ans = deser.deserialize(ser.serialize(root));