序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据。
请设计一个算法来实现二叉树的序列化与反序列化。这里不限定你的序列 / 反序列化算法执行逻辑,你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序列化为原始的树结构。
提示: 输入输出格式与 LeetCode 目前使用的方式一致,详情请参阅 LeetCode 序列化二叉树的格式。你并非必须采取这种方式,你也可以采用其他的方法解决这个问题。
输入:root = [1,2,3,null,null,4,5] 输出:[1,2,3,null,null,4,5]
示例 2:
输入:root = [] 输出:[]
示例 3:
输入:root = [1] 输出:[1]
示例 4:
输入:root = [1,2] 输出:[1,2]
提示:
- 树中结点数在范围 [0, 104] 内
- -1000 <= Node.val <= 1000
平时我们使用的序列化反序列化工具有很多 json,jackson等,他们是将对象转换成byte[]数组,并将byte[]数组反序列化成对象的过程。
今天我们这道题要求我们将一个树转成字符串,再从字符串反序列化成树。今天我就思考下如何将该题通过深度遍历的形式实现。
首先是深度遍历数,每次遍历都将其放入StringBuffer当中
private void toBeString(TreeNode root) { if (root == null) { sb.append("null").append(","); return; } sb.append(root.val).append(","); toBeString(root.left); toBeString(root.right); }
1、遇到root为空节点,则放入StringBuffer一个“null,”字符串
2、如果遇到正常节点,则将节点值放入到StringBuffer。
3、深度遍历左右节点都做这件事儿,知道所有节点都遍历完毕。
1、首先将String字符串按照逗号分割,并将其放入数组中。
2、深度遍历list,每次取出并连接成链表
完整代码如下,仅供参考:
StringBuffer sb = new StringBuffer();
public String serialize(TreeNode root) {
toBeString(root);
return sb.toString();
}
private void toBeString(TreeNode root) {
if (root == null) {
sb.append("null").append(",");
return;
}
sb.append(root.val).append(",");
toBeString(root.left);
toBeString(root.right);
}
// Decodes your encoded data to tree.
public TreeNode deserialize(String data) {
List<String> list = new ArrayList<>(Arrays.asList(data.split(",")));
if ("null".equals(list.get(0))) {
return null;
}
return toBeNode(list);
}
private TreeNode toBeNode(List<String> list) {
if ("null".equals(list.get(0))) {
list.remove(0);
return null;
}
TreeNode node = new TreeNode(Integer.valueOf(list.get(0)));
list.remove(0);
node.left = toBeNode(list);
node.right = toBeNode(list);
return node;
}
时间复杂度O(n),空间复杂度O(n)