问题
一个二叉树,其节点的结构是这样的
type TreeNode struct {
Val interface{}
Left *TreeNode // 左孩子
Right *TreeNode // 右孩子
Parent *TreeNode // 父节点
}
给你这个二叉树的任意一个节点,请找到该节点的按中序遍历顺序的下一个节点。也就是实现该函数
func GetNextNode(node *TreeNode) *TreeNode
注意:输入中并没有二叉树根节点。
分析
中序遍历过程中,二叉树的某个节点(设该节点为X)的下个节点,有这样几种情况
- X有右子树,那么右子树的“最左最下”节点就是下一个节点。
- X没有右子树,X是其父节点P的左孩子,那么P就是下一个节点。
- X没有右子树,也不是其父节点的左孩子,此时就需要从X遍历其祖先节点,找到这样的一个祖先节点A——A是其父节点P的左孩子,则P就是下一个节点。
实现
在上述分析基础上,再简化,得到如下代码
func GetNextNode(node *TreeNode) *TreeNode {
if node == nil {
return nil
}
if node.Right != nil {
return getLeftMost(node.Right)
}
curr := node
for curr != nil && curr.Parent != nil {
if curr == curr.Parent.Left {
return curr.Parent
}
curr = curr.Parent
}
return nil
}
// 找到以root为根节点的某子树的最左最下节点
func getLeftMost(root *TreeNode) *TreeNode {
curr := root
for curr != nil && curr.Left != nil {
curr = curr.Left
}
return curr
}
下面是测试代码
package main
import (
"fmt"
)
func main() {
{
n1 := &TreeNode{Val: 1}
n2 := &TreeNode{Val: 2}
n1.Left = n2
n2.Parent = n1
n3 := &TreeNode{
Val: 3,
}
n4 := &TreeNode{
Val: 4,
Parent: n3,
}
n3.Left = n4
n2.Right = n3
n3.Parent = n2
// n2有右子树
t.Log(GetNextNode(n2))
}
{
n1 := &TreeNode{Val: 1}
n2 := &TreeNode{Val: 2}
n1.Left = n2
n2.Parent = n1
// n2没有右孩子。
// 它是其父节点的左孩子。
fmt.Println(GetNextNode(n2))
}
{
// n1没有右孩子,也没有父节点。
n1 := &TreeNode{Val: 1}
fmt.Println(GetNextNode(n1))
}
{
n1 := &TreeNode{Val: 1}
n2 := &TreeNode{Val: 2}
n1.Left = n2
n2.Parent = n1
n3 := &TreeNode{Val: 3}
n2.Right = n3
n3.Parent = n2
// n3没有右孩子,
// 它不是其父节点的左孩子。
fmt.Println(GetNextNode(n3))
}
}