https://blog.nowcoder.net/n/bb677406ee8e4782badf5fb627e41797
题目分析
- 题目给出我们一棵树,要求我们实现两个函数
- 第一个函数要求我们以任意遍历方式返回一个字符串
- 第二个函数要求我们可以从上一个字符串中重新返回这棵树
-
方法一:递归
- 我们采用前序遍历的方式构造字符串并恢复树
- 序列化过程
- 递归函数退出条件是当节点为空,则返回
"#"
。我们一定要用一个"#"
来实现占位的操作,这样才能保证我们的树是唯一的,否则单独前序遍历出来的字符串是无法恢复成唯一的一棵树的 - 然后我们递归地返回
当前值+","+递归左子节点+","+递归右子节点
- 递归函数退出条件是当节点为空,则返回
- 反序列化过程
- 我们引入了一个新的结构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的区别: 本题是普通二叉树。