フォーチュンは、3つの根拠は、バイナリツリーノードの後継で話題ノードを見つけるclass4-先行ノードをフランスを離れ

1.タイトル:バイナリーツリー内のノードの後継者を見つけます

以下のようにバイナリツリーノードの新しいタイプがある:
パブリッククラスノード
{
パブリックint値は、
;パブリックノードを左
右ノードのパブリック;
パブリック・ノード親;
};ノード(INTデータ)=データ{this.value公共
}
通常より二分木構造親ノードを指す親ポインタのマルチノード構造。バイナリノードタイプのノードを仮定する、ツリー親ポインタ内の各ノードは、適切にその親ノード、親NULLに最初のノードに向けられています。唯一のバイナリツリー内のノードへの1つのノードは、ノードの後続ノードを返す関数を実装します。二分木の配列先行順走査で、ノードの次ノードノードが後続ノードと呼ばれますバイナリツリー内のノードの後継者を探します。(4,2,5,1,6,3,7トラバース配列は2〜4がリレーであるリレー5は2 ...リレーノードの数は、事前の数です)

ここに画像を挿入説明

2.分析

この問題は、子孫ノードとしてのノードの先行順走査で次のノードを見つけるために本質的です。注文トラバーサル順序は左から右です。
それは右の部分木を持っている場合(1)ノードの場合、このノードの後続ノードは、その右サブツリーの左端のノードです。その理由は、順番にトラバースは、右のサブツリーと、左から右の順であることで、そのノードは、次のノードは、ツリー内の右の子ノードは、ノードです、そして右のサブツリーは、正しい順序で検索を残しています左端のノード。だから、現在のノードの後継者は、その右部分木の左端のノードです。1つの最も右の部分木は、リレー1が6であるように、左ノード6です。
現在のノードの親ノードの左サブツリーが現在のノードである場合に右の子は、存在しない場合(2)は、ノードは、その親ノードが現在のノードの後継です。ない場合は、現在のノードが親ノードとなり、探し続けます。ノードは、ノードが左のサブツリー内の最後のノードである前に、後続ノードがあることが必要である場合の理由は、ノードとして親ノードです。2,4のために、2の左サブツリー内の最後のノードである2 4左サブツリー1,5ため、中継ノードの中継ノード5は1であり、最後のノードです。
親ノードが存在しない場合(2)空の場合、後続ノードは、最後のノード7は、中継ノードではありません。境界条件には注意が必要です。

3.コアコード

(1)新しいバイナリツリーデータ構造

class Tree
{
public:
	int val;
	Tree *right;
	Tree *left;
	Tree *parent;
	Tree(int x)
	{
		this->val = x;
		this->left = NULL;
		this->right = NULL;
		this->parent = NULL;
	}
};

(2)(コンストラクタによって)ツリー内のノードを追加

	Tree *head = new Tree(1);
	head->left = new Tree(2);
	head->left->parent = head;
	head->left->left = new Tree(4);
	head->left->left->parent = head->left;
	head->left->right = new Tree(5);
	head->left->right->parent = head->left;

	head->right = new Tree(3);
	head->right->parent = head;
	head->right->left = new Tree(6);
	head->right->left->parent = head->right;
	head->right->right = new Tree(7);
	head->right->right->parent = head->right;

(3)後続ノードを見つけるために

Tree* getSuccessorNode(Tree *cur)
{
	//节点为空中继节点为空
	if(cur == NULL)
		return cur;
	//右子树存在
	if(cur->right != NULL)
	{
		cur = cur->right;
		while(cur->left!=NULL)//找右子树上最左节点
		{
			cur = cur->left;
		}
		return cur;
	}
	else//右子树不存在
	{
		//父节点为空时没有中继节点;父节点的左子树是当前节点则为中继节点
		while(cur->parent!=NULL && cur->parent->left != cur)
		{
			cur = cur->parent;
		}
		return cur->parent;
	}
}

4.完全なコード

#include <iostream>
using namespace std;

class Tree
{
public:
	int val;
	Tree *right;
	Tree *left;
	Tree *parent;
	Tree(int x)
	{
		this->val = x;
		this->left = NULL;
		this->right = NULL;
		this->parent = NULL;
	}
};

Tree* getSuccessorNode(Tree *cur)
{
	//节点为空中继节点为空
	if(cur == NULL)
		return cur;
	//右子树存在
	if(cur->right != NULL)
	{
		cur = cur->right;
		while(cur->left!=NULL)//找右子树上最左节点
		{
			cur = cur->left;
		}
		return cur;
	}
	else//右子树不存在
	{
		//父节点为空时没有中继节点;父节点的左子树是当前节点则为中继节点
		while(cur->parent!=NULL && cur->parent->left != cur)
		{
			cur = cur->parent;
		}
		return cur->parent;
	}
}

int main()
{
	Tree *head = new Tree(1);
	head->left = new Tree(2);
	head->left->parent = head;
	head->left->left = new Tree(4);
	head->left->left->parent = head->left;
	head->left->right = new Tree(5);
	head->left->right->parent = head->left;

	head->right = new Tree(3);
	head->right->parent = head;
	head->right->left = new Tree(6);
	head->right->left->parent = head->right;
	head->right->right = new Tree(7);
	head->right->right->parent = head->right;
	//打印
	Tree* succ = getSuccessorNode(head->right);
	if(succ == NULL)
		cout<<"NULL";
	else
		cout<<succ->val;
		
	system("pause");
	return 0;
}

5.追加:検索先行ノード

同様に:(1)左の部分木、左の部分木の右端のノードが現在のノードの前駆体である場合。その理由は、左側に、現在のノードとしてサブツリー・ノードは、左の部分木の右端ノードが最後のノードで左左右ため、トラバーサル順序どおりである場合、次のノードが現在のノードであるノードであるということです右端のサブツリーノードが現在のノードの前駆ノードで
現在ノードの(2)親ノードが現在のノードの前身であり、その親の右の子です。親ノードをノードとして、左から右の順序で、右の子が右にある右の順に残され、その後、親ノードは、現在のノードの前身です。

公開された51元の記事 ウォンの賞賛1 ビュー1375

おすすめ

転載: blog.csdn.net/shi_xiao_xuan/article/details/103879820