Está en la página 1de 10

Gabriel Antonio Saavedra Martínez.

Matricula ES1821012694
Docente: Ivonne Enríquez Castillo.
Grupo: DS-DEDA-2001-B1-002
Semestre 4°

UNIDAD 3 ACTIVIDAD 2.
Desarrollo de la actividad.
Instrucciones. Implementación en seudocódigo de los métodos relacionados con un TAD árbol binario de búsqueda (ABB):
A) Agregar nodo.
B) Borrar nodo.
C) Imprimir árbol. (recorrido del árbol.)
D) Especificación de los datos necesarios para crear las estructuras nodos y arboles(valor, referencia izquierda y derecha.)

Interfaz. ABB
Datos Descripción. Implementación.
Nodos. Un nodo consta de una variable cuyo valor Nodo nodoArbol:
será igual al almacenado en el nodo y dos Var dato;
referencias de tipo apuntador a los posibles Ptr nodoDerecho
nodos hijo (izquierdo y derecho) del nodo Ptr nodoIzquierdo
instanciado.
Operaciones.
métodos de Descripción Implementación.
construcción.
Crear () Genera un ABB, creando su nodo raíz. Este método recibe como parámetro el dato para el primer nodo del árbol, dicho valor será asignado al campo dato del
nodo raíz, declarado dentro del método. Además se inicializaran los valores de los nodos hijos del nodo raiz.
Por ultimo dicho método retornara un objeto de la clase árbol binario(ABB).
Encabezado del método. ABB crearArbol(var v)
1. //Declarar la variable raiz de tipo nodo
Nodo raiz
2. //Asignar el valor de v al campo dato del nodo raiz
raiz.dato = v
3. //Asignar un valor nulo para los subnodos izquierdo y derecho
raiz.izquierdo = null
raiz.derecho = null
4. retorna una referencia de la misma clase,
retornar ABB nuevoArbol

EliminarArbol() Elimina el espacio ocupado por el ABB. Este método recursivo recorrerá las posiciones del árbol, liberando la memoria destinada a cada nodo
Por lo cual su parámetro será el nodo raíz del árbol a eliminar.
Encabezado: void EliminarArbol(nodo raíz)
Algoritmo:
1. Si(raiz!=null)//Si el nodo raíz(nodo actual no es nulo)
1.1 //llamada recursiva para eliminar el subnodo derecho del nodo actual
EliminarArbol(raíz.derecho)
1.2 //despues liberamos el subnodo izquierdo con otra llamada recursiva
EliminarArbol(raíz.izquierdo)
Raíz = null;//liberamos el puntero del nodo actual
1.3
métodos de Descripción. Implementación.
verificación.
EsVacio() Nos dice si el ABB, se encuentra vacío o Este método requiere como parámetro el árbol, para comprobar su nodo raíz, ya que si este tiene un valor nulo,
tiene por lo menos un nodo. significa que el árbol esta vacio. El método retornara un valor booleano, para indicar si el paremetro es un árbol vacio
Encabezado: booleano Esvacio(Arbol a)
Algoritmo:
1. //si la raíz del árbol es igual a nulo
Si(a.raiz == null)
Return true;//retorna el valor verdadero que, lo que significa que la estructura esta vacio
Sino //si la raíz no es nula se retorna el valor falso
Return false;
Contiene() Indica si el valor búsqueda s, se encuentra
en el ABB. Parámetros de la función.
Las operaciones más relevantes en este Var v: variable con el árbol clave a buscar
algoritmo serán las comparaciones entre la Ptr NodoR: puntero al nodo raíz del subárbol actual.
clave s y el valor del nodo (n): Tipo de retorno booleano.
Si el valor de v es menor al del nodo actual Encabezado de método: bool contiene(var v, ptr nodoR)
se realiza una busqueda en el subnodo Algoritmo:
izquierdo de n. //si el nodo raíz apunta a null, significa que el ABB, esta vacío.
Y en caso de que v sea mayor n la búsqueda Si nodoR == null
se ejecuta sobre el sub-nodo derecho. Retornar falso
En el caso de que ambas condiciones sean Sino Si v == nodoR.dato//si la clave de busqueda es igual al valor en en el nodo
falsas, se habrá encontrado el nodo. Retornar true. //Se ha encontrado el dato
Sino si v<nodoR.dato //verifica si el valor buscado es menor al valor del nodo actual
//llamada recursiva al método cambiando al puntero del subnodo izquierdo
return contiene(v,nodoR.izquierdo)
Sino //y en caso de que v sea mayor al nodo; la llamada recursiva será referenciando al subnodo derecho.
return contiene(v,nodoR.derecho)

