【剑指offer】08. 二叉树的下一个结点

207 阅读1分钟

题目描述

在这里插入图片描述

// 08. 二叉树的下一个结点
// 给定一个二叉树和其中的一个结点,请找出中序遍
// 历顺序的下一个结点并且返回。注意,树中的结点不仅包
// 含左右子结点,同时包含指向父结点的指针。

题解

在这里插入图片描述

// 根据中序遍历的规则(先递归左子树取左结点,取根结点,后递归右子树取右结点),
// 我们可以倒过来讨论以下情况:

// 1,如果结点(a,b,c,e)有右子树(不管有没有左子树),
// 直接按照中序遍历规则在右子树找下一个结点

// 2,如果结点没有右子树,分两种情况:
// 一:如果结点回溯后发现自己是父结点的左子树,则下一结点就是父结点
// 二,如果结点回溯后发现自己是父结点的右子树,则继续回溯,并重新检查1 2

// 时间复杂度: 16ms 运行时间
// 空间复杂度:9868KB 占用内存
public class Solution {
    public TreeLinkNode GetNext(TreeLinkNode pNode) {
   		if (pNode == null) 
			return null;
        // 如果有右子树
        if (pNode.right != null) {
            TreeLinkNode node = pNode.right; // 进入右子树结点
            while (node.left != null) {  // 找有没有左子树
                node = node.left;  // 如果有左子树,找出最左的结点
            }
            return node;  // 有左子树返回最左的结点,没左子树直接返回
        }
        // 如果没有右子树
        else {
            while (pNode.next != null) { // 回溯
                TreeLinkNode node = pNode.next;  // 先行取父结点
				// 若当前结点为父结点的左子树结点
                if (node.left == pNode)  
                    return node;  // 直接返回父结点
                pNode = pNode.next;  // 结点回溯
            }
        }
        return null;  // 回溯无法找出关系,说明是结点已经处于整棵树最右
    }
}