Arbre (en utilisant l'ordre intermédiaire et l'ordre de publication pour restaurer l'arborescence binaire, les pointeurs ne sont pas applicables)

vjudge soumettre le lien

Vous devez déterminer la valeur du nœud feuille dans un arbre binaire donné qui est le nœud terminal d'un chemin de moindre valeur de la racine de l'arbre binaire à n'importe quelle feuille. La valeur d'un chemin est la somme des valeurs des nœuds le long de ce chemin.

Entrée
Le fichier d'entrée contiendra une description de l'arborescence binaire donnée en tant que séquences de traversée inorder et postorder de cet arbre. Votre programme lira deux lignes (jusqu'à la fin du fichier) à partir du fichier d'entrée. La première ligne contiendra la séquence de valeurs associée à une traversée dans l'ordre de l'arbre et la seconde ligne contiendra la séquence de valeurs associée à une traversée post-ordre de l'arbre. Toutes les valeurs seront différentes, supérieures à zéro et inférieures à 10 000. Vous pouvez supposer qu'aucune arborescence binaire n'aura
plus de 10 000 nœuds ou moins d'un nœud.

Sortie
Pour chaque description d'arbre, vous devez afficher la valeur du nœud feuille d'un chemin de moindre valeur. Dans le cas de plusieurs chemins de moindre valeur, vous devez choisir celui avec le moins de valeur sur le nœud terminal.

Exemple d' entrée
3 2 1 4 5 7 6
3 1 2 4 5 6 7
7 8 11 3 5 16 12 18
8 3 11 7 16 18 12 5
255
255

Exemple de sortie
1
3
255

Titre:

Compte tenu de l'ordre du milieu et de l'ordre post de l'arbre, trouvez le chemin le plus court de la racine à la feuille (la somme des poids sur le chemin), et enfin sortez le poids du nœud feuille. S'il existe plusieurs chemins les plus courts, celui avec le plus petit poids de nœud feuille est sorti.

Idées de résolution de problèmes:

Tout d'abord, utilisez l'ordre du milieu et l'ordre de publication pour construire un arbre binaire, puis utilisez le parcours de précommande pour trouver le chemin le plus court et enregistrez le poids du plus petit nœud feuille.

Petits problèmes à noter:

  1. Le nombre de nœuds feuilles n'est pas indiqué. Vous devez l'utiliser pour obtenir la valeur booléenne read_list (int * a). Il n'est pas difficile de comprendre les choses en C ++.
  2. En ce qui concerne la construction de l'arbre binaire, les tableaux lch et rch sont utilisés intelligemment pour simuler l'apparence de l'arbre binaire, donc aucun pointeur n'est utilisé.
  3. Point de fonctionnement similaire ici

Code:

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<sstream>
#include<algorithm>
using namespace std;
const int maxn=10010;
const int INF=0x3f3f3f3f;
int in_order[maxn];//存中序 
int post_order[maxn];//存后序 
int lch[maxn];//存左子树 
int rch[maxn];//存右子树 
int n;//存结点个数
//把未知个数存到数组里的简单方法 
bool read_list(int *a)
{
	string line;//先看成一个字符串 
	if(!getline(cin,line))	return false;
	stringstream ss(line);
	n=0;//切记:这里不能再次定义 
	int x;
	while(ss >> x)	a[n++]=x;//将数字分割出来 
		return n>0; 
}
int build(int l1,int r1,int l2,int r2)//递归建树,l1,r1代表中序,l2,r2代表后序 
{
	if(l1>r1)	return 0;//当左大于右时停止
	int root=post_order[r2];//后序的最后一个为根
	int  p=l1;
	while(in_order[p]!=root)	p++;//找到根的位置
	int cnt=p-l1;//因为中序的根在中间,所以减去l1后恰好算出左子树的个数
	//这里cnt非常棒,一开始真的没看懂,这里考虑一下后序遍历特点:左右根
	//根已经在中序中找到,同时呢还知道根的左边有cnt个结点,当然也可知晓右子树有几个结点(这里知道一个即可) 
	//因为我们一般习惯于利用中序遍历去左右子树,其实当我们知道左右子树个数时,利用后序遍历也是可以分左右子树的 
 
	lch[root]=build(l1,p-1,l2,l2+cnt-1);//分别中序和后序的左子树 
	rch[root]=build(p+1,r1,l2+cnt,r2-1);//分别中序和后序的右子树 
	return root;
}
int best,best_sum;
void dfs(int root,int sum)//先序:根左右 
{
	sum+=root;//求权值和
	if(!lch[root]&&!rch[root])
	{
		if(sum<best_sum||(sum==best_sum&&root<best))
		{
			best=root;
			best_sum=sum;
		}
	}
	if(lch[root])
		dfs(lch[root],sum);//左
	if(rch[root])
		dfs(rch[root],sum);//右
	return; 
}
int main()
{
	while(read_list(in_order))
	{
		read_list(post_order);
		build(0,n-1,0,n-1);
		best_sum=INF;
		dfs(post_order[n-1],0);
		printf("%d\n",best);
	}
	return 0;
}

Je suppose que tu aimes

Origine blog.csdn.net/Helinshan/article/details/114548557
conseillé
Classement