1. Arboles en Java: Recorrido Preorden, Inorden y Postorden
El recorrido de árboles refiere al proceso de visitar de una manera sistemática, exactamente
una vez, cada nodo en una estructura de datos de árbol (examinando y/o actualizando los
datos en los nodos).
Preorden: (raíz, izquierdo, derecho). Para recorrer un árbol binario no vacío en preorden,
hay que realizar las siguientes operaciones recursivamente en cada nodo, comenzando con
el nodo de raíz:
1. Visite la raíz
2. Atraviese el sub-árbol izquierdo
3. Atraviese el sub-árbol derecho
Inorden: (izquierdo, raíz, derecho). Para recorrer un árbol binario no vacío en inorden
(simétrico), hay que realizar las siguientes operaciones recursivamente en cada nodo:
1. Atraviese el sub-árbol izquierdo
2. Visite la raíz
3. Atraviese el sub-árbol derecho
Postorden: (izquierdo, derecho, raíz). Para recorrer un árbol binario no vacío en postorden,
hay que realizar las siguientes operaciones recursivamente en cada nodo:
1. Atraviese el sub-árbol izquierdo
2. Atraviese el sub-árbol derecho
3. Visite la raíz
En general, la diferencia entre preorden, inorden y postorden es cuándo se recorre la raíz.
En los tres, se recorre primero el sub-árbol izquierdo y luego el derecho.
En preorden, la raíz se recorre antes que los recorridos de los subárboles izquierdo y
derecho
En inorden, la raíz se recorre entre los recorridos de los árboles izquierdo y derecho,
y
En postorden, la raíz se recorre después de los recorridos por el subárbol izquierdo y
el derecho
?
1
2
3
4
5
6
public class NodoArbol
{
//miembros de acceso
NodoArbol nodoizquierdo;
int datos;
NodoArbol nododerecho;
//iniciar dato y hacer de este nodo un nodo hoja
2. 7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
public NodoArbol(int datosNodo)
{
datos = datosNodo;
nodoizquierdo = nododerecho = null; //el nodo no tiene hijos
}
//buscar punto de insercion e inserter nodo nuevo
public synchronized void insertar(int valorInsertar)
{
//insertar en subarbol izquierdo
if(valorInsertar < datos)
{
//insertar en subarbol izquierdo
if(nodoizquierdo == null)
nodoizquierdo = new NodoArbol(valorInsertar);
else //continua recorriendo subarbol izquierdo
nodoizquierdo.insertar(valorInsertar);
}
//insertar nodo derecho
else if(valorInsertar > datos)
{
//insertar nuevo nodoArbol
if(nododerecho == null)
nododerecho = new NodoArbol(valorInsertar);
else
nododerecho.insertar(valorInsertar);
}
} // fin del metodo insertar
}
class Arbol
{
private NodoArbol raiz;
//construir un arbol vacio
public Arbol()
{
raiz = null;
}
//insertar un nuevo ndo en el arbol de busqueda binaria
public synchronized void insertarNodo(int valorInsertar)
{
if(raiz == null)
raiz = new NodoArbol(valorInsertar); //crea nodo raiz
else
raiz.insertar(valorInsertar); //llama al metodo
insertar
}
// EMPIEZA EL RECORRIDO EN PREORDEN
public synchronized void recorridoPreorden()
{
ayudantePreorden(raiz);
4. 101
102
103
104
105
106
107
108
109
Clase controladora:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import javax.swing.JOptionPane;
public class PruebaArbol
{
public static void main(String args [])
{
Arbol arbol = new Arbol();
int valor;
String Dato;
System.out.println("Insertando los siguientes valores: ");
Dato = JOptionPane.showInputDialog("Inserta el numero de nodos
que desea ingresar");
int n = Integer.parseInt(Dato);
for(int i = 1; i <= n; i++ )
{
Dato = JOptionPane.showInputDialog("Dame el " + i + " valor
para colocar en el Arbol");
valor = Integer.parseInt(Dato);
System.out.print(valor + " ");
arbol.insertarNodo(valor);
}
System.out.println("nnRecorrido Preorden");
arbol.recorridoPreorden();
System.out.println("nnRecorrido Inorden");
arbol.recorridoInorden();
System.out.println("nnRecorrido Postorden");
arbol.recorridoPosorden();
}
}
Output:
Insertando los siguientes valores:
5. 35 50 8 12 69 84 25 75 93 16
Recorrido Preorden
35 8 12 25 16 50 69 84 75 93
Recorrido Inorden
8 12 16 25 35 50 69 75 84 93
Recorrido Postorden
16 25 12 8 75 93 84 69 50 35
Aplicaciones de árboles binarios
Un árbol binario es una estructura de datos útil cuando se trata de hacer modelos de
procesos en donde se requiere tomar decisiones en uno de dos sentidos en cada parte del
proceso. Por ejemplo, supongamos que tenemos un arreglo en donde queremos encontrar
todos los duplicados. Esta situación es bastante útil en el manejo de las bases de datos, para
evitar un problema que se llama redundancia.
Una manera de encontrar los elementos duplicados en un arreglo es recorrer todo el arreglo
y comparar con cada uno de los elementos del arreglo. Esto implica que si el arreglo tiene
elementos, se deben hacer comparaciones, claro, no es mucho problema si es un
número pequeño, pero el problema se va complicando más a medida que aumenta.
Si usamos un árbol binario, el número de comparaciones se reduce bastante, veamos cómo.
El primer número del arreglo se coloca en la raíz del árbol (como en este ejemplo siempre
vamos a trabajar con árboles binarios, simplemente diremos árbol, para referirnos a un
árbol binario) con sus subárboles izquierdo y derecho vacíos. Luego, cada elemento del
arreglo se compara son la información del nodo raíz y se crean los nuevos hijos con el
siguiente criterio:
Si el elemento del arreglo es igual que la información del nodo raíz, entonces
notificar duplicidad.
Si el elemento del arreglo es menor que la información del nodo raíz, entonces se
crea un hijo izquierdo.
6. Si el elemento del arreglo es mayor que la información del nodo raíz, entonces se
crea un hijo derecho.
Una vez que ya está creado el árbol, se pueden buscar los elementos repetidos. Si x el
elemento buscado, se debe recorrer el árbol del siguiente modo:
Sea k la información del nodo actual p. Si entonces cambiar el nodo actual a
right(p), en caso contrario, en caso de que informar una ocurrencia duplicada y en
caso de que cambiar el nodo actual a left(p).
El siguiente algoritmo
leer numero buscado >> n
tree=makeTree(n)
while(hay numeros en el arreglo){
leeSiguienteNumero >> k
p=q=tree;
while(k!=info(p)&&q!=NULL){
p=q
if(k<info(p))
q=left(p)
else
q=right(p)
}
if(k==info(p))
despliega<<" el numero es duplicado";
else
if (k<info(p))
setLeft(p,k)
else
setRight(p,k)
}
Figura 28: Árbol binario para encontrar números duplicados
Para saber el contenido de todos los nodos en un árbol es necesario recorrer el árbol. Esto
es debido a que solo tenemos conocimiento del contenido de la dirección de un nodo a la
vez. Al recorrer el árbol es necesario tener la dirección de cada nodo, no necesariamente
7. todos al mismo tiempo, de hecho normalmente se tiene la dirección de uno o dos nodos a la
vez; de manera que cuando se tiene la dirección de un nodo, se dice que se visita ese nodo.
Aunque hay un orden preestablecido (la enumeración de los nodos) no siempre es bueno
recorrer el árbol en ese orden, porque el manejo de los apuntadores se vuelve más
complejo. En su lugar se han adoptado tres criterios principales para recorrer un árbol
binario, sin que de omita cualquier otro criterio diferente.
Los tres criterios principales para recorrer un árbol binario y visitar todos sus nodos son,
recorrer el árbol en:
preorden:
Se ejecutan las operaciones:
1. Visitar la raíz
2. recorrer el subárbol izquierdo en preorden
3. recorrer el subárbol derecho en preorden
entreorden:
Se ejecutan las operaciones:
1. recorrer el subárbol izquierdo en entreorden
2. Visitar la raíz
3. recorrer el subárbol derecho en entreorden
postorden:
Se ejecutan las operaciones:
1. recorrer el subárbol izquierdo en postorden
2. recorrer el subárbol derecho en postorden
3. Visitar la raíz
Al considerar el árbol binario que se muestra en la figura 28 usando cada uno de los tres
criterios para recorrer el árbol se tienen las siguientes secuencias de nodos:
En preorden:
En entreorden:
En postorden:
Esto nos lleva a pensar en otra aplicación, el ordenamiento de los elementos de un arreglo.
8. Para ordenar los elementos de un arreglo en sentido ascendente, se debe construir un árbol
similar al árbol binario de búsqueda, pero sin omitir las coincidencias.
El arreglo usado para crear el árbol binario de búsqueda fue
<14,15,4,9,7,18,3,5,16,4,20,17,9,14,5>
El árbol de ordenamiento es el que se muestra en la figura 29
Figura 29: Árbol binario para ordenar una secuencia de números
Para ordenar los elementos de este arreglo basta recorrer el árbol en forma de entreorden.
¿Cuál sería el algoritmo para ordenarlo de manera descendente?
Ejemplo sencillo de árbol de búsqueda binario en JAVA
import java.io.*;
class NodoBinario{
int dato;
NodoBinario Hizq, Hder;
//Constructores
NodoBinario (int Elem){
dato = Elem;
NodoBinario Hizq, Hder = null;
9. }
//Insercion de un elemento
public void InsertaBinario (int Elem){
if(Elem < dato){
if (Hizq == null)
Hizq = new NodoBinario(Elem);
else
Hizq.InsertaBinario(Elem);
}
else{
if (Elem > dato){
if (Hder == null)
Hder = new NodoBinario (Elem);
else
Hder.InsertaBinario(Elem);
}
}
}
}
//Definicion de la clase Arbol
class Arbol{
Cola Cola = new Cola();
NodoBinario Padre;
NodoBinario Raiz;
//Constructor
public Arbol(){
10. Raiz = null;
}
//Insercion de un elemento en el arbol
public void InsertaNodo(int Elem){
if(Raiz == null)
Raiz = new NodoBinario (Elem);
else
Raiz.InsertaBinario (Elem);
}
//Preorden Recursivo del arbol
public void Preorden (NodoBinario Nodo){
if(Nodo == null)
return;
else{
System.out.print (Nodo.dato + ” “);
Preorden (Nodo.Hizq);
Preorden (Nodo.Hder);
}
}
//PostOrden recursivo del arbol
public void PostOrden (NodoBinario Nodo){
if(Nodo == null)
return;
else{
PostOrden (Nodo.Hizq);
PostOrden (Nodo.Hder);
12. //Altura del arbol
public int Altura (NodoBinario Nodo){
int Altder = (Nodo.Hder == null? 0:1 + Altura (Nodo.Hder));
int Altizq = (Nodo.Hizq == null? 0:1 + Altura (Nodo.Hizq));
return Math.max(Altder,Altizq);
}
//Recorrido en anchura del arbol
public void Anchura (NodoBinario Nodo){
Cola cola= new Cola();
NodoBinario T = null;
//System.out.print (“El recorrido en Anchura es: “);
if(Nodo != null){
cola.InsertaFinal (Nodo);
while(!(cola.VaciaLista ())){
T = cola.PrimerNodo.datos;
cola.EliminaInicio();
System.out.print(T.dato + ” “);
if (T.Hizq != null)
cola.InsertaFinal (T.Hizq);
if (T.Hder != null)
cola.InsertaFinal (T.Hder);
}
}
System.out.println();
}
}
13. //Definición de la Clase NodoLista
class NodosListaA{
NodoBinario datos;
NodosListaA siguiente;
//Construtor Crea un nodo del tipo Object
NodosListaA (NodoBinario valor){
datos =valor;
siguiente = null; //siguiente con valor de nulo
}
// Constructor Crea un nodo del Tipo Object y al siguiente nodo de la lista
NodosListaA (NodoBinario valor, NodosListaA signodo){
datos = valor;
siguiente = signodo; //siguiente se refiere al siguiente nodo
}
}
//Definición de la Clase Lista
class Cola{
NodosListaA PrimerNodo;
NodosListaA UltimoNodo;
String Nombre;
//Constructor construye una lista vacia con un nombre de List
public Cola(){
this (“Lista”);
}
//Constructor
public Cola (String s){
14. Nombre = s;
PrimerNodo = UltimoNodo =null;
}
//Retorna True si Lista Vacía
public boolean VaciaLista() {
return PrimerNodo == null;
}
//Inserta un Elemento al Frente de la Lista
public void InsertaInicio (NodoBinario ElemInser){
if(VaciaLista())
PrimerNodo = UltimoNodo = new NodosListaA (ElemInser);
else
PrimerNodo = new NodosListaA (ElemInser, PrimerNodo);
}
//Inserta al Final de la Lista
public void InsertaFinal(NodoBinario ElemInser){
if(VaciaLista())
PrimerNodo = UltimoNodo = new NodosListaA (ElemInser);
else
UltimoNodo=UltimoNodo.siguiente =new NodosListaA (ElemInser);
}
//Eliminar al Inicio
public void EliminaInicio(){
if(VaciaLista())
System.out.println (“No hay elementos”);
// Restablecer las referencias de PrimerNodo y UltimoNodo
15. if(PrimerNodo.equals (UltimoNodo))
PrimerNodo = UltimoNodo = null;
else
PrimerNodo = PrimerNodo.siguiente;
}
//Elimina al final
public void EliminaFinal (){
if(VaciaLista())
System.out.println (“No hay elementos”);
// Restablecer las referencias de PrimerNodo y UltimoNodo
if (PrimerNodo.equals (UltimoNodo))
PrimerNodo = UltimoNodo = null;
else{
NodosListaA Actual =PrimerNodo;
while (Actual.siguiente != UltimoNodo)
Actual = Actual.siguiente;
UltimoNodo =Actual;
Actual.siguiente = null;
}
}
}
public class ArbolBinario{
public static void main (String[]args)throws IOException
{
BufferedReader entrada =new BufferedReader(new InputStreamReader(System.in));
//creando objeto del arbolito xD
17. Tipos de Árboles
Árboles etiquetados y árboles de expresiones:
Cuando se asocia una etiqueta, o valor, a cada nodo del árbol, a éste se le denomina
árbol etiquetado.
La etiqueta de un nodo no es el nombre del nodo, sino que es información que está
incluida en el nodo. Es posible cambiar la etiqueta del nodo sin modificar su nombre.
Un caso particular de los árboles etiquetados lo constituyen los árboles de
expresiones, utilizados para la representación de expresiones aritméticas. Las reglas
para representar una expresión mediante un árbol etiquetado son:
1.- Cada hoja está etiquetada con un operando y sólo
consta de ese operando.
2.- Cada nodo interior está etiquetado con un operador.
Ejemplo 1: la expresión a+b se representaría:
n, n1, n2 son los nombres de los nodos cuyas etiquetas se muestran al lado de los nodos
correspondientes. La operación a realizar se pone en el nodo raíz y los operandos en los
descendientes de éste.
Árboles binarios:
Es un árbol donde cada nodo tiene como máximo dos hijos.
Árboles multicamino:
Cada nodo tiene un número arbitrario de hijos y se mantiene un orden en él.
Árboles-B:
Formalmente se define un árbol-B de la siguiente manera:
18. 1. Cada página, excepto la raíz, contiene entre n y 2n elementos. Se
utilizará m para indicar el número de
elementos por página.
2. Cada página, excepto la página raíz y
las páginas hojas, tienen entre n+1 y
2n+1 descendientes.
3. La página raíz tiene al menos dos descendientes.
4. Las páginas hojas están todas al mismo nivel.
Árboles-B+:
Los árboles-B+ se han convertido en la técnica más utilizada para la organización de
archivos indexados. La principal característica de estos árboles es que todas las claves
se encuentran en las hojas (a diferencia de los árboles-B, en que las claves podían estar
en las páginas intermedias) y por lo tanto cualquier camino desde la raíz hasta alguna
de las claves tienen la misma longitud.
Formalmente se define un árbol-B+ de la siguiente manera:
1. Cada página, excepto la raíz , contiene entre n y 2n elementos.
2. Cada página, excepto la raíz, tiene entre n+1 y 2n+1 descendientes. Se utiliza
m para expresar el número de elementos por página.
3. La página raíz tiene al menos dos descendientes.
4. Las páginas hojas están todas al mismo nivel.
5. Todas las claves se encuentran en las páginas hojas.
6. Las claves de las páginas raíz e interiores se utilizan como índices.
19. Lista de foros
Inicio Foros C / C++
Arbol binario de expresiones c++
kruncher
29 de Mayo del 2008
Tengo la clase para tratar este árbol binario implementada (la pego
aqui abajo), tengo que hacer una función recursiva para crear un
árbol binario de expresiones a través de un string pero no lo
consigo...
/******************************************/
Clase Arbol binario
/******************************************/
#include <iostream>
using namespace std;
#ifndef ARBIN
#define ARBIN
template <class T>
class arbin {
public:
//constructoras
//construye un arbol binario vacio
arbin();
//crea un nuevo arbol binario a partir de un elemento y dos arboles
binarios
arbin(const T & e, const arbin<T> & ai=arbin(), const arbin<T> &
ad=arbin());
//modifica un arbin poniendo e como raiz e izqdo y dcho como hijo
izquierdo
// y derecho respectivamente
void modificar (const T & e, const arbin<T> & izqdo, const
20. arbin<T> & dcho);
//modica el arbol actual hasta obtener el arbin vacio
void vaciar();
//Copia el arbol binario actual
arbin<T> copiar();
//Devuelve el subarbol izquierdo del árbol, NULL si está vacío
arbin<T> & izquierdo() const;
//Devuelve el subarbol derecho del árbol, NULL si está vacío
arbin<T> & derecho() const;
//Devuelve el elemento de la raiz
const T & datoraiz() const;
T & datoraiz() ;
//Indica si el árbol binario está vacio
bool esvacio () const;
//recorre el arbol en preorden
void preorden() const;
//muestra el arbol en notacion infija
void notacion_infija(char) const;
//muestra el arbol en notacion infija
void notacion_funcional() const;
//Comprueba que el arbin es extendido
bool esExtendido () const;
private:
//nodo del arbol binario
struct Nodo {
T info;
arbin<T> izq;
arbin<T> der;
//constructor
Nodo (T e=T(), arbin<T> iz=arbin(), arbin<T> de=arbin()) {
info=e;
izq=iz;
der=de;
}
21. //destructor
//~Nodo();
};
typedef Nodo * PNodo;
PNodo raiz; //puntero a la raiz del árbol binario
};
/******************************************/
Main.cpp - Lo que tengo hecho de momento es
/******************************************/
arbin <char> crear_arbol (char *s, int pos){
int tam = strlen (s);
int sig=0;
if (es_entero(s[pos]))
return arbin <char> (s[pos]);
// Al final del arbol binario siempre hay 2 enteros
//return arbin <char>
(s[pos],crear_arbol(s,pos+1),crear_arbol(s,pos+2));
if (es_entero(s[pos+1]))
return arbin <char>
(s[pos],crear_arbol(s,pos+1),crear_arbol(s,pos+2));
else {
int y=pos+2;
while ((es_entero(s[y])==false) && (y <= tam))
y++;
while ((es_entero(s[y])==true) && (y <= tam))
y++;
cout << "y: " << y;
return arbin <char> (s[pos],crear_arbol(s,pos+1),crear_arbol(s,y));
}
}
Me parece que tengo mal todo, no se como plantear la solución,
alguna idea? gracias !
Creo que la cabezera correcta de la función deberia ser:
arbin <char> crear_arbol (char *s, int &pos){}
pero de momento así no he conseguido nada... Un saludo !
22. RESPONDER
kruncher
29 de Mayo del 2008
/******************************************/
Clase Arbol binario COMPLETA
/******************************************/
#include <iostream>
using namespace std;
#ifndef ARBIN
#define ARBIN
template <class T>
class arbin {
public:
//constructoras
//construye un arbol binario vacio
arbin();
//crea un nuevo arbol binario a partir de un elemento y dos arboles
binarios
arbin(const T & e, const arbin<T> & ai=arbin(), const arbin<T> &
ad=arbin());
//modifica un arbin poniendo e como raiz e izqdo y dcho como hijo
izquierdo
// y derecho respectivamente
void modificar (const T & e, const arbin<T> & izqdo, const
arbin<T> & dcho);
//modica el arbol actual hasta obtener el arbin vacio
void vaciar();
//Copia el arbol binario actual
arbin<T> copiar();
//Devuelve el subarbol izquierdo del árbol, NULL si está vacío
arbin<T> & izquierdo() const;
//Devuelve el subarbol derecho del árbol, NULL si está vacío
arbin<T> & derecho() const;
//Devuelve el elemento de la raiz
const T & datoraiz() const;
23. T & datoraiz() ;
//Indica si el árbol binario está vacio
bool esvacio () const;
//recorre el arbol en preorden
void preorden() const;
//muestra el arbol en notacion infija
void notacion_infija(char) const;
//muestra el arbol en notacion infija
void notacion_funcional() const;
//Comprueba que el arbin es extendido
bool esExtendido () const;
private:
//nodo del arbol binario
struct Nodo {
T info;
arbin<T> izq;
arbin<T> der;
//constructor
Nodo (T e=T(), arbin<T> iz=arbin(), arbin<T> de=arbin()) {
info=e;
izq=iz;
der=de;
}
//destructor
//~Nodo();
};
typedef Nodo * PNodo;
PNodo raiz; //puntero a la raiz del árbol binario
};
#endif
//IMPLEMENTACIONES
//construye un arbol binario vacio
template <class T>
arbin<T>::arbin() {
raiz=NULL;
24. }
//crea un nuevo arbol binario a partir de un elemento y dos arboles
binarios
template <class T>
arbin<T>::arbin(const T & e, const arbin<T> & izqdo, const
arbin<T> & decho) {
raiz= new Nodo(e, izqdo, decho);
}
//modifica un arbin poniendo e como raiz e izqdo y dcho como hijo
izquierdo
// y derecho respectivamente
template <class T>
void arbin<T>::modificar (const T & e, const arbin<T> & izqdo,
const arbin<T> & dcho) {
if (!esvacio()) {
raiz->info=e;
raiz->izq=izqdo;
raiz->der=dcho;
}
else cout << "Error: arbol binario vacio" << endl;
}
//modica el arbol actual hasta obtener el arbin vacio
template <class T>
void arbin<T>::vaciar() {
if (!esvacio()) {
izquierdo().vaciar();
derecho().vaciar();
delete raiz;
}
}
//Copia el arbol binario actual
template <class T>
arbin<T> arbin<T>::copiar() {
arbin i, d ;
if (!esvacio()) {
if (!izquierdo().esvacio()) i=izquierdo().copiar();
if (!derecho().esvacio()) d=derecho().copiar();
//raiz=new Nodo(raiz->info, i, d);
//return raiz;
25. arbin x (raiz->info, i, d);
return x;
}
}
//Devuelve el subarbol izquierdo del árbol, NULL si está vacío
template <class T>
arbin<T> & arbin<T>::izquierdo() const {
return raiz->izq;
}
//Devuelve el subarbol derecho del árbol, NULL si está vacío
template <class T>
arbin<T> & arbin<T>::derecho() const {
return raiz->der;
}
//Devuelve el elemento de la raiz
template <class T>
const T & arbin<T>::datoraiz() const {
return raiz->info;
}
template <class T>
T & arbin<T>::datoraiz() {
return raiz->info;
}
//Indica si el árbol binario está vacio
template <class T>
bool arbin<T>::esvacio () const {
return (raiz==NULL);
}
template <class T>
void arbin<T>::preorden() const {
if (!esvacio()) {
cout << raiz->info << " ";
izquierdo().preorden();
derecho().preorden();
}
}
26. RESPONDER
kruncher
29 de Mayo
del 2008
SOLUCION
Ya tengo hecho el programa, gracias por la ayuda. Lo pego por si os interesa.
/********************************************/
/* arbin.h
/********************************************/
//Clase ARBOL BINARIO
//Esta la clase arbol binario recursiva con el nodo dentro
#include <iostream>
using namespace std;
#ifndef ARBIN
#define ARBIN
template <class T>
class arbin {
public:
//constructoras
//construye un arbol binario vacio
arbin();
//crea un nuevo arbol binario a partir de un elemento y dos arboles binarios
arbin(const T & e, const arbin<T> & ai=arbin(), const arbin<T> & ad=arbin());
//modifica un arbin poniendo e como raiz e izqdo y dcho como hijo izquierdo
// y derecho respectivamente
void modificar (const T & e, const arbin<T> & izqdo, const arbin<T> & dcho);
//modica el arbol actual hasta obtener el arbin vacio
void vaciar();
//Copia el arbol binario actual
arbin<T> copiar();
//Devuelve el subarbol izquierdo del �rbol, NULL si est� vac
arbin<T> & izquierdo() const;
//Devuelve el subarbol derecho del �rbol, NULL si est� vac
arbin<T> & derecho() const;
//Devuelve el elemento de la raiz
27. const T & datoraiz() const;
T & datoraiz() ;
//Indica si el �rbol binario est� vacio
bool esvacio () const;
//recorre el arbol en preorden
void preorden() const;
//muestra el arbol en notacion infija
string notacion_infija() const;
//Comprueba que el arbin es extendido
bool esExtendido () const;
private:
//nodo del arbol binario
struct Nodo {
T info;
arbin<T> izq;
arbin<T> der;
//constructor
Nodo (T e=T(), arbin<T> iz=arbin(), arbin<T> de=arbin()) {
info=e;
izq=iz;
der=de;
}
//destructor
//~Nodo();
};
typedef Nodo * PNodo;
PNodo raiz; //puntero a la raiz del �rbol binario
};
#endif
//IMPLEMENTACIONES
//construye un arbol binario vacio
template <class T>
arbin<T>::arbin() {
raiz=NULL;
}
//crea un nuevo arbol binario a partir de un elemento y dos arboles binarios
28. template <class T>
arbin<T>::arbin(const T & e, const arbin<T> & izqdo, const arbin<T> & decho) {
raiz= new Nodo(e, izqdo, decho);
}
//modifica un arbin poniendo e como raiz e izqdo y dcho como hijo izquierdo
// y derecho respectivamente
template <class T>
void arbin<T>::modificar (const T & e, const arbin<T> & izqdo, const arbin<T> & dcho) {
if (!esvacio()) {
raiz->info=e;
raiz->izq=izqdo;
raiz->der=dcho;
}
else cout << "Error: arbol binario vacio" << endl;
}
//modica el arbol actual hasta obtener el arbin vacio
template <class T>
void arbin<T>::vaciar() {
if (!esvacio()) {
izquierdo().vaciar();
derecho().vaciar();
delete raiz;
}
}
//Copia el arbol binario actual
template <class T>
arbin<T> arbin<T>::copiar() {
arbin i, d ;
if (!esvacio()) {
if (!izquierdo().esvacio()) i=izquierdo().copiar();
if (!derecho().esvacio()) d=derecho().copiar();
//raiz=new Nodo(raiz->info, i, d);
//return raiz;
arbin x (raiz->info, i, d);
return x;
}
}
//Devuelve el subarbol izquierdo del �rbol, NULL si est� vac
template <class T>
arbin<T> & arbin<T>::izquierdo() const {
return raiz->izq;
29. }
//Devuelve el subarbol derecho del �rbol, NULL si est� vac
template <class T>
arbin<T> & arbin<T>::derecho() const {
return raiz->der;
}
//Devuelve el elemento de la raiz
template <class T>
const T & arbin<T>::datoraiz() const {
return raiz->info;
}
template <class T>
T & arbin<T>::datoraiz() {
return raiz->info;
}
//Indica si el �rbol binario est� vacio
template <class T>
bool arbin<T>::esvacio () const {
return (raiz==NULL);
}
template <class T>
void arbin<T>::preorden() const {
if (!esvacio()) {
cout << raiz->info << " ";
izquierdo().preorden();
derecho().preorden();
}
}
template <class T>
string arbin<T>::notacion_infija()const
{
string st;
if(!esvacio())
{
if(!izquierdo().esvacio() && !derecho().esvacio())
return st="("+izquierdo().notacion_infija()+raiz->info+derecho().notacion_infija()+")";
else
return st=raiz->info;
}
}