1. 程式人生 > >《劍指offer》面試題8:二叉樹的下一個節點

《劍指offer》面試題8:二叉樹的下一個節點

題目:給定一顆二叉樹和其中的一個節點,如何找出中序遍歷序列的下一個節點?樹中的節點除了有兩個分別指向左、右子節點的指標,還有一個指向父節點的指標。

二叉樹的節點定義如下:

struct BinaryTreeNode
{
	int m_nValue;
	BinaryTreeNode* m_pParent;
	BinaryTreeNode* m_pLeft;
	BinaryTreeNode* m_pRight;
}

如果一個節點有右子樹,那麼它的下一個節點就是它的右子樹中最左子節點。也就是說,從右子節點出發一直沿著指向左子節點的指標,我們就能找到它的下一個節點。
接著我們分析一個節點沒有右子樹的情形。如果節點是它的父節點左子節點,那麼它的下一個節點就是它的父節點。如果一個節點既沒有右子樹,並且它還是它父節點的右子節點,那麼這種情形就比較複雜。我們可以沿著指向父節點的指標一直向上遍歷,直到找到一個是它父節點的左子節點的節點。如果這樣的節點存在,那麼這個節點的父節點就是我們要找的下一個節點。

書上的程式碼實現如下:

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=pParent->m_pParent;
		}
		pNext=pParent;
	}

	return pNext;
}

測試用例:
a.普通二叉樹(完全二叉樹;不完全二叉樹)。
b.特殊二叉樹(所有節點都沒有右子節點的二叉樹;所有節點都沒有左子節點的二叉樹;只有一個節點的二叉樹;二叉樹的根節點指標為 nullptr)。
c.不同位置的節點的下一個節點(下一個節點為當前節點的右子節點、右子樹的最左子節點、父節點、跨層的父節點等;當前節點沒有下一個節點)。