整理自剑指Offer
一:题目描述
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
二:解题分析
上图红色的是指向父结点的指针
上图二叉树中序遍历的结果为 d b h e i a f c g
中序遍历的顺序:左子树,根节点,右子树
如果一个结点有右子树,那么它的下一个结点就是它右子树中最左边的结点,如a 的下一个结点 f
如果没有右子树,如果结点是它父结点的左孩子,那么它下一个结点就是它的父结点,如 d 的下一个结点 b
如果一个结点没有右子树,并且他还是父结点的右孩子。可以沿着指向父结点的指针一直向上遍历,直到找到一个是他父结点的左孩子的结点,如果这个节点存在,那么这个节点的父结点就是我们要找的下一个结点,如i的下一个结点a ,g没有下一个结点
三:代码实现
/*
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)
{
//结点为NULL,返回NULL
if(pNode==NULL)
return NULL;
TreeLinkNode* pTemp;
//如果该结点有右子树,它的下一个结点就是右子树的最左子结点
if(pNode->right!=NULL){
pTemp=pNode->right;
while(pTemp->left!=NULL){
pTemp=pTemp->left;
}
return pTemp;
}
//如果该结点是它父结点的左孩子,下一个结点就是它的父结点
//1.根节点,没有右子树,下个节点为空
if(pNode->next==NULL)
return NULL;
//2.非根节点
if(pNode->next->left==pNode)
return pNode->next;
//如果以上两种情况均不满足,该结点是其父结点的右孩子且该结点没有右子树
//沿着父结点一直向上遍历,知道找到一个是它父结点的左子结点的结点,如果存在,该结点的父结点就是我们的下一个结点
pTemp=pNode;
while(pTemp->next){
//找到这样的结点
if(pTemp->next->left==pTemp){
return pTemp->next;
}
pTemp=pTemp->next;
}
//未找到这样的结点
return NULL;
}
};