剑指 Offer 37. 序列化二叉树
请实现两个函数,分别用来序列化和反序列化二叉树。
示例:
你可以将以下二叉树:
1
/ \
2 3
/ \
4 5
序列化为 "[1,2,3,null,null,4,5]"
注意:
本题与主站 297 题相同:https://leetcode-cn.com/problems/serialize-and-deserialize-binary-tree/
解题思路
做过一定数量二叉树题目的同学一定会发现,题目如果用数组形式表示一颗二叉树时,都是用层序遍历表示的,并且null
也会给出,因为这样才好唯一确定一棵树。因此这里序列化我们也用层序遍历
,为完整表示二叉树,考虑将叶节点下的 null
也记录。在此基础上,对于列表中任意某节点 node
,其左子节点 node.left
和右子节点 node.right
在序列中的位置便是唯一确定的了。
Java代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Codec {
// Encodes a tree to a single string.
public String serialize(TreeNode root) {
StringBuilder sb = new StringBuilder();
Queue<TreeNode> queue = new LinkedList<>();
if(root == null) return "null";
//层序遍历,用“,”隔开每个元素,最后会多出一个“,”但是没什么关系。
//因为反序列化时,用‘,’切分,自然就去掉最后的‘,’了
queue.add(root);
sb.append(root.val).append(",");
while(!queue.isEmpty()){
TreeNode cur = queue.poll();
if(cur.left != null){
queue.add(cur.left);
sb.append(cur.left.val).append(",");
}else{
sb.append("null,");
}
if(cur.right != null){
queue.add(cur.right);
sb.append(cur.right.val).append(",");
}else{
sb.append("null,");
}
}
//System.out.print(sb.toString());用于查看是否序列化成功
return sb.toString();
}
// Decodes your encoded data to tree.
public TreeNode deserialize(String data) {
String[] strs = data.split(",");
if(strs.length == 0 || strs[0].equals("null")) return null;
TreeNode root = new TreeNode(Integer.valueOf(strs[0]));
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
int index = 1;
while(index < strs.length){
TreeNode node = queue.poll();
if (node != null) {//按照层序遍历特性,当前节点不是null的话,就从数组中读取两个值作为其左右子节点
TreeNode left = strs[index].equals("null") ? null : new TreeNode(Integer.valueOf(strs[index]));
index++;
queue.add(left);
node.left = left;
TreeNode right = strs[index].equals("null") ? null : new TreeNode(Integer.valueOf(strs[index]));
index++;
queue.add(right);
node.right = right;
}
}
return root;
}
}
// Your Codec object will be instantiated and called as such:
// Codec codec = new Codec();
// codec.deserialize(codec.serialize(root));
Go代码
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
type Codec struct {
}
func Constructor() Codec {
return Codec{}
}
// Serializes a tree to a single string.
func (this *Codec) serialize(root *TreeNode) string {
if root == nil {
return "null"
}
// 层序遍历,用,连接手游节点的字符串表示
sb := strings.Builder{}
queue := make([]*TreeNode,0)
queue = append(queue,root)
sb.WriteString(fmt.Sprintf("%d,",root.Val))
for len(queue) != 0 {
curNode := queue[0]
queue = queue[1:]
if curNode.Left != nil {
sb.WriteString(fmt.Sprintf("%d,",curNode.Left.Val))
queue = append(queue,curNode.Left)
} else {
sb.WriteString("null,")
}
if curNode.Right != nil {
sb.WriteString(fmt.Sprintf("%d,",curNode.Right.Val))
queue = append(queue,curNode.Right)
} else {
sb.WriteString("null,")
}
}
res := sb.String()
// 去除最后的逗号返回
return res[0:len(res) - 1]
}
// Deserializes your encoded data to tree.
func (this *Codec) deserialize(data string) *TreeNode {
// 将数据按,号分割后,再按层序变成树
dataArr := strings.Split(data,",")
if len(dataArr) == 0 || dataArr[0] == "null" {
return nil
}
rootVal ,_:= strconv.Atoi(dataArr[0])
root := &TreeNode{Val:rootVal}
queue := make([]*TreeNode,0)
queue = append(queue,root)
index := 1
for index < len(dataArr) {
curNode := queue[0]
queue = queue[1:]
if curNode != nil {
left,right := &TreeNode{},&TreeNode{}
if dataArr[index] == "null" {
left = nil
} else {
leftVal ,_:= strconv.Atoi(dataArr[index])
left = &TreeNode{Val:leftVal}
}
curNode.Left = left
queue = append(queue,left)
index++
if dataArr[index] == "null" {
right = nil
} else {
rightVal ,_:= strconv.Atoi(dataArr[index])
right = &TreeNode{Val:rightVal}
}
curNode.Right = right
queue = append(queue,right)
index++
}
}
return root
}
/**
* Your Codec object will be instantiated and called as such:
* ser := Constructor();
* deser := Constructor();
* data := ser.serialize(root);
* ans := deser.deserialize(data);
*/