二叉树的序列化和反序列化
题目 - 二叉树的序列化和反序列化
设计一个算法,并编写代码来序列化和反序列化二叉树。将树写入一个文件被称为“序列化”,读取文件后重建同样的二叉树被称为“反序列化”。
如何反序列化或序列化二叉树是没有限制的,你只需要确保可以将二叉树序列化为一个字符串,并且可以将字符串反序列化为原来的树结构。
分析
简单的说就是广度遍历二叉树,和根据数组生成二叉树。
先放上二叉树的类
/**
* 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;
}

浙公网安备 33010602011771号