Está en la página 1de 6

Informe Tarea IV

Recorridos en Árboles Binarios

Fecha: 31 de mayo de 2019


Profesor: Nelson Baloian
Autor: Valentina Moraga Villarroel
Correo: valemoraga98@gmail.com
Curso: CC3001-2
Introducción
Problema:

Se tiene un árbol binario como se muestra en la Figura 1 cuyos nodos no pueden tener más de 2
subárboles. Está conformado por un conjunto de nodos internos, que en la figura se pueden
observar como los que contienen una letra, y nodos externos, como los que no poseen hijos, es decir
nodos sucesores.

Figura 1: Esquema de árbol binario

Los arboles binarios son utilizados para organizar información, de manera que los elementos estén
relacionados entre sí mediante las ramas. Por lo tanto, para visualizar la información es necesario
recorrer el árbol, para visitar cada uno de sus nodos.

Existen varias maneras para recorrer un árbol binario, ya que la gran mayoría de las aplicaciones con
árbol binario son bastantes sensibles al orden de visita de los nodos.

Para este trabajo nos enfocaremos en recorrer el árbol de dos maneras. El recorrido postorden
consiste en ir, de manera recursiva en cada nodo, desde subárbol izquierdo, luego subárbol derecho
y finalmente raíz. Por otro lado, el recorrido preorden consiste en atravesar primero la raíz, luego
subárbol izquierdo y finalmente subárbol derecho.

Por ejemplo, para el árbol de la Figura 1 su recorrido postorden es:

Y su recorrido preorden:

Una característica que tiene el recorrido postorden y que se busca lograr mediante el trabajo. es
reconstruir mediante este recorrido un árbol binario. Además, se busca a partir de un árbol binario
obtener su recorrido preorden.

Solución:

Para esto se tiene un archivo de texto que contendrá el recorrido postorden, del cual
reconstruiremos el árbol y encontraremos su recorrido preorden.

Se realizaron dos funciones, generarArbol la cual reconstruye el árbol y nos retorna un puntero en
la raíz de este y generaPreorden donde a partir del árbol que se obtiene de la función anterior se
recorre según preorden.
2
Diseño de la solución

A continuación, se detalla cuales son las partes de la clase Main que resolverá dicho problema
planteado anteriormente mediante la implementación de la estructura Nodo y el uso de Stack.

Primero se creó la estructura Nodo que nos permitió formar el árbol binario. Un Nodo posee un
String info y dos Nodos hijos, izq y der.

A partir del archivo de texto que contiene el recorrido postorden, se utiliza Scanner para poder
trabajar con el recorrido como un string.

Para formar el árbol se utiliza un stack y se examina de izquierda a derecha cada elemento del string.
Como el string posee tanto punto como letras, nos ponemos en estos dos casos:

1) si el elemento es igual a punto: se crea un Nodo nodoExterno que contiene el punto y se


coloca en el stack.
2) si el elemento es una letra se crea un Nodo Letra que contenga dicha letra, luego se deben
extraer del stack los hijos de dicho nodo, los cuales son nodoExterno. Primero se le asigna
a Letra.der un Nodo y después a Letra.izq de manera de generar los hijos del Nodo Letra.
Finalmente, se apila el Nodo Letra al stack.

Este procedimiento se realiza hasta haber recorrido completamente el String recorrido, donde al
final solo tendremos apilado en el stack el Nodo raíz del árbol. Siendo este el Nodo que se retorna.

Para poder encontrar el recorrido preorden del árbol, utilizamos 2 stack los cuales nos darán al final
del proceso los nodos en orden para el recorrido en preorden del árbol.

Como queremos tener el recorrido en preorden hay que tener claro que se debe primero retornar
la raíz, luego el subárbol izquierdo y después derecho. Por lo tanto, al tener solo el puntero a la raíz
del árbol se busca ir colocando en un stack cada nodo del árbol desde la raíz, su hijo izquierdo y
luego hijo derecho, por ende se tendría en un primer stack de abajo-arriba nodo raíz, hijo izquierdo
e hijo derecho. Ahora, para formar el recorrido se desapilan los elementos del stack y se apilan en
otro de esta forma se tendría en el segundo stack de abajo-arriba hijo derecho, hijo izquierdo y la
raíz, para así cuando se desapilen se obtenga el preorden del árbol.

