# 剑指 Offer 37 -「java」层序遍历BFS 解决二叉树的序列化与反序列化 清晰的实现思路

Tags:

  • 困难
  • 二叉树
  • BFS
  • java

题目链接:

剑指 Offer 37. 序列化二叉树


解题思路[BFS]:

  1. [序列化(树展开)]: 借助队列进行层序遍历(BFS), 展开的过程中, 需要注意对于左缺子树以及最后一层的空子树层的判断和处理;

  2. [反序列化(生成树)]: 借助队列进行层序遍历, 组装原二叉树, 组装过程中也需要注意对于"null"值的处理;


实现代码:

public class Codec {

    // Encodes a tree to a single string.
    public String serialize(TreeNode root) {    //BFS (利用队列实现)
        if(null == root){
            return "[]";
        }
        StringBuilder sb = new StringBuilder("[");
        Queue<TreeNode> queue = new LinkedList<>();
        queue.add(root);
        boolean flag = true;   //当前是否还需要继续遍历(是否为"非最后一层")
        while(!queue.isEmpty() && flag){    //同时根据是否有下一层作为判断条件
            int count = queue.size();
            boolean hasNext = false;    //本层是否还有下一层
            for(int i=0; i< count; i++){
                TreeNode node = queue.poll();
                TreeNode left = node.left;
                TreeNode right = node.right;
                if(node.val != Integer.MAX_VALUE){  //当前节点为非空节点
                    sb.append( node.val +",");
                    queue.add(left == null ? new TreeNode(Integer.MAX_VALUE) : left);   //子节点为空节点, 需要新建一个空节点放入队列
                    queue.add(right == null ? new TreeNode(Integer.MAX_VALUE) : right);
                }else{  //当前为空节点
                    sb.append("null,");
                }
                hasNext = !(left == null && right == null) || hasNext;  //当前节点是否有子节点
            }
            flag = flag && hasNext; //当前层是否还有下一层的子节点
        }
        return sb.substring(0,sb.length()-1).toString() + "]";  //处理返回值
    }

    // Decodes your encoded data to tree.
    public TreeNode deserialize(String data) {  //BFS, 借助队列
        data = data.substring(1, data.length()-1);
        if(null == data || data.length() == 0){
            return null;
        }
        String[] arr = data.split(",");
        int ind = 1;    //当前遍历的角标
        TreeNode head = new TreeNode(Integer.parseInt(arr[0]));
        Queue <TreeNode> queue = new LinkedList<>();
        queue.add(head);

        while(!queue.isEmpty() && ind < arr.length){
            int count = queue.size();
            for(int i= 0; i<count; i++){
                TreeNode curr = queue.poll();
                if(!"null".equals(arr[ind])){   //组装左子节点
                    TreeNode left = new TreeNode(Integer.parseInt(arr[ind]));
                    curr.left = left;
                    queue.add(left);
                }
                ind++;  //无论是否为空, 角标都需要右移
                if(!"null".equals(arr[ind])){   //组装右子节点
                    TreeNode right = new TreeNode(Integer.parseInt(arr[ind]));
                    curr.right = right;
                    queue.add(right);
                }
                ind++;
            }
        }
        return head;
    }
}

提交记录[20210630]:

执行用时:25 ms, 在所有 Java 提交中击败了49.13%的用户
内存消耗:40.6 MB, 在所有 Java 提交中击败了56.75%的用户
posted @ 2023-03-14 20:31  zhiyuanZAG  阅读(37)  评论(0)    收藏  举报