297. 二叉树的序列化与反序列化
序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据。
请设计一个算法来实现二叉树的序列化与反序列化。这里不限定你的序列 / 反序列化算法执行逻辑,你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序列化为原始的树结构。
//递归,也是通法,和后一题可以通用
type Codec struct {
res []string
}
func Constructor() Codec {
return Codec{}
}
//序列化
func (this *Codec) serialize(root *TreeNode) string {
if root == nil {
return "X"
}
return strconv.Itoa(root.Val) + "," + this.serialize(root.Left) + "," + this.serialize(root.Right)
}
//反序列化
func buildTree(list *[]string) *TreeNode {
rootVal := (*list)[0]
*list = (*list)[1:]
if rootVal == "X" {
return nil
}
Val, _ := strconv.Atoi(rootVal)
root := &TreeNode{Val: Val}
root.Left = buildTree(list)
root.Right = buildTree(list)
return root
}
func (this *Codec) deserialize(data string) *TreeNode {
list := strings.Split(data, ",")
return buildTree(&list)
}
//bfs,不会考的,太多了
type Codec struct {
res []string
}
func Constructor() Codec {
return Codec{}
}
//序列化
func (this *Codec) serialize(root *TreeNode) string {
q := []*TreeNode{root}
res := []string{}
for len(q) != 0 {
node := q[0]
q = q[1:]
if node != nil {
res = append(res, strconv.Itoa(node.Val))
q = append(q, node.Left)
q = append(q, node.Right)
} else {
res = append(res, "X")
}
}
return strings.Join(res, ",")
}
//反序列化
func (this *Codec) deserialize(data string) *TreeNode {
if data == "X" {
return nil
}
list := strings.Split(data, ",")
Val, _ := strconv.Atoi(list[0])
root := &TreeNode{Val: Val}
q := []*TreeNode{root}
cursor := 1
for cursor < len(list) {
node := q[0]
q = q[1:]
leftVal := list[cursor]
rightVal := list[cursor+1]
if leftVal != "X" {
v, _ := strconv.Atoi(leftVal)
leftNode := &TreeNode{Val: v}
node.Left = leftNode
q = append(q, leftNode)
}
if rightVal != "X" {
v, _ := strconv.Atoi(rightVal)
rightNode := &TreeNode{Val: v}
node.Right = rightNode
q = append(q, rightNode)
}
cursor += 2
}
return root
}