二叉树的序列化和反序列化

题目 - 二叉树的序列化和反序列化

设计一个算法,并编写代码来序列化和反序列化二叉树。将树写入一个文件被称为“序列化”,读取文件后重建同样的二叉树被称为“反序列化”。

如何反序列化或序列化二叉树是没有限制的,你只需要确保可以将二叉树序列化为一个字符串,并且可以将字符串反序列化为原来的树结构。

分析

简单的说就是广度遍历二叉树,和根据数组生成二叉树。

先放上二叉树的类

/**
 * Definition of TreeNode:
 * public class TreeNode {
 *     public int val;
 *     public TreeNode left, right;
 *     public TreeNode(int val) {
 *         this.val = val;
 *         this.left = this.right = null;
 *     }
 * }
 */

先说遍历 -- 两种思路

第一种思路

先从根节点开始入手,将根节点的孩子遍历出来,如果不为空,将其放入栈中,遍历完根节点之后,将栈中的首位取出作为根节点,再对它进行遍历,以此类推。

代码
    public String serialize(TreeNode root) {
        // write your code here
        if (root == null) {
            return "{}";
        }
        StringBuilder sb = new StringBuilder();
        sb.append("{");
        LinkedList<TreeNode> trees = new LinkedList<TreeNode>();
        sb.append(root.val);
        while(root!=null){
          //左孩子不为空,将值放入结果,并将该节点存到栈中
            if(root.left!=null){
                sb.append(",");
              sb.append(root.left.val);
              trees.add(root.left);
            }
            else{
                sb.append(",#");
            }
            //右孩子不为空,将值放入结果,并将该节点存到栈中
            if(root.right!=null){
                sb.append(",");
                sb.append(root.right.val);
                trees.add(root.right);
            }
            else{
                 sb.append(",#");
            }
            
            root = trees.poll();
        }
        sb.append("}");
        System.out.println(sb.toString());
        return sb.toString();
 }

第二种思路

先遍历出所有的节点数量,然后去掉最后的空节点,再遍历所有的节点,然后根据节点是否为空,修改结果。

代码
       public String serialize(TreeNode root) {
       if (root == null) {
            return "{}";
        }

        ArrayList<TreeNode> queue = new ArrayList<TreeNode>();
        queue.add(root);

        for (int i = 0; i < queue.size(); i++) {
            TreeNode node = queue.get(i);
            if (node == null) {
                continue;
            }
            queue.add(node.left);
            queue.add(node.right);
        }

        while (queue.get(queue.size() - 1) == null) {
            queue.remove(queue.size() - 1);
        }

        StringBuilder sb = new StringBuilder();
        sb.append("{");
        sb.append(queue.get(0).val);
        for (int i = 1; i < queue.size(); i++) {
            if (queue.get(i) == null) {
                sb.append(",#");
            } else {
                sb.append(",");
                sb.append(queue.get(i).val);
            }
        }
        sb.append("}");
        return sb.toString();
        
    }

再说根据数据生成二叉树

也是两种思路

第一种思路

跟上面的第一种思路有点像,对数据进行遍历,由第一个数据生成根节点,然后用后面的数据生成孩子节点,将孩子节点组合到根节点上,然后将孩子节点作为根节点,继续对数据进行遍历。

代码
public TreeNode deserialize(String data) {
if(data.equals("{}")){
        return null;
    }
    
    String [] vals = data.substring(1,data.length()-1).split(",");
    LinkedList<TreeNode> trees = new LinkedList<TreeNode>();
    TreeNode root = new TreeNode(Integer.parseInt(vals[0]));
    TreeNode root1 = root;
    for(int i = 1;i<vals.length;){
        TreeNode leftChild;
        TreeNode rightChild;
        if(root1 == null){
            root1 = trees.poll();
            continue;
        }
        if(vals[i].equals("#")){
            leftChild = null;
        }
        else{
            leftChild = new TreeNode(Integer.parseInt(vals[i]));
        }
        root1.left = leftChild;
        trees.add(leftChild);
        i++;
        if(i<vals.length){
            if(vals[i].equals("#")){
                rightChild = null;
            }
            else{
                rightChild = new TreeNode(Integer.parseInt(vals[i]));
            }
        }
        else{
            rightChild = null;
        }
        root1.right = rightChild;
        trees.add(rightChild);
        i++;
        root1 = trees.poll();
    }
    return root;
    
    }

第二种思路

也不能说第二种思路,其实差不多,实现方法改变了一下。

代码
    public TreeNode deserialize(String data) {
        // write your code here
      if (data.equals("{}")) {
            return null;
        }
        String[] vals = data.substring(1, data.length() - 1).split(",");
        ArrayList<TreeNode> queue = new ArrayList<TreeNode>();
        TreeNode root = new TreeNode(Integer.parseInt(vals[0]));
        queue.add(root);
        int index = 0;
        boolean isLeftChild = true;
        for (int i = 1; i < vals.length; i++) {
            if (!vals[i].equals("#")) {
                TreeNode node = new TreeNode(Integer.parseInt(vals[i]));
                if (isLeftChild) {
                    queue.get(index).left = node;
                } else {
                    queue.get(index).right = node;
                }
                queue.add(node);
            }
            if (!isLeftChild) {
                index++;
            }
            isLeftChild = !isLeftChild;
        }
        return root;
        }
posted @ 2020-05-22 20:58  了3乐  阅读(230)  评论(0)    收藏  举报