Leer parámetros. ABB Descripción Implementación.


AlturaNodo() Calcula y retorna la altura de un nodo. Este método calculara la altura de cierto nodo, sumando las alturas de sus subnodos(si es un nodo padre) y
sumándolas recursivamente.
Variables y parametros: int altIzquierda: almacenara la altura de cada subnodo izquierdo
Int alderecha: almacenara las alturas de los subnodos a la derecha.
Nodo n: nodo el cual se calculara su altura en cada llamada
Encabezado: int AlturaNodo(Nodo n)
Algoritmo:
1. declara e incializa los contadores de altura a cero
Int altIzquierda = 0, altderecha=0
2. Si el subnodo izquierdo del nodo actual no está vacío
Si(nodo.izquierdo ¡= null)
//llama recursivamente al método y calcula su altura almacenándola en la variable adecuada
altIzquierda = AlturaNodo(nodo.izquierda)
3. Sino verifica si el nodo de la derecha no esta vacío
Si(nodo.izquierdo ¡= null)
//sino lo está, hace otra llamada recursiva pero esta vez cambiando el parámetro por el subnodo
derecho
altDerecha = AlturaNodo(nodo.derecha)
4. Por ultimo retorna la altura máxima entre izquierda derecha aumentada en 1
If(altDerecha>altIzquierda)
Return (altDerecha + 1)
Else
Return (altIzquierda + 1)

AlturaArbol() Calcula la altura de una estructura de árbol Gracias al método auxiliar que calcula la altura de un nodo para obtener la altura del árbol tan solo tenemos que
completa. calcular la altura del nodo raíz con una llamada a dicho método.
Este método utilizara como auxiliar el método
para obtener la altura general del árbol. Variables y parametros: R: nodo raíz del árbol
Encabezado: AlturaArbol(nodo R)
Algoritmo:
1. Si (r!=null)//Si el nodo raíz no tiene valor nulo
//Retornamos el resultado de la llamada al método altura nodo
1.1 return AlturaNodo( r );
2. Y en caso de que la raíz sea vacia
Return 0; la altura del árbol sera cero
size() Contabiliza y retorna el número de nodos en Este método recibe como parámetro la estructura de árbol, y se implementa recursivamente sumando cada uno de los
el ABB. tamaños de los subárboles izquierdo y derecho del nodo actual.
De acuerdo a lo anterior la implementación seria la siguiente
Variables y parametros:
Var tamArbol: variable auxiliar que en cada recursión ira sumando los nodos que se encuentren.
Param: rt: nodo raíz del árbol, del se contabilizaran sus nodos
Encabezado: int size( Nodo rt)
Algoritmo:
1. Usamos el metodo esVacio para comprobar si el árbol tiene nodos.
Si(esVacio(tr)==false)
1.1 //Sino esta vacío
//retorna la suma de los resultados obtenidos de las llamadas recursivas al método para calcular los nodos
del subárbol izquierdo y los del derecho, agregando una unidad por el nodo raíz del árbol
.Size(tr.izquierdo) + 1 + Size(tr.derecho)
2.//En caso de que el arbol este vacio
Return 0;//retornamos un cero

leerRaizDato() Retorna el valor almacenado en el nodo raíz. Este método recibe el árbol como parámetro y retorna el valor almacenado en el campo de su nodo raíz.
Variables y parámetros: Árbol ab parámetro de tipo estructura árbol
Encabezado: leerRaizdato(árbol ab)
Algoritmo
Si ab.dato!=null//si la raíz del árbol no esta vacia
Return ab.dato retornamos el valor de su campo dato
Sino//y si el campo se encuentra vacio
Imprimir “No hay valor en la raíz.”
Métodos para agregar Descripción. Implementación.
o eliminar
ColocarEnRaiz() Sustituye el dato almacenado en el nodo raíz. Este método recibe un dato que será posicionado en la raíz del árbol, por lo que simplemente debemos pasar la
variable con el nuevo a valor y sustituir el valor actual del nodo raíz con el del parámetro.
Variables y parámetros.
Var d: variable con el nuevo valor para el nodo raiz
Algoritmo:
1. Si (d!=null)//si la variable de sustitución no tiene un valor nulo
1.1 raiz.dato=d//Lo asignamos como dato del nodo raíz.
2. En caso de que se haya ingresado un valor invalido, mostramos un mensaje al usuario
Imprimir “Dato ingresado no valido”

Agregar() Crea un nuevo nodo y almacena un dato en Variables y parámetros


