题目描述
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
思路
- 有右子树,下一结点是右子树中的最左结点;
- 无右子树,且结点是该结点父结点的左子树,则下一结点是该结点的父结点;
- 无右子树,且结点是该结点父结点的右子树,则我们一直沿着父结点追朔,直到找到某个结点是其父结点的左子树,如果存在这样的结点,那么这个结点的父结点就是我们要找的下一结点。
public class Solution {
public TreeLinkNode GetNext(TreeLinkNode pNode) {
// 1.
if (pNode.right != null) {
TreeLinkNode pRight = pNode.right;
while (pRight.left != null) {
pRight = pRight.left;
}
return pRight;
}
// 2.
if (pNode.next != null && pNode.next.left == pNode) {
return pNode.next;
}
// 3.
if (pNode.next != null) {
TreeLinkNode pNext = pNode.next;
while (pNext.next != null && pNext.next.right == pNext) {
pNext = pNext.next;
}
return pNext.next;
}
return 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)
{
if(pNode == nullptr)
return nullptr;
if(pNode->right != nullptr) {
pNode = pNode->right;
while(pNode->left != nullptr)
pNode = pNode->left;
return pNode;
}
while(pNode->next != nullptr){
if(pNode->next->left == pNode)
return pNode->next;
pNode = pNode->next;
}
return nullptr;
}
};