1. 前序遍历
public class Codec {
public String serialize(TreeNode root) {
if(root==null) {
return "#";
}
return root.val+","+serialize(root.left)+","+serialize(root.right);
}
// Decodes your encoded data to tree.
public TreeNode deserialize(String data) {
String[] values=data.split(",");
LinkedList<String> q=new LinkedList<>();
q.addAll(Arrays.asList(values));
return deserialize(data, q);
}
public TreeNode deserialize(String data,LinkedList<String> q) {
String s=q.removeFirst();
if(s.equals("#")) {
return null;
}
TreeNode node=new TreeNode(Integer.parseInt(s));
node.left=deserialize(data, q);
node.right=deserialize(data, q);
return node;
}
}
2. 后序遍历
public String serialize(TreeNode root) {
if(root==null) {
return "#";
}
return serialize(root.left)+","+serialize(root.right)+","+root.val;
}
// Decodes your encoded data to tree.
public TreeNode deserialize(String data) {
String[] values=data.split(",");
LinkedList<String> q=new LinkedList<>();
q.addAll(Arrays.asList(values));
return deserialize(data, q);
}
public TreeNode deserialize(String data,LinkedList<String> q) {
String s=q.removeLast();
if(s.equals("#")) {
return null;
}
TreeNode node=new TreeNode(Integer.parseInt(s));
node.right=deserialize(data, q);//左右根 根节点处理完了 往后取的是右结点
node.left=deserialize(data, q);
return node;
}
后序处理的方式相较于前序遍历,只需要改变两个地方:
- 前序是每次取队列中的第一个元素,后序是取队列中的最后一个元素
- 前序反序列化递归顺序是“根左右”, 后续反序列化递归顺序是“根右左”
3. 层次遍历
public String serialize(TreeNode root) {
LinkedList<TreeNode> q = new LinkedList<>();
StringBuilder sb = new StringBuilder();
q.offer(root);
while (!q.isEmpty()) {
TreeNode node = q.poll();
if (node == null) {
sb.append("#" + ",");
continue;
}
sb.append(node.val + ",");
q.offer(node.left);//空节点也需要入队 后面作为#拼接
q.offer(node.right);
}
return sb.toString().substring(0, sb.length() - 1);// 最后多了1个逗号 去掉
}
// Decodes your encoded data to tree.
public TreeNode deserialize(String data) {
String[] values = data.split(",");
int n = values.length;
if (values[0].equals("#")) {
return null;
}
LinkedList<TreeNode> q = new LinkedList<>();
q.offer(new TreeNode(Integer.parseInt(values[0])));
TreeNode root = q.peek();
int i = 1;// 注意i从1开始 因为根节点不作为子节点
while (i < n) {
TreeNode node = q.poll();// 获取队首节点
if (!values[i].equals("#")) {
// 当前节点存在左子节点
node.left = new TreeNode(Integer.parseInt(values[i]));
q.offer(node.left);// 左子节点加入队列 下一次取出来处理
}
i += 1;
if (!values[i].equals("#")) {
// 当前节点存在右子节点
node.right = new TreeNode(Integer.parseInt(values[i]));
q.offer(node.right);
}
i += 1;
}
return root;
}
- 序列化时使用一个队列,同时拼接字符串
- 反序列化时也需要使用一个队列保存已经创建的非空节点,空节点不入队
没有中序序列化方式,中序序列化不能确定一棵二叉树