0%

Golang 重建二叉树

这是剑指offer的一道题。

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建出如下图所示的二叉树并输出它的头结点。 

思路如下:

  • 中序遍历中根节点之前的节点属于左子树,之后为右子树。
  • 前序遍历的第一个节点为根节点。
  • 前序遍历结果的排列为:根节点-左子树节点-右子树节点
  • 拆分出左子树和右子树递归重复上述过程
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
package main

import (
"fmt"
)

// 重建二叉树

type Node struct {
value int64
left *Node
right *Node
}

func main() {
preOrder := []int64{1,2,4,7,3,5,6,8}
inOrder := []int64{4,7,2,1,5,3,8,6}

tree := constructBTree(preOrder, inOrder)

//将构建好的二叉树 输出先序遍历和中序遍历的结果 用于检验
preCatTree(tree)
inCatTree(tree)
}

//重建二叉树
func constructBTree(preOrder, inOrder []int64) *Node{
l := len(preOrder)
if l == 0{
return nil
}

root := &Node{
value:preOrder[0],
}
if l == 1{
return root
}

leftLen := 0
rightLen := 0
for _,v := range inOrder{
if v == root.value{
break
}
leftLen++ //根节点之前的为左子树长度
}
rightLen = l - leftLen - 1 //右子树长度

if leftLen > 0{
//fmt.Println("左子树",preOrder[1:leftLen+1], inOrder[0:leftLen]) //可打开注释查看详细过程
root.left = constructBTree(preOrder[1:leftLen+1], inOrder[0:leftLen])
}
if rightLen >0{
//fmt.Println("右子树",preOrder[leftLen+1:], inOrder[leftLen+1:])
root.right = constructBTree(preOrder[leftLen+1:], inOrder[leftLen+1:])
}

return root
}


func preCatTree(t *Node) {
fmt.Println(t.value)
if t.left!=nil{
preCatTree(t.left)
}
if t.right!=nil{
preCatTree(t.right)
}
}
func inCatTree(t *Node) {
if t.left!=nil{
inCatTree(t.left)
}
fmt.Println(t.value)
if t.right!=nil{
inCatTree(t.right)
}
}