题目:给定一棵二叉树和其中一个结点,如何找出中序遍历序列的下一个节点?树中的节点除了有两个分别指向左右子节点的指针,还有一个指向父节点的指针。
思路:
这道题开始读题目的时候可能有点懵,所以最好的办法是画一棵树,然后具体地分析问题从中找规律。比如上面这棵树的中序遍历序列为{d,b,h,e,i,a,f,c,g},可以发现,如果一个节点它是有右子树的,比如b和c,那么它们中序序列的下一个节点就是右子树最左边的节点b的右子树的最左边的节点为h,c的右子树的只有一个节点g,那就是g。如果一个节点它是没有右子树的,那么分为两种情况来考虑,一种情况是它是它父节点的右子树,这个情况比较复杂一点,需要向上回溯,直到找到一个祖先节点,该祖先节点是它父节点的左节点,那么这个父亲结点就是我们要找的下一个节点。比如i找到的就是a,从g开始找,找不到,那么节点g没有下一个节点。中序遍历下一个节点考虑的是右子树和父节点,换做是先序遍历,一个节点有左子树,那么就是左子树的根节点,如果没有左子树那么就右子树的根节点,如果左右子树都没有,那么如果它是父节点的左孩子,那么就要找父节点的右孩子,如果父节点没有右孩子,那么就网上回溯,直到找到一个有右孩子的节点,如果找不到那么它就没有下一个节点。如果它是父节点的左孩子,那么需要向上回溯,找到一个有右孩子的节点,如果找不到那么它就没有下一个节点。
代码:
struct BinaryTreeNode {
int m_nValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_pRight;
BinaryTreeNode* m_pParent;
};
BinaryTreeNode* GetNext(BinaryTreeNode* pNode)
{
if (pNode == nullptr)//输入为空指针的时候要特判一下
return nullptr;
BinaryTreeNode* pNext=nullptr;//指针要初始化一下
if (pNode->m_pRight != nullptr)
{
BinaryTreeNode*pRight = pNode->m_pRight;
while (pRight->m_pLeft!=nullptr)
{
pRight = pRight->m_pLeft;
}
pNext=pRight;
}
else if (pNode->m_pParent != nullptr)
{
BinaryTreeNode*pCurrent = pNode;
BinaryTreeNode*pParent = pNode->m_pParent;
while (pParent!=nullptr && pCurrent==pParent->m_pRight)
{
pCurrent = pParent;
pParent = pCurrent->m_pParent;
}
pNext = pParent;
}
return pNext;
}
复习:
第一种情况就是该节点有右子树,中序遍历的下一个节点就是右子树的根节点,如果没有右子树就需要往上回溯,如果该节点是父节点的左子节点,那么下一个节点就是父节点,如果不是就继续往上回溯去找一个祖先节点,该祖先节点是它父节点的左子节点,如果找不到就为nullptr,说明该节点是中序遍历的最后一个节点,后面的两个小点可以合并考虑,这个要注意。
二刷代码:
struct BinaryTreeNode
{
int m_nValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_Right;
BinaryTreeNode* m_pParent;
};
BinaryTreeNode* GetNext(BinaryTreeNode* pNode)
{
if (pNode == nullptr)
return nullptr;
BinaryTreeNode*pNext = nullptr;
if (pNode->m_Right != nullptr)
{
BinaryTreeNode* pRight = pNode->m_Right;
while (pRight->m_pLeft!=nullptr)
{
pRight = pRight->m_pLeft;
}
pNext = pRight;
}
else if (pNode->m_pParent != nullptr)
{
BinaryTreeNode* pCurrent = pNode;
BinaryTreeNode* pParent = pNode->m_pParent;
while (pParent!=nullptr&&pCurrent==pParent->m_Right)
{
pCurrent = pParent;
pParent = pParent->m_pParent;
}
pNext = pParent;
}
return pNext;
}