PTA L2-004 S'agit-il d'un arbre de recherche binaire? (Traversée d'arbre binaire)

L2-004 S'agit-il d'un arbre de recherche binaire? (25 points)

Un arbre de recherche binaire peut être défini de manière récursive comme un arbre binaire avec les propriétés suivantes: Pour tout nœud,

  • La valeur de clé de tous les nœuds du sous-arbre de gauche est inférieure à la valeur de clé du nœud;
  • La valeur de clé de tous les nœuds du sous-arbre de droite est supérieure ou égale à la valeur de clé du nœud;
  • Les sous-arbres gauche et droit sont des arbres de recherche binaires.

Le soi-disant "miroir" de l'arbre de recherche binaire est l'arbre obtenu après avoir permuté les positions des sous-arbres gauche et droit de tous les nœuds.

Étant donné une séquence de valeurs de clé entières, veuillez écrire un programme pour déterminer s'il s'agit du résultat de la pré-traversée d'un arbre de recherche binaire ou de son image miroir.

Format d'entrée:

La première ligne d'entrée donne un entier positif N (≤1000). La ligne suivante donne N valeurs de clé entières, séparées par des espaces.

Format de sortie:

Si la séquence d'entrée est le résultat d'un parcours de précommande d'un arbre de recherche binaire ou de son miroir, affichez d'abord OUI sur une ligne, puis sortez le résultat de la traversée ultérieure de l'arborescence sur la ligne suivante. Il y a 1 espace entre les nombres et il ne doit y avoir aucun espace supplémentaire au début et à la fin d'une ligne. Si la réponse est non, émettez NON.

Exemple d'entrée 1:

7
8 6 5 7 10 8 11

Exemple de sortie 1:

YES
5 7 6 8 11 10 8

Exemple d'entrée 2:

7
8 10 11 8 6 7 5

Exemple de sortie 2:

YES
11 8 10 7 5 6 8

Exemple d'entrée 3:

7
8 6 8 5 10 9 11

Exemple de sortie 3:

NO

Résolution de problème

Le parcours d'un arbre binaire consiste à trouver le point de division qui divise la séquence en deux sous-arbres, puis à effectuer une recherche avec dfs. Ce
problème est un arbre de recherche binaire, caractérisé par le fait que le nœud racine est supérieur à tous les sous-arbres de gauche et inférieur à ou égal à tous les sous-arbres de droite. C'est la condition pour trouver le point de coupure
, puis lister la recherche dfs.

Code

#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
using namespace std;
const int maxn = 1e3 + 2;
vector<int> v, v_back;
bool isTree = true;

void dfs(int root, int l, int r) {
    
    	// Õý³£ËÑË÷Ê÷
	if(l > r) return;

	int k = root;
	for(int i = l + 1; i <= r; i++)
		if(v[i] < v[root]) k = i;
		else break;

	for(int i = k + 1; i <= r; i++)
		if(v[i] < v[root]) {
    
    
			isTree = false;
			break;
		}

	dfs(root + 1, root + 1, k);
	dfs(k + 1, k + 1, r);
	v_back.push_back(v[root]);	//»ñÈ¡ºóÐò±éÀú 
}

void dfs_back(int root, int l, int r) {
    
    	//ËÑË÷Ê÷¾µÏñ
	if(l > r) return;

	int k = root;
	for(int i = l + 1; i <= r; i++)
		if(v[i] >= v[root]) k = i;
		else break;

	for(int i = k + 1; i <= r; i++)
		if(v[i] >= v[root]) {
    
    
			isTree = false;
			break;
		}

	dfs_back(root + 1, root + 1, k);
	dfs_back(k + 1, k + 1, r);
	v_back.push_back(v[root]);
}


int main() {
    
    
	int N;
	cin >> N;
	v.resize(N);
	for(int i = 0; i < N; i++) cin >> v[i];

	if(N == 1) {
    
    	//ÌØÅÐ 
		cout << "YES" << endl;
		cout << v[0] << endl;
		return 0;
	}

	if(v[1] < v[0])
		dfs(0, 0, v.size() - 1);
	else
		dfs_back(0, 0, v.size() - 1);

	if(isTree) {
    
    	
		cout << "YES" << endl;
		for(int i = 0; i < v_back.size(); i++) {
    
    
			if(i) cout << " ";
			cout << v_back[i];
		}
	} else
		cout << "NO" << endl;

	return 0;
}

Je suppose que tu aimes

Origine blog.csdn.net/qq_45349225/article/details/110006354
conseillé
Classement