Sunteți pe pagina 1din 17

Arboles en Java: Recorrido Preorden, Inorden y Postorden

El recorrido de rboles refiere al proceso de visitar de una manera sistemtica, exactamente una vez,
cada nodo en una estructura de datos de rbol (examinando y/o actualizando los datos en los
nodos).

Preorden: (raz, izquierdo, derecho). Para recorrer un rbol binario no vaco en preorden, hay que
realizar las siguientes operaciones recursivamente en cada nodo, comenzando con el nodo de raz:

1.

Visite la raz

2. Atraviese el sub-rbol izquierdo


3. Atraviese el sub-rbol derecho
Inorden: (izquierdo, raz, derecho). Para recorrer un rbol binario no vaco en inorden (simtrico),
hay que realizar las siguientes operaciones recursivamente en cada nodo:

1.

Atraviese el sub-rbol izquierdo

2. Visite la raz
3. Atraviese el sub-rbol derecho
Postorden: (izquierdo, derecho, raz). Para recorrer un rbol binario no vaco 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 raz

En general, la diferencia entre preorden, inorden y postorden es cundo se recorre la raz. En los
tres, se recorre primero el sub-rbol izquierdo y luego el derecho.

En preorden, la raz se recorre antes que los recorridos de los subrboles izquierdo y
derecho

En inorden, la raz se recorre entre los recorridos de los rboles izquierdo y derecho, y

En postorden, la raz se recorre despus de los recorridos por el subrbol izquierdo y el


derecho

Para que sirve un rbol binario?


Como todos sabemos un rbol binario es una estructura de datos, y
como todas, este sirve para organizar datos para facilitar su
manipulacin, ya sea el ingreso, borrado o bsqueda de datos, y
precisamente una de las principales ventajas de los rboles binarios es
la bsqueda, ya que como en muchos algoritmos de bsqueda
necesitamos tener la informacin ordenada y en nuestros rboles
binarios precisamente los datos van ingresando de forma ordenada.
Recorridos con los conocidos mtodos recursivos:

Inorden
Postorden
Preorden

Cmo se ingresa la informacin?


Como dije anteriormente, la informacin se ingresa de forma ordenada esto se
resuelve de forma muy sencilla con estos pasos:
1.
2.
3.

Se toma el dato a ingresar X


Partiendo de la raz preguntamos: Nodo == null ( o no existe ) ?
En caso afirmativo X pasa a ocupar el lugar del nodo y ya hemos
ingresado nuestro primer dato.
4.
En caso negativo preguntamos: X < Nodo
5.
En caso de ser menor pasamos al Nodo de la IZQUIERDA del que
acabamos de preguntar y repetimos desde el paso 2 partiendo del Nodo al
que acabamos de visitar
6.
En caso de ser mayor pasamos al Nodo de la DERECHA y tal cual hicimos
con el caso anterior repetimos desde el paso 2 partiendo de este nuevo
Nodo.

Nos daremos cuenta de que es un proceso RECURSIVO en el cual al final por


ms grande que sea el rbol el dato a entrar ocupar un lugar, vamos a
ejemplificar lo ya mencionado con una imagen:

Si observan con detenimiento la imagen aunque se vea algo complejo


entendern bien el funcionamiento.

Vamos a programarlo
Todo lo dicho anteriormente, vamos a programarlo ahora usando POO
con java (para que sea ms fcil de entender).
Comenzamos con la abstraccin de la informacin, tenemos que un
rbol binario est compuesto por la raz y sus nodos hijos, de la misma
forma que la misma raz no es ms que otro nodo, partiendo de esto
entonces crearemos 2 clases:
(Quiero comentar antes de esto que, aunque no soy muy partidario de
escribir los nombres de los mtodos y clases en espaol, por cuestiones
de entendimiento para muchas personas que lleguen a esta informacin,
los pondr de esa forma).

Arbol
Nodo

Para comenzar con esas clases tenemos, vamos ahora a definirlas:


Nodo.java

