序列化二叉树

https://blog.nowcoder.net/n/bb677406ee8e4782badf5fb627e41797

题目分析

  1. 题目给出我们一棵树,要求我们实现两个函数
  2. 第一个函数要求我们以任意遍历方式返回一个字符串
  3. 第二个函数要求我们可以从上一个字符串中重新返回这棵树
  • 方法一:递归

    • 我们采用前序遍历的方式构造字符串并恢复树
    • 序列化过程
      • 递归函数退出条件是当节点为空,则返回"#"。我们一定要用一个"#"来实现占位的操作,这样才能保证我们的树是唯一的,否则单独前序遍历出来的字符串是无法恢复成唯一的一棵树的
      • 然后我们递归地返回 当前值+","+递归左子节点+","+递归右子节点
    • 反序列化过程
      • 我们引入了一个新的结构queue来储存字符串分割后的前序遍历结果
      • 由于前序遍历,我们首先从queue中取出队首,将其对象化成为一个节点
      • 然后将左子节点值设为递归这个queue的函数返回结果
      • 然后将右子节点值设为递归这个queue的函数返回结果
      • 这正好符合了前序遍历的规则,我们倒着又建立了这棵树

 

 

/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/
import java.util.LinkedList;
import java.util.Queue;
public class Solution {
    String Serialize(TreeNode root) {
        if(root == null) return "#";        // 对所有的空节点也要存储占位符号"#"
        return root.val + "," + Serialize(root.left) + "," + Serialize(root.right);    // 递归前序遍历返回字符串
    }
    TreeNode Deserialize(String str) {
       String[] s = str.split(",");                             // 切分字符串
       Queue<String> q = new LinkedList<String>();
       for(int i = 0; i != s.length; i++) q.offer(s[i]);        // 将分割后的字符串数组顺序入队
       return de(q);                                            // 按照新的递归函数进行返回
    }
    
    TreeNode de(Queue<String> queue) {
        String s = queue.poll();                                // 递归函数每次从队首读出一个元素,因此读出的顺序也是前序
        if(s.equals("#")) return null;                          // 对递归推出条件之一进行处理
        TreeNode head = new TreeNode(Integer.valueOf(s));       // 前序首先建立一个节点
        head.left = de(queue);                                  // 然后递归左右子节点
        head.right = de(queue);
        return head;
    }
    
}

 

同https://www.cnblogs.com/wzj4858/p/7712014.html的区别: 本题是普通二叉树。

posted @ 2022-02-03 10:01  daniel456  阅读(53)  评论(0编辑  收藏  举报