码迷,mamicode.com
首页 > 其他好文 > 详细

二叉树的重建

时间:2018-12-08 19:17:12      阅读:158      评论:0      收藏:0      [点我收藏+]

标签:ftp   fun   中序遍历   range   code   特性   uil   ==   排序二叉树   

已知二叉树前序遍历和中序遍历的结果,重建二叉树

解决思路:

  • 前序遍历的结果中根节点在左右孩子的前面,左孩子在右孩子前面;中序遍历的结果中根节点在左右孩子的中间,中序遍历可以找出根节点的左子树和右子树,前序遍历的第一个节点是根节点,根据这些特性可以递归的重建二叉树

例如 pre=[1,2,4,7,3,5,6,8] mid=[4,7,2,1,5,3,8,6]

  1. 1作为根节点,左子树[4,7,2] 右子树[5,3,8,6]
  2. 左子树[4,7,2]中由于前序遍历结果2在前面,所以2位左子树根节点;同理3是右子树根节点;因此2有左子树[4,7]没右子树,3有左子树5,右子树[8,6]
  3. [4,7]由于前序遍历中4在前面,所以4是根节点,4右子树为[7];同理[8,6]中6为根节点,[8]是左子树
  4. 最终二叉树为[1,2,3,4,null,5,6,null,7,null,null,null,null,8]

         1
        2 3
       4 5 6
        7 8
  • 采用排序二叉树中序遍历为有序数组的特性

1.思路一

func main() {
    pre := []int{1, 2, 4, 7, 3, 5, 6, 8} // 根节点
    mid := []int{4, 7, 2, 1, 5, 3, 8, 6}

    root := new(node)
    reBuildTree(root, pre, mid)

    // 前序遍历
    preV(root)
    fmt.Println()
    // 中序遍历
    midV(root)
    fmt.Println()
}


// 重建左子树
func reBuildTree(root *node, pre, mid []int) {
    if len(pre) == 0 {
        return
    }

    // 确定根节点
    root.val = pre[0]
    var idx int
    for ; mid[idx] != pre[0]; idx++ {
    }
    //左子树
    leftMid := mid[:idx]
    leftPre := pre[1:len(leftMid)+1]
    if len(leftPre) > 0 {
        n := new(node)
        root.left = n
        reBuildTree(n, leftPre, leftMid)
    }

    // 右子树
    rightMid := mid[idx+1:]
    rightPre := pre[len(leftMid)+1:]
    if len(rightPre) > 0 {
        n := new(node)
        root.right = n
        reBuildTree(n, rightPre, rightMid)
    }
}

// 前序遍历
func preV(root *node) {
    if root != nil {
        fmt.Print(root.val)
        preV(root.left)
        preV(root.right)
    }

}

// 中序遍历
func midV(root *node) {
    if root != nil {
        midV(root.left)
        fmt.Print(root.val)
        midV(root.right)
    }

}

output:

12473568
47215386

2.思路二

func main() {
    pre := []int{1, 2, 4, 7, 3, 5, 6, 8} // 根节点
    mid := []int{4, 7, 2, 1, 5, 3, 8, 6}

    // 排序二叉树,中序遍历顺序递增
    sortM := make(map[int]int, len(mid))
    for i, v := range mid {
        sortM[v] = i
    }
    root := new(node)
    root.val = pre[0]
    // 按照前序遍历的顺序插入节点
    for _, v := range pre {
        insert(v, root, sortM)
    }

    // 前序遍历
    preV(root)
    fmt.Println()
    // 中序遍历
    midV(root)
    fmt.Println()
}


func insert(data int, root *node, sortM map[int]int) {
    if sortM[data] < sortM[root.val] {
        if root.left != nil {
            insert(data, root.left, sortM)
        } else {
            root.left = &node{val: data}
            return
        }
    } else {
        if root.right != nil {
            insert(data, root.right, sortM)
        } else {
            root.right = &node{val: data}
        }
    }

}

output:

12473568
47215386

二叉树的重建

标签:ftp   fun   中序遍历   range   code   特性   uil   ==   排序二叉树   

原文地址:https://www.cnblogs.com/fwdqxl/p/10049510.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!