go语言实现前序与中序遍历构造二叉树
例一:
根据一棵树的前序遍历与中序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。
例如,给出
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:
3
/
9 20
/
15 7
/**
-
Definition for a binary tree node.
-
type TreeNode struct {
-
Val int
-
Left *TreeNode
-
Right *TreeNode
-
}
*/
// 关于树结构的问题第一时间想到递归法
// 先确定树根,再将左子树和右子树挂到树根上
func buildTree(preorder []int, inorder []int) *TreeNode {
// 如果 preorder 和 inorder 的长度不相等,那么不存在这样的树
if len(preorder) != len(inorder) {
return nil
}n := len(preorder)
// 如果长度是 0
if n == 0 {
return nil
}
// 树的前序遍历遍历到的第一个节点肯定是根节点!!!
root := TreeNode {
Val : preorder[0],
Left : nil,
Right : nil,
}
// 如果长度是 1,那么这棵树只有树根
if n == 1 {
// 加取地址符的原因是要函数要求返回指针
return &root
}// 在中序遍历数组中找到根的下标,下标左边的是左子树的所有节点
// 下标右边的是右子树的所有节点
indexOfRoot := -1
for i:= 0; i < n; i++ {
if inorder[i] == root.Val {
indexOfRoot = i
break
}
}
// 左子树的长度是
lenOfLeft := indexOfRoot// preorder[1] 就为左子树的根节点
// 我们要得到左子树的前序遍历和中序遍历
leftPreorder := preorder[1 : lenOfLeft + 1]
leftInorder := inorder[0 : indexOfRoot]
// 这样就可以构建左子树了
left := buildTree(leftPreorder, leftInorder)// preorder[lenOfLeft + 1] 为右子树的根
// 我们要得到右子树的前序遍历和中序遍历
rightPreorder := preorder[lenOfLeft + 1 : ]
rightInorder := inorder[indexOfRoot + 1 : ]
// 这样就可以构建左子树了
right := buildTree(rightPreorder, rightInorder)// 把左子树和右子树挂到树根上
root.Left = left
root.Right = rightreturn &root
}
// 最后分析一下上面程序的时间复杂度和空间复杂度
// 空间复杂度 : 因为定义了左子树和右子树各自的前序遍历和中序遍历数组
// 又递归了 n 次
// 所有空间复杂度应该为 O(n * n);
// 时间复杂度 : 递归的时间复杂度等于每次递归的时间复杂度乘以递归的次数
// 每次是 O(n),次数是 n 次
// 所以时间复杂度应该是 O(n * n);
例二:
从中序与后序遍历序列构造二叉树
例如,给出
中序遍历 inorder = [9,3,15,20,7]
后序遍历 postorder = [9,15,7,20,3]
返回如下的二叉树:
3
/
9 20
/
15 7
/**
- Definition for a binary tree node.
- type TreeNode struct {
-
Val int
-
Left *TreeNode
-
Right *TreeNode
- }
*/
func buildTree(inorder []int, postorder []int) *TreeNode {
if len(inorder)!=len(postorder){
return nil
}
if len(inorder)0{
return nil
}
n:=len(inorder)
root:=TreeNode{
Val:postorder[n-1],
Left:nil,
Right:nil,
}
if n1{
return &root
}
indexroot:=1
for i:=0;i<n;i++{
if inorder[i]==postorder[n-1]{
indexroot=i
break
}
}
leftinorder:=inorder[:indexroot]
leftpostorder:=postorder[:indexroot]
left:=buildTree(leftinorder,leftpostorder)
rightinorder:=inorder[indexroot+1:]
rightpostorder:=postorder[indexroot:n-1]
right:=buildTree(rightinorder,rightpostorder)
root.Left=left
root.Right=right
return &root
}