Está en la página 1de 12

TALLER 2

ARBOLES

JUAN CAMILO ARBOLEDA RESTREPO

DOCENTE
ELIANA LONDONO

ESTRUCTURA DE DATOS II

FUNDACIÓN UNIVERSITARIA
CATÓLICA DEL NORTE
OCTUBRE DE 2019
UNIVERSIDAD CATÓLICA DEL NORTE
Taller 2
Estructuras de Datos Dinámicos
Estructuras de Datos II

En los puntos 1 y 2, no se hace algoritmo.

1. Dibujar un árbol binario que leído en inorden represente la siguiente

expresión:

A–(B–(C–D)/ (E+F))

R/
1. Lea el siguiente árbol en preorden, posorden e inorden:

R/
Preorden: R,I,D
A,B,D,E,C,F,G

Postorden: I,D,R
D,E,B,F,G,C,A

Inorden: I,R,D
D,B,E,A,F,C,G

2. Escriba un algoritmo para calcular el número de nodos un árbol e


imprimir el promedio de los elementos menores que 100 que hay en él.
Recuerde que en pseint no se pueden trabajar árboles. El algoritmo se
entrega en seudocódigo, no es válido codificar en ningún lenguaje.
R/

Proceso búsqueda

dato de tipo entero


si raiz == NULL
imprimir por pantalla “Arbol vacío”
en caso contrario
solicitar valor a buscar;
asignar a dato;
asignar aux=raiz,
mientras aux diferente null && aux->clave diferente dato
si dato > aux->clave
asignar aux=aux->der,
en caso contrario
asignar aux=aux->izq;
fin del si
Fin del mientras
si aux== NULL
imprimir por pantalla “El número no existe”
en caso contrario
imprimir aux->clave;
fin del si
fin del proceso

Ejemplo

/* Arbol Binario de Búsqueda en C */

#include <stdlib.h>
#include <stdio.h>
#define TRUE 1
#define FALSE 0

/* Estructuras y tipos */
typedef struct _nodo {
int dato;
struct _nodo *derecho;
struct _nodo *izquierdo;
} tipoNodo;

typedef tipoNodo *pNodo;


typedef tipoNodo *Arbol;

/* Funciones con árboles: */


/* Insertar en árbol ordenado: */
void Insertar(Arbol *a, int dat);
/* Borrar un elemento: */
void Borrar(Arbol *a, int dat);
/* Función de búsqueda: */
int Buscar(Arbol a, int dat);
/* Comprobar si el árbol está vacío: */
int Vacio(Arbol r);
/* Comprobar si es un nodo hoja: */
int EsHoja(pNodo r);
/* Contar número de nodos: */
int NumeroNodos(Arbol a, int* c);
/* Calcular la altura de un árbol: */
int AlturaArbol(Arbol a, int* altura);
/* Calcular altura de un dato: */
int Altura(Arbol a, int dat);
/* Aplicar una función a cada elemento del árbol: */
void InOrden(Arbol, void (*func)(int*));
void PreOrden(Arbol, void (*func)(int*));
void PostOrden(Arbol, void (*func)(int*));

/* Funciones auxiliares: */
void Podar(Arbol *a);
void auxContador(Arbol a, int*);
void auxAltura(Arbol a, int, int*);

void Mostrar(int *d);

