Está en la página 1de 21

Árboles

Programación III.
[Programación III ]- [1]
Objetivos

- Repasar los conceptos de


árboles.
- Revisar aplicaciones con
árboles de expresión.
- Revisar los diferentes
recorridos en un árbol

[2]
Estructura de un árbol binario
o Al igual que las estructuras de datos anteriores
(Listas, pilas y colas), los árboles se construyen
haciendo uso del concepto de nodo, para almacenar
el valor y dos punteros, el primero representará el
hijo izquierdo y el segundo el hijo derecho.

Izquierdo Dato Derecho

Izquierdo Dato Derecho

[3]
Estructura de un árbol binario
o Representación en C/C++.
typedef struct nodo *puntero; class nodo{
struct nodo{ int dato;
int dato; nodo *izquierdo;
puntero izquierdo; nodo *derecho;
puntero derecho; friend class arbol;
}; };

[4]
Operaciones con arboles binarios:
o Determinar su altura.
o Determinar el número de elementos.
o Hacer una copia.
o Visualizar el árbol binario en pantalla.
o Determinar si dos árboles binarios son idénticos.
o Borrar (Eliminar el árbol).
o Si es un árbol es de expresión, evaluar la expresión.
o Si es un árbol es de expresión, obtener la forma de
paréntesis de la expresion.
[5]
Árboles de expresión
o Una aplicación muy importante de los árboles binarios son
los árboles de expresión. Una expresión es una secuencia
de tokens (componentes del léxico), que siguen una reglas
prescritas. Un token puede ser o bien un operando o bien
un operador.
+
a * ( b + c) + d
* d

a +

b c

[6]
Un árbol de expresión, es un árbol binario con las
siguientes propiedades:
o Cada hoja es un operando.

o Los nodos raíz e internos son operadores

o Los subárboles son subexpresiones en las que el


nodo raíz es un operador.

[7]
+

( A * B) + C * C

A B

Obsérvese que los paréntesis no se almacenan en el


árbol pero están implicados en la forma del árbol. Si se
supone que todos los operadores tienen dos operandos,
se puede representar una expresión por un árbol
binario cuya raíz contiene un operador y cuyos
subárboles izquierdo y derecho son los operandos
izquierdos y derechos respectivamente.
[8]
Ejercicios
o Escribir la expresión del siguiente árbol.
*

+ -

X Y A B

o Dibujar el árbol de la siguiente expresión.


(X + (Y * Z)) * (A - B)

[9]
Algoritmo para árbol de expresión
o La primera vez que se encuentra un paréntesis a la izquierda, crea un
nodo y lo hace en el raíz. A éste se le llama nodo actual y se sitúa su
puntero en la pila.
o Cada vez que se encuentre un nuevo paréntesis a la izquierda, crear un
nuevo nodo. Si el nodo actual no tiene un hijo izquierdo, hacer al nuevo
nodo el hijo izquierdo; en caso contrario, hacerlo el hijo derecho. Hacer
al nuevo nodo el nodo actual, y situar su puntero en una pila.
o Cuando se encuentra un operando, crear un nuevo nodo y asignar el
operando a su campo de datos. Si el nodo actual no tiene hijo izquierdo,
hacer al nuevo nodo el hijo izquierdo. Caso contrario hacerlo hijo
derecho.
o Cuando se encuentra un operador, sacar un puntero de la pila y situar el
operador en el campo de datos del nodo del puntero.
o Ignorar paréntesis derecho y blancos.
[10]
Recorrido en un árbol
o Para visualizar o consultar los datos almacenados en un
árbol se necesita recorrer el árbol o visitar los nodos del
mismo. Al contrario que en las listas enlazadas, los árboles
binarios no tienen realmente un primer valor, un segundo,
un tercero, etc. ¿Se puede afirmar que el raíz viene el
primero, pero quién viene a continuación? Existen
diferentes métodos de recorrido del árbol.
o Recorrido de un árbol binario requiere que cada nodo del
árbol sea procesado(visitado) una vez y sólo una en una
secuencia predeterminada. Existen dos enfoques generales
para la secuencia de recorrido, profundidad y anchura.
[11]
Recorrido en un árbol
o Recorrido por profundidad, el proceso exige un camino
desde el raíz a través de un hijo, al descendiente mas lejano
del primer hijo antes de proseguir a un segundo hijo. En
otras palabras, en el recorrido en profundidad, todos los
descendientes de un hijo se procesan antes del siguiente
hijo.
o Recorrido en anchura, el proceso se realiza
horizontalmente desde el raíz a todos sus hijos, a
continuación a los hijos de sus hijos y así sucesivamente
hasta que todos los nodos han sido procesados. En otras
palabras, en el recorrido en anchura cada nivel se procesa
totalmente antes que comience el siguiente nivel.
[12]
Recorrido en un árbol
o Dado un árbol binario que consta de un raíz, un subárbol
izquierdo y un subárbol derecho se pueden definir tres
tipos de secuencia de recorrido.
1 2 3