1 public class Nodo {


2
3

/* Declaraciones de variables */

private int valor;

5
6

private Nodo padre;

private Nodo hojaIzquierda;

private Nodo hojaDerecha;

9
1
0

/* Constructor */
public Nodo(int valor) {

1
1

this.valor = valor;

1
2

1
3

/* Setters y Getters */

1
4
1
5
1
6
1
7
1

public void setValor(int valor) {


this.valor = valor;
}

public int getValor() {


return valor;
}

8
1
9

public Nodo getPadre() {


return padre;

2
0

2
1

public void setPadre(Nodo padre) {

2
2
2
3
2
4
2
5
2
6
2
7
2
8
2
9
3
0
3
1
3
2
3
3
3 }
4
3
5
3
6
3
7

this.padre = padre;
}

public Nodo getHojaIzquierda() {


return hojaIzquierda;
}

public void setHojaIzquierda(Nodo hojaIzquierda) {


this.hojaIzquierda = hojaIzquierda;
}

public Nodo getHojaDerecha() {


return hojaDerecha;
}

public void setHojaDerecha(Nodo hojaDerecha) {


this.hojaDerecha = hojaDerecha;
}

3
8
3
9
4
0
4
1
4
2
4
3
4
4
4
5
4
6
4
7
4
8

Vamos a revisar un poco ms de cerca el cdigo.


Es una clase muy sencilla, como podemos ver nicamente tiene 4
atributos (variables) fciles de entender:

valor
hojaIzquierda
hojaDerecha

valor es el dato almacenado del propio nodo, mientras que como


recordaremos cada nodo puede tener mximo 2 hijos uno a la izquierda
y otro a la derecha, donde todos los nodos a su izquierda son menores a
el mismo y todos los nodos a su derecha son mayores a el mismo, pero
que comienzan como nulos ya que al crear un nuevo nodo, este no tiene
hijos.

Hay que tener cuidado con setValor( int valor ) Porque? pues bien, no
podemos actualizar el valor al aire ya que perderamos el orden, por lo
que tenemos un contructor:

/* Constructor */

public Nodo(int valor) {

this.valor = valor;

a partir del cual se ingresa el valor del nodo al crear una instancia del
mismo:

1 Nodo nodo = new Nodo( 1 );

Ya tenemos nuestra clase nodo lista, ahora pasemos con la clase


Arbol.java que es an ms sencilla ( en definicin ) que Nodo:
Arbol.java

1 public class Arbol {


2
3

/* Atributos */

private Nodo raiz;

5
6
7
8
9
1
0

/* Contructories */
public Arbol( int valor ) {

1
1

this.raiz = new Nodo( valor );

1
2

1
3

public Arbol( Nodo raiz ) {

1
4

this.raiz = raiz;
}

1
5

/* Setters y Getters */

1
6

public Nodo getRaiz() {

1
7

return raiz;
}

1
8
1
9

public void setRaiz(Nodo raiz) {

2
0

2
1

this.raiz = raiz;

2
2
2
3
2
4

Prcticamente por ahora lo importante es su atributo raiz del tipo


Nodo, el cual representar a todo nuestro rbol, adicionalmente he

creado constructores que pueden ser de ayuda al momento de inicializar


el rbol para crear la raz de paso.
pffff que nos hemos alargado con el post, pero an no terminamos,
acabamos apenas de definir entidades faltan todas las funciones del
mismo. vamos con ellas.
Hay que agregar mtodos a nuestra clase de Arbol para poder ingresar
nuevos nodos:

addNodo
removeNodo
recorridoPreorden
recorridoInorden
recorridoPostorden

Programando las funciones del rbol

En esta primera parte quiero abarcar al menos hasta el ingreso de


nuevos nodos, comencemos entonces.
La modificacin la haremos en nuestra clase Arbol que es la que llevar
estas funciones de control, recordemos nuestro algoritmo de insercin
que planteamos anteriormente:
1.
2.
3.

Se toma el dato a ingresar X


Partiendo de la raz preguntamos: Nodo == null ( o no existe ) ?
En caso afirmativo X pasa a ocupar el lugar del nodo y ya hemos
ingresado nuestro primer dato.
4.
En caso negativo preguntamos: X < Nodo
5.
En caso de ser menor pasamos al Nodo de la IZQUIERDA del que
acabamos de preguntar y repetimos desde el paso 2 partiendo del Nodo
al que acabamos de visitar
6.
En caso de ser mayor pasamos al Nodo de la DERECHA y tal cual
hicimos con el caso anterior repetimos desde el paso 2 partiendo de
este nuevo Nodo.

Entonces definamos nuestra funcin:

private void private void addNodo( Nodo nodo, Nodo raiz ) {

/* 2.- Partiendo de la raz preguntamos: Nodo == null ( o no existe ) ? */

if ( raiz == null ) {

/*

* 3.- En caso afirmativo X pasa a ocupar el lugar del nodo y ya

* hemos ingresado nuestro primer dato.

* ==== EDITO =====

* Muchas gracias a @Espectro por la correccin de esta lnea

*/

1
0
1
1
1
2

this.setRaiz(nodo);
}
else {
/* 4.- En caso negativo preguntamos: X < Nodo */
if ( nodo.getValor() <= raiz.getValor() ) {

1
3

/*
* 5.- En caso de ser menor pasamos al Nodo de la IZQUIERDA del

1
4

* que acabamos de preguntar y repetimos desde el paso 2


* partiendo del Nodo al que acabamos de visitar

1
5

*/

1
6

if (raiz.getHojaIzquierda() == null) {
raiz.setHojaIzquierda(nodo);

1
7

1
8

else {

1
9

2
0
2

addNodo( nodo , raiz.getHojaIzquierda() );

}
else {

/*

2
2

* 6.- En caso de ser mayor pasamos al Nodo de la DERECHA y tal


* cual hicimos con el caso anterior repetimos desde el paso 2

2
3

* partiendo de este nuevo Nodo.


*/

2
4

if (raiz.getHojaDerecha() == null) {

2
5

raiz.setHojaDerecha(nodo);
}

2
6

else {
addNodo( nodo, raiz.getHojaDerecha() );

2
7

2
8
2
9
3
0
3
1
3
2
3
3
3
4
3
5
3
6
3
7
3
8
3
9
4
0

}
}
}

public void addNodo( Nodo nodo ) {


this.addNodo( nodo , this.raiz );
}

4
1
4
2
4
3
4
4
4
5

Podemos ver que he agregado 2 funciones para insertar un nuevo nodo,


pero solo 1 de ellas es vista desde fuera, la que nosotros llamaremos,
esto es porque la funcin que usamos realmente para insertar (llamada
dentro del mtodo que vemos desde fuera de la clase [el mtodo
pblico, para quien ande perdido]) necesita una referencia de la raz a
partir de que nodo va a hacer las comprobaciones, para que al usar la
recursividad esta raz pueda ir cambiando (de acuerdo al algoritmo) y
seguir probando y comparando nodos.
Hasta ahora hemos comprendido el funcionamiento de los rboles
binarios, hemos definido las clases a usar y ya comenzamos con las
funciones bsicas del mismo, en la prxima entrada veremos como
hacer la eliminacin de un nodo para as continuar hasta terminar este
tema (que tanto dolor de cabeza le da a algunas personas) tan
interesante.
Igual que la lista, el rbol es una estructura de datos. Son muy eficientes para la
bsqueda de informacin. Los rboles soportan estructuras no lineales.

Algunos conceptos de la estructura de datos tipo rbol:


Nodo
hoja:
Es
un
nodo
sin
descendientes
(Nodo
terminal)
Ej. Nodos E ? F ? C y D.
Nodo
interior:
Es
un
nodo
que
no
es
hoja.
Ej. Nodos A y B.
Nivel de un rbol: El nodo A est en el nivel 1 sus descendientes directos estn
en
el
nivel
2
y
as
sucesivamente.
El nivel del rbol est dado por el nodo de mximo nivel.
Ej. Este rbol es de nivel 3.
Grado de un nodo: es el nmero de nodos hijos que tiene dicho nodo (solo se
tiene
en
cuenta
los
nodos
interiores)
Ej.
El
nodo
A
tiene
grado
3.
El
nodo
B
tiene
grado
2.
Los otros nodos no tienen grado porque no tienen descendientes.
Grado de un rbol: Es el mximo de los grados de todos los nodos de un rbol.
Ej. El grado del rbol es 3.
Longitud de camino del nodo x: Al nmero de arcos que deben ser recorridos
para
llegar
a
un
nodo
x,
partiendo
de
la
raiz.
La raiz tiene longitud de camino 1, sus descendientes directos tienen longitud de
camino 2, etc. En forma general un nodo en el nivel i tiene longitud de camino i.
rbol binario: Un rbol es binario si cada nodo tiene como mximo 2
descendientes.

Para cada nodo est definido el subrbol izquierdo y el derecho.


Para el nodo A el subrbol izquierdo est constituido por los nodos B, D y E. Y el
subrbol
derecho
est
formado
por
los
nodos
C
y
F.
Lo mismo para el nodo B tiene el subrbol izquierdo con un nodo (D) y un nodo en
el
subrbol
derecho
(E).
El
nodo
D
tiene
ambos
subrboles
vacos.
El nodo C tiene el subrbol izquierdo vaco y el subrbol derecho con un nodo (F).
rbol binario perfectamente equilibrado: Si para cada nodo el nmero de nodos
en el subrbol izquierdo y el nmero de nodos en el subrbol derecho, difiere
como
mucho
en
una
unidad.
Hay que tener en cuenta todos los nodos del rbol.
El rbol de ms arriba es perfectamente equilibrado.
Ej.
rbol
que
no
es
perfectamente
equilibrado:
El nodo A tiene 3 nodos en el subrbol izquierdo y solo uno en el subrbol
derecho, por lo que no es perfectamente equilibrado.

rbol binario completo: Es un rbol binario con hojas como mximo en los
niveles
n-1
y
n
(Siendo
n
el
nivel
del
rbol)
Los dos rboles graficados son completos porque son rboles de nivel 3 y hay
nodos hoja en el nivel 3 en el primer caso, y hay nodos hoja en los niveles 3 y 2 en
el
segundo
caso.
Ej. rbol binario no completo:

Hay nodos hoja en los niveles 4, 3 y 2. No debera haber nodos hojas en el nivel 2.
rbol binario ordenado: Si para cada nodo del rbol, los nodos ubicados a la
izquierda son inferiores al que consideramos raz para ese momento y los nodos
ubicados a la derecha son mayores que la raz.

Ej.
Analicemos
si
se
trata
de
un
rbol
binario
ordenado:
Para
el
nodo
que
tiene
el
50:
Los nodos del subrbol izquierdo son todos menores a 50? 8, 25, 30 Si
Los nodos del subrbol derecho son todos mayores a 50? 70 Si.
Para
el
nodo
que
tiene
el
25:
Los nodos del subrbol izquierdo son todos menores a 25? 8 Si
Los nodos del subrbol derecho son todos mayores a 25? 30 Si.
No hace falta analizar los nodos hoja. Si todas las respuestas son afirmativas
podemos luego decir que se trata de un rbol binario ordenado.

S-ar putea să vă placă și