/* Programa de ejemplo */
int main()
{
Arbol ArbolInt=NULL;
int altura;
int nnodos;
/* Inserción de nodos en árbol: */
Insertar(&ArbolInt, 10);
Insertar(&ArbolInt, 5);
Insertar(&ArbolInt, 12);
Insertar(&ArbolInt, 4);
Insertar(&ArbolInt, 7);
Insertar(&ArbolInt, 3);
Insertar(&ArbolInt, 6);
Insertar(&ArbolInt, 9);
Insertar(&ArbolInt, 8);
Insertar(&ArbolInt, 11);
Insertar(&ArbolInt, 14);
Insertar(&ArbolInt, 13);
Insertar(&ArbolInt, 2);
Insertar(&ArbolInt, 1);
Insertar(&ArbolInt, 15);
Insertar(&ArbolInt, 10);
Insertar(&ArbolInt, 17);
Insertar(&ArbolInt, 18);
Insertar(&ArbolInt, 16);

printf("Altura de arbol %d\n", AlturaArbol(ArbolInt, &altura));

/* Mostrar el árbol en tres ordenes distintos: */


printf("InOrden: ");
InOrden(ArbolInt, Mostrar);
printf("\n");
printf("PreOrden: ");
PreOrden(ArbolInt, Mostrar);
printf("\n");
printf("PostOrden: ");
PostOrden(ArbolInt, Mostrar);
printf("\n");

/* Borraremos algunos elementos: */


printf("N nodos: %d\n", NumeroNodos(ArbolInt, &nnodos));
Borrar(&ArbolInt, 5);
printf("Borrar 5: ");
InOrden(ArbolInt, Mostrar);
printf("\n");
Borrar(&ArbolInt, 8);
printf("Borrar 8: ");
InOrden(ArbolInt, Mostrar);
printf("\n");
Borrar(&ArbolInt, 15);
printf("Borrar 15: ");
InOrden(ArbolInt, Mostrar);
printf("\n");
Borrar(&ArbolInt, 245);
printf("Borrar 245: ");
InOrden(ArbolInt, Mostrar);
printf("\n");
Borrar(&ArbolInt, 4);
printf("Borrar 4: ");
InOrden(ArbolInt, Mostrar);
printf("\n");
Borrar(&ArbolInt, 17);
printf("Borrar 17: ");
InOrden(ArbolInt, Mostrar);
printf("\n");

/* Veamos algunos parámetros */


printf("N nodos: %d\n", NumeroNodos(ArbolInt, &nnodos));
printf("Altura de 1 %d\n", Altura(ArbolInt, 1));
printf("Altura de 10 %d\n", Altura(ArbolInt, 10));
printf("Altura de arbol %d\n", AlturaArbol(ArbolInt, &altura));

/* Liberar memoria asociada al árbol: */


Podar(&ArbolInt);
system("PAUSE");
return 0;
}

/* Poda: borrar todos los nodos a partir de uno, incluido */


void Podar(Arbol *a)
{
/* Algoritmo recursivo, recorrido en postorden */
if(*a) {
Podar(&(*a)->izquierdo); /* Podar izquierdo */
Podar(&(*a)->derecho); /* Podar derecho */
free(*a); /* Eliminar nodo */
*a = NULL;
}
}

/* Insertar un dato en el árbol ABB */


void Insertar(Arbol *a, int dat)
{
pNodo padre = NULL;
pNodo actual = *a;

/* Buscar el dato en el árbol, manteniendo un puntero al nodo padre */


while(!Vacio(actual) && dat != actual->dato) {
padre = actual;
if(dat < actual->dato) actual = actual->izquierdo;
else if(dat > actual->dato) actual = actual->derecho;
}

/* Si se ha encontrado el elemento, regresar sin insertar */


if(!Vacio(actual)) return;
/* Si padre es NULL, entonces el árbol estaba vacío, el nuevo nodo será
el nodo raiz */
if(Vacio(padre)) {
*a = (Arbol)malloc(sizeof(tipoNodo));
(*a)->dato = dat;
(*a)->izquierdo = (*a)->derecho = NULL;
}
/* Si el dato es menor que el que contiene el nodo padre, lo insertamos
en la rama izquierda */
else if(dat < padre->dato) {
actual = (Arbol)malloc(sizeof(tipoNodo));
padre->izquierdo = actual;
actual->dato = dat;
actual->izquierdo = actual->derecho = NULL;
}
/* Si el dato es mayor que el que contiene el nodo padre, lo insertamos
en la rama derecha */
else if(dat > padre->dato) {
actual = (Arbol)malloc(sizeof(tipoNodo));
padre->derecho = actual;
actual->dato = dat;
actual->izquierdo = actual->derecho = NULL;
}
}

/* Eliminar un elemento de un árbol ABB */


void Borrar(Arbol *a, int dat)
{
pNodo padre = NULL;
pNodo actual;
pNodo nodo;
int aux;

actual = *a;
/* Mientras sea posible que el valor esté en el árbol */
while(!Vacio(actual)) {
if(dat == actual->dato) { /* Si el valor está en el nodo actual */
if(EsHoja(actual)) { /* Y si además es un nodo hoja: lo borramos */
if(padre) /* Si tiene padre (no es el nodo raiz) */
/* Anulamos el puntero que le hace referencia */
if(padre->derecho == actual) padre->derecho = NULL;
else if(padre->izquierdo == actual) padre->izquierdo = NULL;
free(actual); /* Borrar el nodo */
actual = NULL;
return;
}
else { /* Si el valor está en el nodo actual, pero no es hoja */
padre = actual;
/* Buscar nodo más izquierdo de rama derecha */
if(actual->derecho) {
nodo = actual->derecho;
while(nodo->izquierdo) {
padre = nodo;
nodo = nodo->izquierdo;
}
}
/* O buscar nodo más derecho de rama izquierda */
else {
nodo = actual->izquierdo;
while(nodo->derecho) {
padre = nodo;
nodo = nodo->derecho;
}
}
/* Intercambiar valores de no a borrar u nodo encontrado
y continuar, cerrando el bucle. El nodo encontrado no tiene
por qué ser un nodo hoja, cerrando el bucle nos aseguramos
de que sólo se eliminan nodos hoja. */
aux = actual->dato;
actual->dato = nodo->dato;
nodo->dato = aux;
actual = nodo;
}
}
else { /* Todavía no hemos encontrado el valor, seguir buscándolo */
padre = actual;
if(dat > actual->dato) actual = actual->derecho;
else if(dat < actual->dato) actual = actual->izquierdo;
}
}
}

