M1 Programacion
M1 Programacion
M1 Programacion
ÁR B OLES
Introducción
1. ÁR B OLES
Introducción
Verify to continue
We detected a high number of errors from your
connection. To continue, please confirm that
you’re a human (and not a spambot).
En este módulo veremos cómo almacenar datos en forma ordenada, para la representación de
expresiones aritméticas, dado que una, con dos operandos, la podemos representar como un árbol cuya
raíz sea el operador y sus subárboles sean los operandos. Por tal motivo, crear un mal funcionamiento
del algoritmo puede borrar información equivocada o generar un desbordamiento de datos básicos.
Objetivos del módulo
Resolver problemas complejos entendiendo las estructuras de datos y avanzando en los saberes
previos a través de la programación orientada a objetos.
C O NT I NU A R
28
En esta unidad abordaremos el concepto de árbol, sus características y utilizaciones. También veremos los
alcances de esta estructura no lineal, acompañados de ejemplos para su mejor comprensión.
Es importante tener en cuenta que las estructuras de datos, así como arreglos y registros son estáticas,
mientras que las listas y los árboles son dinámicas.
Es una estructura de datos no lineal, hasta ahora se vieron colas, pilas y listas. Estas eran estructuras de
datos lineales; ya que al tener un puntero siguiente podíamos recorrer la lista de una sola forma. En cambio,
en el árbol, no tendremos un puntero, sino, dos: uno para la derecha y otro para la izquierda. Es decir,
podremos recorrer el árbol de diferentes formas. Es por ello que, a los árboles, se los conoce como
estructuras dinámicas y no lineales.
A cada nodo “H”, excepto la raíz, le llega una arista de otro nodo (“P” padre de “H” y “H”, uno de
los hijos de “P”).
A su vez, el conjunto finito de líneas, que conectan los nodos, son lo que se denomina como ramas.
Características
4 Se dice que todos los nodos que son descendientes directos de un mismo nodo (padre), son
hermanos.
5 Todo nodo que no tiene ramificaciones (hijos) se le conoce con el nombre de terminal u hoja.
6 Todo nodo que no es raíz, ni terminal u hoja, se conoce con el nombre de interior.
Teniendo en cuenta estas características, construyamos nuestro primer nodo con el nombre A,
denominado raíz.
Este primer nodo puede tener hijos, tanto a la derecha como a la izquierda. Por ende, los nodos que
derivan de la raíz, se denominan hijos.
Ya hemos visto qué se entiende por raíz, nodo hijo y hoja. Ahora, observemos cómo se ve esto en un árbol
con números enteros:
Figura 5. Árbol. Elaboración propia.
El 16 es la raíz, el 8 y el 24 son los nodos hijo y el 7, 13 y 21 son las hojas porque ya no tienen hijos.
Estructuras de datos
La siguiente imagen les permitirá observar el alcance de lo que venimos viendo a lo largo del módulo y hacia
dónde apuntamos en la programación.
LINEALES
Figura 1. Estructuras de datos lineales y no lineales. Elaboración propia.
C O NT I NU A R
38
Para definir una estructura nodo necesitamos un nodo que apunte a otros nodos. En la figura 6, definimos
una estructura de este tipo con tres campos.
En el primero de ellos, colocamos un dato que es del tipo entero (el n° 16) y es lo que se denomina como raíz.
Puede apuntar tanto a la derecha como a la izquierda. Por tal motivo, necesitamos dos punteros, uno para
cada lado. En este caso lo usamos para un árbol binario, pero si fuese para un árbol ternario que tenga tres o
más hijos, necesitaríamos más punteros.
C O NT I NU A R
48
Los árboles presentan determinadas propiedades. A continuación, veremos qué implica cada una de ellas.
Longitud de camino:
Es el número de ramas que uno tiene que pasar para llegar de un nodo a otro, generalmente se comienza del
nodo raíz. Por ejemplo: si queremos saber la longitud de camino del nodo 7, debemos contar la cantidad de
ramas. Es decir, cada una de las líneas o flechas desde la raíz hasta el número 7 (ver Figura 7). En este caso,
la longitud de camino para encontrar el nodo 7, es 3.
Altura de un nodo:
Si queremos calcular la altura del nodo 24, debemos observar desde las hojas y hacia arriba. En este caso,
la altura es 2 (ver Figura 9).
Figura 9. Altura de un nodo. Elaboración propia.
Profundidad de un nodo:
La profundidad se ve desde arriba. Es decir, desde la raíz y hacia abajo. Por lo tanto, para hallar la
profundidad de un nodo, debemos tener en cuenta los niveles. Por ejemplo: en la figura 10, la raíz es el nivel 0
del árbol y profundidad del nodo 19 es igual a 2; ya que se encuentra en dicho nivel.
Figura 10. Profundidad de un nodo. Elaboración propia.
C O NT I NU A R
58
Se caracterizan por estar al mismo nivel y, además, tener en común el mismo padre. Por ejemplo: en la
figura 11, los nodos hermanos son el 3 y el 13 o el 8 y el 24; ya que son hijos del 8, respectivamente. Si bien
el 13 y el 19, comparten la misma línea, no comparten el mismo padre.
Por otro lado, el orden un árbol será la máxima cantidad de hijos que puede tener cada nodo. Por ejemplo: si
un árbol es del orden 2, esto significa que puede tener 0, 1 o 2 hijos. Este tipo de árbol es conocido como
binario.
C O NT I NU A R
68
Un árbol binario es un árbol de orden 2. Se conoce el nodo de la izquierda como hijo izquierdo y el nodo de la
derecha como hijo derecho.
Un árbol ordenado es aquel en el que las ramas de los nodos del árbol están ordenadas. Teniendo en cuenta
esto, podemos decir que un árbol binario es un árbol ordenando que puede tener cuando máximo dos
subárboles denominados: subárbol izquierdo y subárbol derecho. Este tipo de árbol, presenta las siguientes
características:
El nodo A es antecesor del nodo B (y recíprocamente el nodo B es descendiente del nodo A), si
A es el padre de B o el padre de algún ancestro de B.
Dos nodos son hermanos si son hijos izquierdos y derecho del mismo padre.
Un árbol binario es, además, una estructura recursiva y se divide en tres subconjuntos distintos:
1 Nodo raíz.
2 Subárbol izquierdo.
3 Subárbol derecho.
En el árbol de la figura 12, tenemos tres partes: la raíz (indicado con la letra R), de allí, se desprende un
subárbol izquierdo (indicado con la letra I) y un subárbol derecho (indicado con la letra D).
Decimos que es recursivo porque si separamos la raíz, nos queda de la siguiente manera:
Figura 13. Raíz y subárbol. Elaboración propia.
Si observamos la figura 13, podemos decir que el subárbol izquierdo es un árbol binario al igual que el
subárbol derecho.
Árbol lleno
–
Todos sus nodos, salvo los últimos, tienen 2 hijos (ver Figura 14).
Árbol degenerado
–
Es un árbol en el que todos los nodos tienen solamente un subárbol excepto el último (figura 16).
Nuevo_nodo=5; (al ingresar este nodo, lo colocamos del lado izquierdo porque los numero menores,
en este caso 10, se colocan de ese lado).
Nuevo_nodo=8 (8 es menor a 10, por lo tanto, se coloca del lado izquierdo, pero es mayor que 5,
entonces, se coloca del lado derecho).
Nuevo_nodo=20 (20 es mayor a 10 y mayor a 15 y, por este motivo, lo colocamos del lado derecho).
Primeramente, debemos crear un nodo con tres campos, tal como se observa en la figura 18. El primero es el
campo DATO y es donde se almacena el dato que queremos colocar. Este es del tipo entero y cuenta con un
puntero hacia el hijo derecho y otro hacia el hijo izquierdo. Luego, se crea el nodo como nuevo_nodo y se le
asignan los tres campos del nodo. Como el nodo derecho e izquierdo son nuevos, le asignamos NULL.
Es importante tener en cuenta ciertos aspectos al momento de insertar un árbol. Por ejemplo: el lado
izquierdo, nos indica si el nodo se encuentra vacío. En cambio, el lado derecho es para saber si tiene un nodo
o más de uno. Recordemos que los datos, dependiendo del valor que tengan, se colocan en el lado izquierdo
o derecho.
Figura 19. Aspectos a tener en cuenta al insertar un nodo en el árbol. Elaborada a partir de
Ingeniería de Software (s/f).
En caso de crear un nuevo nodo en C++, deberíamos realizarlo tal como se muestra en las siguientes
imágenes.
Figura 20. Creación de un nuevo nodo en C++ (Paszniuk, s/f).
Figura 22. Función de menú e insertado de nuevo nodo en C++ (Paszniuk, s/f).
En la línea 40, podemos observar de manera detallada cómo debe ingresarse el nuevo nodo (ver Figura 23).
A su vez, lo cargado en dicha línea se compila y aparece tal como se observa en la figura 24.
Figura 24. Compilación de nuevo nodo en C++ (Paszniuk, s/f).
Para finalizar, debemos registrar los que se observa, en la figura 25, luego de la línea 40.
Figura 25. Función para insertar elementos en el árbol en C++ (Paszniuk, s/f).
La importancia de la programación
En este video podremos ver cuál es la importancia de la programación y cómo podemos aplicarla.
Verify to continue
We detected a high number of errors from your
connection. To continue, please confirm that you’re
a human (and not a spambot).
Bibliografía de referencia
C O NT I NU A R
88