题目描述
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
思路
已知题干为中序遍历,则对于以下情况,下一节点分别是:
1.如一个节点有右子树,该节点的下一节点为它的右子树的最左子节点.
如下图中b->h, a->f
2.如一个节点没有右子树,且该节点为父节点的左子节点,则该节点的下一节点为它的父节点
如下图中d->b, f->c
3.(较复杂情况)如一个节点没有右子树(图中i),且它还是其父节点的右子节点:
则我们沿着指向该节点父节点的指针一直向上遍历,直至找到一个节点(图中b)(该节点是其父节点的左子节点),则该节点的父节点(图中a)即为 所求节点的下一节点
即下图中i->a
代码
/*
struct TreeLinkNode {
int val;
struct TreeLinkNode *left;
struct TreeLinkNode *right;
struct TreeLinkNode *next; //父节点指针
TreeLinkNode(int x) :val(x), left(NULL), right(NULL), next(NULL) {
}
};
*/
class Solution {
public:
TreeLinkNode* GetNext(TreeLinkNode* pNode)
{
//判有效性
if(pNode == nullptr)
return nullptr;
//声明给定节点的下一节点
TreeLinkNode* pNext = nullptr;
//情况1:如果当前节点有右子树
if(pNode->right != nullptr)
{
//设一个指向当前节点右子节点的指针
TreeLinkNode* pRight = pNode->right;
while(pRight->left != nullptr)
{
//只要节点存在左子节点就沿左子节点下移
pRight = pRight->left;
}
pNext = pRight;
}
//下面为当前节点无右子树时
//判断是否为根节点
else if(pNode->next != nullptr)
{
//当前节点无右子树,非根节点
//设当前节点指针 和 其父节点指针 用于后续逐层向上找
TreeLinkNode* pCurrent = pNode;
TreeLinkNode* pParent = pNode->next;
//满足while条件即为情况3:当前节点无右子树,且是其父节点的右子节点
while(pParent != nullptr && pCurrent == pParent->right)
{
//逐层上移
pCurrent = pParent;
pParent = pParent->next;
}
//不执行while直接跳至此为情况2
pNext = pParent;
}
//是根节点时直接返回此时的pNext(nullptr)
return pNext;
}
};