剑指offer面试题8——二叉树的下一个节点

题目:给定一棵二叉树和其中一个结点,如何找出中序遍历序列的下一个节点?树中的节点除了有两个分别指向左右子节点的指针,还有一个指向父节点的指针。

 

思路:

       这道题开始读题目的时候可能有点懵,所以最好的办法是画一棵树,然后具体地分析问题从中找规律。比如上面这棵树的中序遍历序列为{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;



}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值