[PTA]同じバイナリ検索ツリーですか?ツリーを構築しないのですか?

/ ************************************************* ************************************************** *******************
挿入シーケンスが与えられると、バイナリ検索ツリーを一意に決定できます。ただし、特定のバイナリ検索ツリーは、多くの異なる挿入シーケンスから取得できます。たとえば、最初は空のバイナリ検索ツリーをシーケンス{2、1、3}および{2、3、1}に従って挿入すると、同じ結果が得られます。したがって、さまざまな入力シーケンスについて、それらが同じバイナリ検索ツリーを生成できるかどうかを判断する必要があります。

入力形式:
入力には、いくつかのテストデータのセットが含まれています。データの各グループの最初の行は、2つの正の整数N(≤10)とLを示します。これらは、各シーケンスに挿入された要素の数と、チェックされるシーケンスの数です。2行目は、最初の挿入シーケンスとして、スペースで区切られたN個の正の整数を示しています。最後のL行では、各行にN個の挿入された要素があり、これらはチェック対象のLシーケンスに属しています。

簡単にするために、各挿入シーケンスが1からNへの順列であることを確認します。Nが0であることが読み取られると、マークの入力は終了し、このデータグループは処理されません。

出力形式:
チェックするシーケンスごとに、生成されたバイナリ検索ツリーが対応する初期シーケンスと同じ場合は「はい」を出力し、そうでない場合は「いいえ」を出力します。

入力例:
4 2
3 1 4 2
3 4 1 2
3 2 4 1
2 1
2 1
1 2
0
出力例:
はい
いいえ
いいえ
****************** ************************************************** ************************************************** /
最初の数//ルートノード、すべての右の部分木のシーケンス番号としてルートノードよりも大きく、それ以外の場合は、左の部分木の配列
//「抽出」のすべての右の部分木のノードは、与える:センチネルを- >右サブツリー、この時点で元のシーケンスが残っています:ルートノード->左サブツリー
//右サブツリーと左サブツリーを再帰的に並べ替え、ルートノードに接続し、番兵を解放し、
最後にシーケンスのプレオーダートラバーサルを取得します
//同じ検索ツリーが最初にトラバースされたシーケンスに基づいているかどうかを判断します(検索ツリーは最初にトラバースすることによって決定されます)

#include <iostream>
using namespace std;

typedef struct TNode* Tree;
typedef struct TNode {
    
    
	int Data;
	Tree Next;
};

Tree InputOrder(int N)
{
    
    
	int X;
	Tree root, tmp, input;
	root = new struct TNode({
    
    0, NULL});
	tmp = root;
	for (int n(0); n < N; n++)
	{
    
    
		cin >> X;
		input = new struct TNode({
    
     X, NULL });
		tmp->Next = input;
		tmp = input;
	}
	tmp = root;
	root = root->Next;
	delete tmp;
	return root;
}

Tree PreOrder(Tree T)
{
    
    
	//以第一个数为根结点,所有比根结点大的数作为右子树序列,否则为左子树序列
	//“抽取”所有右子树结点,得到:哨兵->右子树,此时原序列剩下:根结点->左子树
	//对右子树、左子树递归排序,续接到根结点,释放哨兵
	//最终得到序列的先序遍历
	Tree Root(T);
	if (T) {
    
    
		Tree Right = new struct TNode({
    
     T->Data, NULL }), RightRoot(Right);
		while(T->Next)
		{
    
    
			if (T->Next->Data > Root->Data){
    
    
				Right->Next = T->Next;
				T->Next = T->Next->Next;
				Right = Right->Next;
			}
			else
				T = T->Next;
		}
		Right->Next = NULL;	//尾部指向NULL
		Right = RightRoot->Next;	//“抽取”右子树
		delete RightRoot;	//释放哨兵

		Tree Left(Root->Next);
		Root->Next = PreOrder(Left);	//对左子树递归排序,根结点指向左子树
		for (Left = Root; Left->Next; Left = Left->Next);	//移动到左子树尾部
		Left->Next = PreOrder(Right);	//对右子树递归排序,左子树尾部指向右子树
	}
	return Root;
}

bool Compare(Tree T1, Tree T2)
{
    
    
	while (T1 && T2 && T1->Data == T2->Data)
	{
    
    
		T1 = T1->Next;
		T2 = T2->Next;
	}
	return !(T1 || T2);	//若T1, T2均为空,则所有结点均相等
}

int main()
{
    
    
	int N, L;

	cin >> N;
	while (N) {
    
    
		cin >> L;
		Tree RefOrder = InputOrder(N);
		RefOrder = PreOrder(RefOrder);
		while (L--) {
    
    
			Tree CmpOrder = InputOrder(N);
			CmpOrder = PreOrder(CmpOrder);
			if (Compare(RefOrder, CmpOrder))
				cout << "Yes\n";
			else
				cout << "No\n";
		}
		cin >> N;
	}
	return 0;
}

おすすめ

転載: blog.csdn.net/jimaofu0494/article/details/103058214