0
点赞
收藏
分享

微信扫一扫

[算法]剑指offer p6 重建二叉树 golang

梦幻之云 2022-02-11 阅读 56

[算法]剑指offer p6 重建二叉树 golang

题目

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

type BTree struct {
	Data int
	Left *BTree
	Right *BTree
}

image-20220211164646190

思路

举例发现规律解决问题

  • 前序遍历: 当前节点 -> 左子树 -> 右子树
  • 中序遍历: 左子树 -> 当前节点 -> 右子树

我们可以发现就是左子树和当前节点的打印顺序不一样

image-20220211170712081

前序遍历的第一个节点是根节点1

在中序遍历中1的左边是左子树,右边是右子树

前序遍历 2

中序遍历的 2 的左边是 2 的左子树, 右边没有就是没有右子树

image-20220211171108510

前序遍历 4

中序遍历的 4 的右边是 7 为 4 的右子树

image-20220211171336763

前序遍历 7

7 没有左子树也没有右子树旧返回

image-20220211171441437

右子树也是同理的

代码(golang)

//二叉树
type BTree struct {
	Data  int
	Left  *BTree
	Right *BTree
}
//通过前序遍历顺序和中序遍历循序构建二叉树返回根节点
func BuildBTree(preOrder []int, midOrder []int) (root *BTree) {
	// 参数处理
	if len(preOrder) == 0 || len(midOrder) == 0 || len(preOrder) != len(midOrder) {
		fmt.Printf("%s\n", "参数错误")
		return
	}
	//todo 参数处理,2个数组元素需要一致
	preIndex := 0
	return buildBTree(preOrder, midOrder, &preIndex)
}

//递归
//preIndex 是前序遍历的当前遍历节点
func buildBTree(preOrder []int, midOrder []int, preIndex *int) (root *BTree) {
	//如果midOrder只有一个节点就返回该节点,没有节点就返回nil
	if len(midOrder) == 0 {
		return nil
	}
	midVal := preOrder[*preIndex]
	*preIndex++
	//赋值该节点
	root = &BTree{Data: midVal}
	if len(midOrder) == 1 {
		return
	}
	//找到中序遍历的节点的值和 midIndex
	midIndex := 0
	for i := 0; i < len(midOrder); i++ {
		if midVal == midOrder[i] {
			midIndex = i
			break
		}
	}
	//切割midOrder左边并递归
	root.Left = buildBTree(preOrder, midOrder[:midIndex], preIndex)
	if midIndex != len(midOrder) {
		//todo 切割arr溢出
		//切割midOrder右边边并递归
		root.Right = buildBTree(preOrder, midOrder[midIndex+1:], preIndex)
	}
	return
}

测试

//返回 exampel1 二叉树实例
func E1Except() (root *BTree) {
	//构造数据
	E1 := &BTree{Data: 1}
	E2 := &BTree{Data: 2}
	E3 := &BTree{Data: 3}
	E4 := &BTree{Data: 4}
	E5 := &BTree{Data: 5}
	E6 := &BTree{Data: 6}
	E7 := &BTree{Data: 7}
	E8 := &BTree{Data: 8}
	E1.Left = E2
	E2.Left = E4
	E4.Right = E7
	E1.Right = E3
	E3.Left = E5
	E3.Right = E6
	E6.Left = E8
	return E1
}
func TestP6(t *testing.T) {
	examples := []struct {
		preOrder []int
		midOrder []int
		except   *BTree
	}{
		{
			preOrder: []int{1, 2, 4, 7, 3, 5, 6, 8},
			midOrder: []int{4, 7, 2, 1, 5, 3, 8, 6},
			except:   E1Except(),
		},
		{
			preOrder: []int{},
			midOrder: []int{},
			except:   nil,
		},
	}
	for _, e := range examples {
		assert.Equal(t, e.except, BuildBTree(e.preOrder, e.midOrder))
	}
}

TODO:

  • 检查前序遍历和中序遍历的数据问题
举报

相关推荐

0 条评论