《劍指offer》:[58]二叉樹的下一個結點

塵虛緣_KY發表於2016-06-28
題目:給定一棵二叉樹和其中一個結點,如何找出中序遍歷順序的下一個結點?樹中的結點除了有兩個分別指向左右子結點的指標外,還有一個指向父節點的指標。
分析:這裡已經說了是中序遍歷,所以我們就以中序遍歷為例。由於是二叉樹,所以有三種情況;
(1)如果如果一個結點有右子樹,那麼它的下一個結點就是它的右子樹中最左子節點。也就是說從右子節點出發一直沿著指向左子結點的指標,我們就能找到它的
下一個結點。
(2)如果這個結點沒有右子樹,如果結點是它父節點的左子樹,則它的下一個結點就是它的父節點。
(3)如果一個結點沒有右子樹,並且是它父結點的右子樹,那麼旗下一個結點就是沿著指向父指標的結點向上找,直到找到一個是它父結點的左子結點的結點。如果這樣的結點存在則該結點的父節點就是下一個結點。

說的可能不直觀,我們用3張圖來來直觀的解釋一下上述三種情況,因為我覺得一張簡單的圖遠比長篇大論要簡潔易懂,所以我的筆記裡有很多圖,可能畫的不好!


具體實現程式碼如下:
#include <iostream>
using namespace std;
struct BinaryTree
{
	int data;
	BinaryTree *pLeft;
	BinaryTree *pRight;
	BinaryTree *pParent;
};
BinaryTree *pRoot=NULL;
int arr[7]={10,6,15,4,5,12,18};
void InSertTree(BinaryTree *root1,int data)
{
	//插入在左邊;
	if(root1->data > data)
	{
		if(root1->pLeft==NULL)
		{
			BinaryTree *node=new BinaryTree;
			node->data=data;
			node->pLeft=node->pRight=NULL;
			node->pParent=root1;
			root1->pLeft=node;
		}
		else
		{
			InSertTree(root1->pLeft,data);
		}
	}
	//插入在右邊;
	else
	{
		if(root1->pRight==NULL)
		{
			BinaryTree *node=new BinaryTree;
			node->data=data;
			node->pLeft=node->pRight=NULL;
			node->pParent=root1;
			root1->pRight=node;
		}
		else
		{
			InSertTree(root1->pRight,data);
		}
	}
}
void CreateTree(BinaryTree **root,int length,int *array)
{
	for(int i=0;i<length;i++)
	{
		if(*root==NULL)
		{
			BinaryTree *pNode=new BinaryTree;
			pNode->data=array[i];
			pNode->pLeft=pNode->pRight=NULL;
			*root=pNode;
		}
		else
			InSertTree(*root,array[i]);
	}
}
BinaryTree *GetNextNode(BinaryTree* pNode)
{
	if(pNode==NULL)
		return NULL;
	BinaryTree *pNext=NULL;
	if(pNode->pRight!=NULL)
	{
		BinaryTree *right=pNode->pRight;
		while(right->pLeft!=NULL)
			right=right->pLeft;//找到最左邊的一個節點;
		pNext=right;
	}
	else if(pNode->pParent!=NULL)
	{
		BinaryTree *pCurrent=pNode;
		BinaryTree *parent=pNode->pParent;
		while(parent!=NULL && pCurrent==parent->pRight)
		{
			pCurrent=parent;
			parent=parent->pParent;
		}
		pNext=parent;
	}
	return pNext;
}
int main()
{
	BinaryTree *result=NULL;
	CreateTree(&pRoot,7,arr);
	result=GetNextNode(pRoot);
	if(NULL==result)
		cout<<"輸入的結點不存在!"<<endl;
	else
		cout<<pRoot->data<<"的下一個結點為:"<<result->data<<endl;
	system("pause");
	return 0;
}

輸入的二叉樹是:


執行結果:



相關文章