/* Recorrido de árbol en inorden, aplicamos la función func, que tiene


el prototipo:
void func(int*);
*/
void InOrden(Arbol a, void (*func)(int*))
{
if(a->izquierdo) InOrden(a->izquierdo, func);
func(&(a->dato));
if(a->derecho) InOrden(a->derecho, func);
}

/* Recorrido de árbol en preorden, aplicamos la función func, que tiene


el prototipo:
void func(int*);
*/
void PreOrden(Arbol a, void (*func)(int*))
{
func(&a->dato);
if(a->izquierdo) PreOrden(a->izquierdo, func);
if(a->derecho) PreOrden(a->derecho, func);
}

/* Recorrido de árbol en postorden, aplicamos la función func, que tiene


el prototipo:
void func(int*);
*/
void PostOrden(Arbol a, void (*func)(int*))
{
if(a->izquierdo) PostOrden(a->izquierdo, func);
if(a->derecho) PostOrden(a->derecho, func);
func(&a->dato);
}

/* Buscar un valor en el árbol */


int Buscar(Arbol a, int dat)
{
pNodo actual = a;

/* Todavía puede aparecer, ya que quedan nodos por mirar */


while(!Vacio(actual)) {
if(dat == actual->dato) return TRUE; /* dato encontrado */
else if(dat < actual->dato) actual = actual->izquierdo; /* Seguir */
else if(dat > actual->dato) actual = actual->derecho;
}
return FALSE; /* No está en árbol */
}

/* Calcular la altura del nodo que contiene el dato dat */


int Altura(Arbol a, int dat)
{
int altura = 0;
pNodo actual = a;

/* Todavía puede aparecer, ya que quedan nodos por mirar */


while(!Vacio(actual)) {
if(dat == actual->dato) return altura; /* encontrado: devolver altura */
else {
altura++; /* Incrementamos la altura, seguimos buscando */
if(dat < actual->dato) actual = actual->izquierdo;
else if(dat > actual->dato) actual = actual->derecho;
}
}
return -1; /* No está en árbol, devolver -1 */
}

/* Contar el número de nodos */


int NumeroNodos(Arbol a, int *contador)
{
*contador = 0;

auxContador(a, contador); /* Función auxiliar */


return *contador;
}

/* Función auxiliar para contar nodos. Función recursiva de recorrido en


preorden, el proceso es aumentar el contador */
void auxContador(Arbol nodo, int *c)
{
(*c)++; /* Otro nodo */
/* Continuar recorrido */
if(nodo->izquierdo) auxContador(nodo->izquierdo, c);
if(nodo->derecho) auxContador(nodo->derecho, c);
}

/* Calcular la altura del árbol, que es la altura del nodo de mayor altura. */
int AlturaArbol(Arbol a, int *altura)
{
*altura = 0;

auxAltura(a, 0, altura); /* Función auxiliar */


return *altura;
}

/* Función auxiliar para calcular altura. Función recursiva de recorrido en


postorden, el proceso es actualizar la altura sólo en nodos hojas de mayor
altura de la máxima actual */
void auxAltura(pNodo nodo, int a, int *altura)
{
/* Recorrido postorden */
if(nodo->izquierdo) auxAltura(nodo->izquierdo, a+1, altura);
if(nodo->derecho) auxAltura(nodo->derecho, a+1, altura);
/* Proceso, si es un nodo hoja, y su altura es mayor que la actual del
árbol, actualizamos la altura actual del árbol */
if(EsHoja(nodo) && a > *altura) *altura = a;
}
/* Comprobar si un árbol es vacío */
int Vacio(Arbol r)
{
return r==NULL;
}

/* Comprobar si un nodo es hoja */


int EsHoja(pNodo r)
{
return !r->derecho && !r->izquierdo;
}

/* Función de prueba para recorridos del árbol */


void Mostrar(int *d)
{
printf("%d, ", *d);
}

También podría gustarte