/ *********************************************** *********************************************** *******************
Dada una secuencia de inserción, un árbol de búsqueda binaria se puede determinar de forma única. Sin embargo, un árbol de búsqueda binario dado se puede obtener a partir de muchas secuencias de inserción diferentes. Por ejemplo, inserte un árbol de búsqueda binario inicialmente vacío de acuerdo con la secuencia {2, 1, 3} y {2, 3, 1} y obtenga el mismo resultado. Entonces, para las diversas secuencias de entrada, debe juzgar si pueden generar el mismo árbol de búsqueda binaria.
Formato de entrada: la
entrada contiene varios conjuntos de datos de prueba. La primera fila de cada grupo de datos da dos números enteros positivos N (≤10) y L, que son el número de elementos insertados en cada secuencia y el número de secuencias a verificar. La segunda línea da N números enteros positivos separados por espacios como secuencia de inserción inicial. En las últimas L filas, cada fila da N elementos insertados, que pertenecen a L secuencias a verificar.
Para simplificar, nos aseguramos de que cada secuencia de inserción sea una permutación de 1 a N. Cuando se lee que N es 0, se termina la entrada de la marca y este grupo de datos no debe procesarse.
Formato de salida:
Para cada secuencia a verificar, si el árbol de búsqueda binario generado es el mismo que la secuencia inicial correspondiente, envíe "Sí", en caso contrario, muestre "No".
Ejemplo de entrada:
4 2
3 1 4 2
3 4 1 2
3 2 4 1
2 1
2 1
1 2
0
Ejemplo de salida:
Sí
No
No
****************** *********************************************** *********************************************** /
// nodo raíz al primer número, todo más grande que el nodo raíz como número de secuencia del subárbol derecho, de lo contrario, la secuencia del subárbol izquierdo
// "extracción" Todos los nodos del subárbol derecho, para dar: Sentinel -> Subárbol derecho, la secuencia original se deja en este momento: nodo raíz -> subárbol izquierdo
// ordena de forma recursiva el subárbol derecho y el subárbol izquierdo, conéctese al nodo raíz, suelte el centinela y
finalmente obtenga el recorrido de preorden de la secuencia
// Juzgar si el mismo árbol de búsqueda se basa en la secuencia del recorrido de preorden (el recorrido de preorden determina el árbol de búsqueda)
#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;
}