2021-01-09

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 = right

    return &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 n
    1{
    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

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值