este. Var: ptrNodo: es un nuevo puntero al nodo que será agregado.
Par: d: variable primitiva u objeto que guardara el dato a insertar en el nodo.
Par nodoR: nodo raíz del árbol donde se agregara el nodo
Encabezado de método. Agregar(nodoR, d)
Algoritmo:
1. instanciamos el nuevo nodo, pasando como parámetro su dato
Nodo ptrNodo(d)
//si el nodo raíz del árbol esta vacio
2. Si NodoR == null
2.1 asignamos el nuevo nodo a la raíz.
NodoR = ptrNodo;
2.2 //si lo anterior no se cumple.
a. Si d<nodoR.dato//verifica si el valor a ingresar es menor al del nodo raíz actual
//si es menor, hacemos una llamada recursiva, pasando como parámetro el subnodo izquierdo de la raiz
Return Agregar(nodoR.izq, d)
b. Si d>nodoR.dato// y en caso de que d sea mayor al valor del nodo actual.
//en la llamada recursiva, pasamos el puntero derecho del nodo raiz actual
Return Agregar(nodoR.der, d)
c. Sino //si ninguna de las condiciones anteriores se cumple, el valor d ya fue almacenado.
Escribir “El valor ya se encuentra en el árbol”

Borrar() Borra un nodo de el ABB Borrar un elemento de un ABB, es una operación con un mayor grado de complejidad que las de búsqueda
e inserción de elementos, dado que debemos asegurar que sus propiedades como un árbol binario de
búsqueda, se conserven, ejecutando las reestructuraciones necesarias.

Existen tres casos distintos en la operación de borrar un nodo:


a) Si el nodo a eliminar es de tipo terminal, simplemente se elimina el nodo.
b) Si el nodo es de tipo padre y solo tiene un nodo hijo(izquierdo o derecho)
Asignamos la referencia del nodo hijo al nodo que se desea eliminar.
c) Y en el caso de que el nodo sea padre con ambos nodos hijos, buscamos el siguiente mayor elemento
sucesor, sobre el subnodo derecho. Reemplazando el nodo a ser removido por el nodo sucesor hallado y
por ultimo borrar el nodo sucesor ya que estará duplicado.
El siguiente método implementado de manera recursiva contempla los tres casos.

Variables y parametros:
Nodo raíz: un parámetro de tipo apuntador al nodo raíz del árbol.
Var val: parámetro variable que almacena el valor buscado a eliminar.
Tipo de retorno: Nodo: retornara un nodo del árbol modificado por el método.

Encabezado: nodo Borrar(Nodo raíz, val)


Algoritmo:
1. Si (raiz == nulo)//Si el nodo raíz es nulo
1.1 Return raíz. //retornamos el nodo raíz.
//operaciones en caso de que el nodo actual tenga ambos hijos
2. Si (val < raíz.dato)//si el valor a eliminar es menor al del nodo actual(raíz)
//llamada recursiva cambiando el nodo actual como el subnodo izquierdo.
root.izquierda = Borrar(raíz.izquierda,val)
3. Sino Si (val>raíz.dato)//Y en caso de que val sea mayor al del nodo actual
//la llamada recursiva será cambiando el nodo actual por el subnodo derecho
root.derecha = Borrar(raíz.derecha,val)
4. //Sino y en caso de que el nodo actual solo tenga un hijo
4.1 //verificamos cual de los subnodos esta vacio
4.1.1 Si (raíz.izquierda == null)//en caso de de ser izquierdo
//Retornamos el nodo derecho como el nuevo nodo actual
return raíz.derecho;
4.1.2 Si (raíz.derecha == null)// y si el vacio es el subnodo derecho
//Retornamos el nodo derecho.
5. //en caso de que el nodo sea de tipo terminal
5.1 //cambiamos el valor del nodo actual por el menor entre los subnodos de su subárbol derecho
//para ello empleamos un método auxiliar que hace un recorrido a la derecha del subnodo
Raíz.dato = SucesorInOrden(raíz.derecha)
//Cuando tengamos la posición y el valor a sustituir hacemos la llamada recursiva para borrar el
elemento
Raíz.derecho = Borrar(Raiz.derecho, raíz.dato)
6. //Por ultimo retornaremos el nodo raiz que apuntara al nodo a sustituir.
Return raíz.