3
Implementación

Comenzamos creando el árbol binario, para ello se crea la función generarArbol, la cual recibe un
string, que es el recorrido postorden de un árbol binario. A partir de este recorrido, la función crea
un stack y se recorre el string. Se va llenando el stack con null si el carácter del string es un punto y
si el carácter es una letra se hace un nodo que contenga la letra. Luego a este stack, ordenado en
postorden en inversa, le aplicamos la función auxiliar colocarSimbolos. Se puede observar lo
anterior en el siguiente extracto del código:
Stack<Nodo> s = new Stack<>();
for (int r = 0; r < recorrido.length(); r++) {
char c = recorrido.charAt(r);
if (c != ' ' && c != '.') {
Nodo n = new Nodo(Character.toString(c));
s.push(n);
}
if (c == '.'){
s.push(null);
}
}
Nodo retorno=colocarSímbolos(s);

Por otro lado, La función colocarSimobolo toma un stack, el cual está ordenado de la forma dada
en la función generarArbol, descrita anteriormente, y forma el árbol a partir de dicho stack.
Finalmente, se entrega la referencia del nodo (la raíz) como vemos en el siguiente extracto del
código:
Nodo base=stack.pop();
if(base==null){
return null;
}
base.der=colocarSímbolos(stack);
base.izq=colocarSímbolos(stack);
return base;

Una vez construido el árbol binario y retornar el puntero de la raíz, se quiere encontrar el recorrido
preorden de dicho árbol. Para esto se crea la función generaPreorden, la cual recibe el puntero de
la raíz del árbol.

Se crearon 2 stack en los cuales se apilan y desapilan los nodos. Primero se apila en s1 la raíz y se
ingresa al ciclo cada vez que s1 no esté vacío.

Una vez en el ciclo, se crea un nodo momentáneo para igualarlo a un nodo que desapilaremos de
s1, y colocaremos el nodo momentaneo en el stack s2. Dado que un nodo posee dos hijos, nodo.der
y nodo.izq surgen dos casos para el nodo momentaneo: si su hijo derecho es no null, colocamos el
hijo derecho en el stack s1, y si su hijo izquierdo es no null, apilamos el hijo izquierdo en el stack s1.

De esta manera, vamos sacando el nodo tope del stack s1 y lo apilamos en el stack s2 para apilar en
s1 los hijos derecho e izquierdo de dicho nodo. La iteración está dada por el siguiente extracto de
código:

4
s1.push(raiz);
while (!s1.empty()) {
Nodo momentaneo = s1.pop();
s2.push(momentaneo);
if (momentaneo.der != null) {
s1.push(momentaneo.der);
}else if(momentaneo.info!="."){
Nodo k = new Nodo(".");
s1.push(k);
}
if (momentaneo.izq != null) {
s1.push(momentaneo.izq);
}else if(momentaneo.info!="."){
Nodo k = new Nodo(".");
s1.push(k);
}
}

Así, obtendremos en el stack s2 el recorrido en preorden invertido. Por lo tanto, se apila todo s2 en s1 para
finalmente retornar el recorrido en preorden, como se ve en el siguiente extracto del código:

String o = new String();


while (!s2.empty()) {
s1.push(s2.pop());}
while(! s1.empty()){
o += s1.pop().info ;
o+= " ";
}
return o;
}

5
Resultados y Conclusiones
Output ejemplo input00.txt

Output ejemplo input02.txt

Output ejemplo input04.txt

Output ejemplo input06.txt

Output ejemplo input08.txt

A partir de los resultados, podemos afirmar que el programa funciona correctamente frente a cada
uno de los ejemplos de input.txt . Logra a partir del string recorrido en postorden formar el árbol
binario para posteriormente encontrar y retornar el recorrido en preorden del árbol.

Finalmente, podemos reconocer que es factible y de utilidad poder pasar desde un método para
recorrer un árbol binario a otro método, como lo hemos realizado en esta tarea desde postorden a
preorden. Esto debido a que un árbol binario nos permite organizar información y por lo tanto es
importante poder visualizar o consultar los datos almacenados en el árbol.
6

También podría gustarte