前言
序列化:二叉树被记录成文件的过程叫做序列化
反序列化:通过文件内容重建原来二叉树的过程叫做反序列化
第一种方式:先序遍历
先序遍历进行序列化和反序列化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
|
func PreorderSerialize(root *TreeNode) string { if root == nil { return "#!" }
var ret string
ret += strconv.Itoa(root.Val) + "!" ret += PreorderSerialize(root.Left) ret += PreorderSerialize(root.Right) return ret }
func PreorderDeserialize(ret string) *TreeNode { strs := strings.Split(ret, "!")
root := ReconstructTreeFromPreorder(&strs) return root }
func ReconstructTreeFromPreorder(strs *[]string) *TreeNode { if (*strs)[0] == "#" { (*strs) = (*strs)[1:] return nil }
val, _ := strconv.Atoi((*strs)[0]) node := &TreeNode{ Val: val, }
(*strs) = (*strs)[1:] node.Left = ReconstructTreeFromPreorder(strs) node.Right = ReconstructTreeFromPreorder(strs)
return node }
|
第二种方式:层次遍历
自己写的层次遍历序列化
层次遍历进行序列化和反序列化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
|
func LevelOrderSerialize(root *TreeNode) string { if root == nil { return "#!" }
var ret string queue := []*TreeNode{root}
for len(queue) != 0 { node := queue[0] queue = queue[1:]
if node != nil { ret += strconv.Itoa(node.Val) + "!" } else { ret += "#!" continue } queue = append(queue, node.Left) queue = append(queue, node.Right) }
return ret }
func LevelOrderDeserialize(str string) *TreeNode { strs := strings.Split(str, "!") root := LevelOrderReconstruct(strs) return root }
func LevelOrderReconstruct(strs []string) *TreeNode { var head *TreeNode if strs[0] == "#" { return nil } else { val, _ := strconv.Atoi(strs[0]) head = &TreeNode{ Val: val, } }
index := 1
queue := []*TreeNode{head} for len(queue) != 0 { cur := queue[0] queue = queue[1:]
if strs[index] == "#" { cur.Left = nil } else { val, _ := strconv.Atoi(strs[index]) cur.Left = &TreeNode{ Val: val, } queue = append(queue, cur.Left) } index++
if strs[index] == "#" { cur.Right = nil } else { val, _ := strconv.Atoi(strs[index]) cur.Right = &TreeNode{ Val: val, } queue = append(queue, cur.Right) } index++ }
return head }
|
参考左神代码:对层次遍历进行序列化和反序列化的改进
加入了一个函数generateNodeFromString避免代码臃肿
层次遍历进行序列化和反序列化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
| func LevelOrderSerialize(root *TreeNode) string { if root == nil { return "#!" }
var ret string queue := []*TreeNode{root}
for len(queue) != 0 { node := queue[0] queue = queue[1:]
if node != nil { ret += strconv.Itoa(node.Val) + "!" } else { ret += "#!" continue } queue = append(queue, node.Left) queue = append(queue, node.Right) }
return ret }
func LevelOrderDeserialize(str string) *TreeNode { strs := strings.Split(str, "!") root := LevelOrderReconstruct(strs) return root }
func LevelOrderReconstruct(strs []string) *TreeNode { head := generateNodeFromString(strs[0])
if head == nil { return nil }
index := 1
queue := []*TreeNode{head} for len(queue) != 0 { cur := queue[0] queue = queue[1:]
cur.Left = generateNodeFromString(strs[index]) index++
cur.Right = generateNodeFromString(strs[index]) index++
if cur.Left != nil { queue = append(queue, cur.Left) } if cur.Right != nil { queue = append(queue, cur.Right) } }
return head }
func generateNodeFromString(val string) *TreeNode { if val == "#" { return nil }
temp, _ := strconv.Atoi(val) return &TreeNode{ Val: temp, } }
|
可能出现的问题
递归函数传入切片作为参数造成切片修改后递归回来又还原