2 3 1 3 1 2

Preorden Enorden Postorden


NID IND IDN

[13]
Recorrido Preorden
El recorrido preorden (NID) conlleva los siguientes pasos, en
los que el raíz va antes que los subárboles:
n Recorrer el raíz (N)
n Recorrer el subárbol izquierdo (I)
n Recorrer el subárbol derecho (D)
Dados las características recursivas de los árboles, el
algoritmo de recorrido tiene naturaleza recursiva. Primero, se
procesa el raíz; a continuación, el subárbol izquierdo, y, por
último, el subárbol derecho. Para procesar el subárbol
izquierdo, se hace una llamada recursiva al procedimiento
preorden, y luego se hace lo mismo con el subárbol derecho.
[14]
Recorrido Preorden
A
A-B-D-E-C-F-G
B C

Código fuente en C++


D E F G
void preorden(Nodo *p){
if (p){
cout << p->valor << “-”;
preorden (p->izda);
preorden (p->dcha);
}
}

[15]
Recorrido Enorden
El recorrido enorden (inorder) procesa primero el subárbol
izquierdo, después el raíz y a continuación el subárbol
derecho. El significado de in es que la raíz se procesa entre los
subárboles. Si el árbol no está vacío, el método implica los
siguientes pasos.
n Recorrer el subárbol izquierdo (I)
n Recorrer el raíz (N)
n Recorrer el subárbol derecho (D)

[16]
Recorrido Enorden
A
D-B-E-A-F-C-G
B C

Código fuente en C++


D E F G
void enorden(Nodo *p){
if (p){
enorden (p->izda);
cout << p->valor << “-”;
enorden (p->dcha);
}
}

[17]
Recorrido Postorden
El recorrido postorden (IDN) procesa el nodo raíz (post)
después de que los subárboles izquierdo y derecho se han
procesado. Se comienza situándose en las hojas más a la
izquierda y se procesa. A continuación , se procesa su subárbol
derecho. Por último se procesa el nodo raíz.
n Recorrer el subárbol izquierdo (I)
n Recorrer el subárbol derecho (D)
n Recorrer el raíz (N)

[18]
Recorrido Postorden
A
D-E-B-F-G-C-A
B C

Código fuente en C++


D E F G
void postorden(Nodo *p){
if (p){
postorden (p->izda);
postorden (p->dcha);
cout << p->valor << “-”;
}
}

[19]
[20]
Bibliografía
http://c.conclase.net/edd/?cap=006#inicio
http://es.wikipedia.org/wiki/%C3%81rbol_(inform
%C3%A1tica)
http://www.algoritmia.net/articles.php?id=17
Programación en C++, 1ª Edición, Luis Joyanes
Aguilar, capitulo 21

[21]

También podría gustarte