下一站结点
题目
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
思路
注意是中序遍历,先画出一个例子
上图的中序遍历结果是:
d, b, h, e, i, a, f, c, g
要找出下中序遍历的下一个结点,
有三种情况:
- 当前结点有 右子树,则下一个就是右子树的最左结点,如a下一个是f,b下一个是h
- 当前节点没有右子树
- 该节点为左子节点,则下一个就是其父节点,如d下一个是b
- 该节点为右子节点,则下一个就是其 (为左子节点的祖宗节点)的父节点。如 i 下一个是 b的父节点a,g的下一个为null。
实现
/*
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)
{
TreeLinkNode* pNext = nullptr;
if(pNode->right!=nullptr)
{
TreeLinkNode* next = pNode->right;
while(next->left!=nullptr)
next = next->left;
pNext = next;
}
else if (pNode->next!=nullptr)
{
if(pNode->next->left == pNode)
{
pNext = pNode->next; //实际上,这个if可以不要,该情况可以合并到下面的else里面
}
else
{
TreeLinkNode* parent = pNode->next;
TreeLinkNode* current = pNode;
while(parent!=nullptr && parent->right==current)
{
current = parent;
parent = parent->next;
}
pNext = parent;
}
}
return pNext;
}
};
/*
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->right!=nullptr)
{
TreeLinkNode* next = pNode->right;
while(next->left!=nullptr)
next = next->left;
return next;
}
else
{
if(pNode->next==nullptr)
return nullptr;
if(pNode->next->left == pNode)
{
return pNode->next;
}
else
{
TreeLinkNode* parent = pNode->next;
while(parent->next!=nullptr && parent->next->right==parent)
parent = parent->next;
if(parent->next==nullptr)
return nullptr;
else
return parent->next;
}
}
}
};