Ahora vemos la implementación del método auxiliar, que realiza un recorrido inOrden, para buscar el nodo a sustituir
en el caso de eliminación de un nodo de tipo hoja.
Recordemos que este método solo recibe como parámetro un nodo raíz.
SucesorInOrden(Nodo r)
Algoritmo:
// Declaramos una variable que almacenara el próximo valor menor a la derecha del nodo raiz.
1. Var mínimo = r.dato//su valor inicial será el del nodo actual r
//Recorremos los nodos a la izquierda mientras no encontremos un nodo de tipo hoja
2. Mientras(r.izquierda ¡=null){
2.1 mínimo = r.izquierda.dato//actualizamos el valor mínimo
2.2 r = r.izquierda; //cambiamos al nodo actual al nodo al siguiente nodo a la izquierda
3.//Cuando encontremos un nodo padre sin nodo hijo izquierdo
Return mínimum; retornamos su valor que será el mínimo

Metodos para recorridos Descripción Implementación.


dentro del ABB
recorridoPostOrden() Todos los métodos de recorrido se simplifican El algoritmo del método es:
al implementarlos de forma recursiva, en recorridoPostOrden (Nodo actual)
cada uno se llamará dos veces al mismo 1. //Si el nodo actual (en principio el nodo raíz) no está vacío
método y se incluirá las respectivas Si(actual ¡= null)
instrucciones para procesar cada uno de los 1.1 //hacemos la primer llamada recursiva, pasando como parámetro el subnodo izquierdo del nodo actual
datos en los nodos del árbol. Preorden(actual.izquierdo)
Todos los métodos necesitan como único 1.2 //después se realiza la segunda llamada cursiva pero el parámetro será el subnodo derecho
parámetro el nodo raíz del árbol. Preorden(actual.derecho)
Su diferencia fundamental es el orden de 1.3 //Procesamos el nodo actual.
ambas llamadas recursivas y el cambio de su Imprimir(actual.dato)//imprimiendo el valor que almacena
parámetro al subnodo izquierdo o derecho
del nodo raíz actual.

El método postOrden recorre los nodos


moviéndose entre los nodos del subárbol
izquierdo hasta encontrar un nodo terminal a
procesar. Después repite la operación sobre
el subárbol derecho.
Al finalizar ambos recorridos retorna a la raíz
del árbol para procesarla.
recorridoPreOrden() Este método comienza procesando la raíz del Su algoritmo es:
subárbol; y a continuación se procesa recorridoPreOrden (Nodo actual)
respectivamente cada subárbol comenzado 1. //Si el nodo actual(en principio el nodo raíz) no está vacío
por el izquierdo y por ultimo el derecho. Si(actual ¡= null)
1.1 //procesamos el nodo actual
Imprimir(actual.dato)
1.2 //Después se realiza las llamadas recursivas, la 1° con el subnodo izquierdo y la 2° con el derecho
Preorden(actual.izquierdo)
Preorden(actual.derecho)
recorridoInOrden() Este método recorre el árbol comenzando por Su algoritmo es:
su subárbol izquierdo. recorridoInOrden (Nodo actual)
Procesa el nodo raíz. 1. //Si el nodo actual(en principio el nodo raíz) no está vacío
Y por ultimo recorre el subarbol derecho Si(actual ¡= null)
1.2 // realiza la llamadas recursiva, pasando el subnodo izquierdo, como parámetro.
Preorden(actual.izquierdo)
1.3 Y a continuación la llamada con el subnodo derecho
Preorden(actual.derecho)
Conclusiones.
El uso de estructuras de árbol binario es una de las mejores opciones para
implementar algoritmos de alta eficiencia.
Los diferentes algoritmos creados para operar sobre este tipo de estructuras nos
permiten, obtener toda la información necesaria acerca de este tipo de estructuras:
Como su número de elementos, la posición dentro del mismo, procesar los datos
en distintas secuencias etc.
Gracias a sus caracteristicas como la dar un orden a los elementos, mientras se
van ingresando nuevos nodos, además su manejo de memoria dinámica, le
permiten crecer sin mayor limite que el dado por los recursos de hardware donde
implementan los algoritmos.

Es por todo ello, que debemos de conocer la implementación de cada una de


estas operaciones, lo que nos permitirá desarrollar aplicaciones que trabajen de
manera mas eficiente con los datos que serán procesados.
Referencias.
Cairo Osvaldo & Guardati Silvia(2006)Estructuras de datos. 3Ed. McgrawHill
Goodrich, M. y Tamassia, R. (2010). Estructura de datos y algoritmos en Java.
México: CECSA.s
DiscoDurodeRoer. (2017/11/16). Ejercicios Java - Estructuras dinámicas #9
¡Haciendo nuestro propio árbol! .[archivo de video] Youtube:
DiscoDurodeRoer. (2018/01/02). Ejercicios Java - Recursividad #7 ¡Contamos los
nodos de un árbol binario!. [archivo de video] Youtube:
https://www.youtube.com/watch?v=j8Po-rHF1Tc
N.N(S.F). write-a-c-program-to-calculate-size-of-a-tree. Recuperado de:
https://www.geeksforgeeks.org/write-a-c-program-to-calculate-size-of-a-tree/

También podría gustarte