ÁRBOLES BINARIOS

JAVIER LEONARDO LEON NUÑEZ

Profesor: OSCAR MORERA

UNIVERSIDAD DE CUNDINAMARCA INGENIERIA DE SISTEMAS FACATATIVA ± CUNDINAMARCA 2011

como se usan.INTRODUCCION Con este trabajo se pretende hacer una descripción acerca de los Arboles Binarios. . que son. La información que se muestra en este trabajo ha sido consultada en varias fuentes e internet y algunos libros. cual es su utilidad. como manejarlos en el lenguaje C++.

OBJETIVOS OBJETIVO GENERAL Dar a conocer la estructura de los Arboles Binarios. OBJETIVOS ESPECIFICOS y y Explicar el concepto de Arboles Binarios. . Mostrar el Uso y Manejo de los Arboles Binarios. sus diferentes características y funciones.

tablas.1 ÁRBOL El árbol es una estructura usada en todos los ámbitos de la informática ya que se adapta a la representación natural de informaciones homogéneas organizadas y de una gran comodidad y rapidez de manipulación. DEFINICIONES 1.1. el árbol derecho está conformado por un árbol sin ramificaciones.S. etc. quienes a su vez también son dos árboles binarios (árbol izquierdo. la rama derecha y la rama izquierda.I) . La Raíz de este árbol es A y el árbol derecho está conformado por otro árbol que tiene como raíz B.1 Es un conjunto finito de uno o más nodos donde hay un nodo llamado Raíz del árbol el cual es el punto de partida de la estructura. como son árboles genealógicos. Las estructuras tipo árbol se usan para representar datos con una relación jerárquica entre sus elementos. los nodos restantes se dividen en conjuntos disjuntos cada uno de los cuales a su vez es un árbol se denominan subárboles. árbol derecho).2 ÁRBOLES BINARIOS Este tipo de árbol se caracteriza por tener un vértice principal denominado raíz y de él se desprenden dos ramas (no más de dos). 1 Arboles Binarios en C++( Laboratorio de Programación E. 1.T.

Un nodo está compuesto de la siguiente manera: 1.1. 1.6 HIJO Como vemos en el ejemplo anterior el nodo D es el Hijo del nodo B y a su vez los nodos B y C son hijos del nodo A. 1.9 NODO NO TERMINAL Es aquel nodo que posee por lo menos una ramificación. un árbol puede tener cero nodos (árbol vacio).8 HOJA Es un nodo que no tiene ramificaciones.5 PADRE Es un nodo que puede o no tener ramificaciones como por ejemplo: En este caso el nodo A es el padre de los nodos B y C pero no es el padre del nodo D 1.7 HERMANO Son los hijos del mismo padre.10 CAMINO .4 RAIZ Un árbol binario consta de la raíz principal y las raíces de los demás subárboles (si los tiene).3 NODO Un árbol binario está compuesto de un conjunto de elementos de los cuales cada uno se denomina nodo. 1. 1. Puede tener un solo nodo (solo la raíz) o puede tener un numero finito de nodos. 1.

. 1. 1. el grado de un nodo está entre 0 y 2.14 NIVEL Los nodos tienen un nivel dentro de un árbol.15 GRADO DE UN NODO El grado de un nodo esta dado por el número de hijos.Un árbol siempre se examina hacia abajo. ejemplo de C hasta A (raíz principal). 1. 1.17 PESO Es el número de nodos en el árbol si contarse el mismo (raíz). 1.13 ANCESTRO Un nodo es Ancestro de otro si a través de un camino podemos llegar un nodo al otro nodo.11 LONGITUD Es el número de nodos que se deben de recorrer para pasar de un nodo a otro. ejemplo de A (raíz principal) hasta C. podemos llegar a una hoja por medio del padre pero no podemos llegar al padre por medio de la hoja.12 DESCENDIENTE Un nodo es descendiente de otro si a través de un camino podemos llegar un nodo al otro nodo.16 ALTURA Es el nivel de la hoja o de las hojas que están más distantes de la raíz. por concepto el nodo raíz tiene un nivel 0 y los demás nodos tienen el nivel de su padre mas 1. 1. 1.

// nodo_arbol macro instrucción explicada más adelante nuevo->info = n. p->izq = nuevo. nuevo->der = NULL. int n) { struct nodo *nuevo. } 2 Estructuras de datos en C++ (Cesar A. CREACION NODO2 Tipo de datos que representa un nodo: Struct nodo { int info. struct nodo *der. la función recibe los datos así: void ins_izq(struct nodo *p. // p se recibe por valor ya que el contenido de p con cambia La función: void ins_izq(struct nodo *p. Becerra) . int n). struct nodo *izq. nuevo = nodo_arbol. }. Queda algo como: Raíz //malloc solicitud bloque de memoria Si queremos por la izquierda el número 5 elaboraremos una función que inserte por la izquierda un nuevo nodo dado un apuntador a nodo padre del nuevo hijo. nuevo->izq =NULL.2. Y una variable definida: struct nodo*raiz La instrucción sería: raiz=(struct nodo *)malloc(sizeof (struct nodo)).

nos encontramos con otro árbol entonces examinamos el dato C y recorremos . luego pasamos a recorrer el árbol izquierdo de la raíz principal. . es una hoja por lo tanto no tiene hijos. Posorden. examinamos esa raíz D y pasamos al recorrer el árbol derecho E. FORMAS DE RECORRER UN ARBOL Existen 3 formas de recorrer un árbol binario: Preorden. .Recorrer el árbol derecho en preorden.1 PREORDEN Entonces para recorrer un árbol en preorden tenemos que: . Para recorrer este árbol en preorden entonces: Examinar el dato raíz en este caso seria A luego recorrer el árbol izquierdo en preorden para lo cual necesitamos examinar el dato raíz de este árbol que sería B luego recorrer el árbol izquierdo en preorden. inorden.Examinar el dato del nodo raíz.Si n = 5 entonces: La Macro instrucción introducida anteriormente: nodo_arbol está diseñada así: #define nodo_arbol(struct nodo*)malloc(sizeof(struct nodo)) Utilizando esa función y la de derecha (void ins_der en el que cambia p->izq por p->der) podemos seguir añadiendo datos al árbol. Si construimos un árbol como: 3. 3.Recorrer el árbol izquierdo en preorden.

. Para recorrer este árbol en posorden entonces: Examinamos el árbol izquierdo en postorden encontramos B que a su vez tiene como hijo D en el árbol izquierdo luego analizamos el árbol derecho E y por último la raíz B.Examinar la raíz. luego examinamos la raíz en este caso B luego el árbol derecho en inorden con lo que nos encontramos a E una raíz sin hijos.3 POSTORDEN Ahora veamos el recorrido en posoden para ello tenemos que: . .el árbol izquierdo F y luego el derecho G con lo que nos quedaría el árbol recorrido en preorden así: A-B-D-E-C-F-G.Recorrer el árbol derecho en posorden.Recorrer el árbol izquierdo en inorden. la examinamos y pasamos a examinar la raíz C y luego el otro árbol el izquierdo y allí encontramos G raíz sin hijos examinamos esta raíz y terminamos de examinar el árbol nos queda así : D-B-E-A-F-C-G 3.Recorrer el árbol derecho en inorden. luego examinamos la raíz principal A que es la raíz padre de B luego pasamos al árbol derecho de la raíz y encontramos el árbol con raíz C el cual recorremos en inorden y nos encontramos con F una raíz si hijos. . Para recorrer este árbol en inorden entonces: Examinar el árbol izquierdo en inorden con lo que encontramos el árbol con raíz B este lo recorremos en inorden de nuevo con lo que nos encontramos en este caso con la raíz D que ni tiene hijos. 3. luego analizamos el árbol derecho C el cual tiene en su árbol izquierdo a F y en el derecho a G y luego analizamos la raíz C y por último la raíz que seria A el árbol nos quedaría: D-E-B-F-G-C-A . .2 INORDEN Ahora veamos el recorrido en inorden para ello tenemos que: .Recorrer el árbol izquierdo en posorden.Examinar la raíz.

luego al leer 25 como 25 es menor que 87 lo creamos un nuevo nodo por la izquierda de 87. 8 . 92. while(n!=9999){ buscar sitio para insertar n. luego al leer 23. si es menor al contenido del nodo se adiciona al árbol por la izquierda y si es mayor por la derecha. insertar n. al llegar a 25 creamos un nuevo nodo a la izquierda por lo que 23 es menor que 25. las instrucciones para crearla están fuera de el ciclo para controlar la finalización de los datos: n=lea_entero().92. al leer el siguiente dato este es rechazado porque ya existe el 25 en el árbol. tendremos la lista pedida (ascendente) 8.87. raiz->der=NULL.4. 23. 48. 23. raiz->info=n. 25. raiz->izq=NULL. si imprimimos el contenido de este árbol recorriéndolo en inorden. 25. 25. entonces: al leer el numero 87 creamos este dato en el nodo raíz. Al recorrer este árbol en inorden quedaría: 8-23-25-48-87-92 Ahora implementar el problema para qué función en un computador. La raiz de el árbol es necesaria crearla solamente una vez. La entrada es 87. al leer 48 . } . nos desplazamos por la izquierda del 87 hasta el 25 y luego creamos un nuevo nodo a la derecha del 25 ya que 48 es mayor que 25. n=lea_entero(). raiz=nodo_arbol. Para solucionar este ³problema´ simplemente tenemos que ir leyendo cifra a cifra y adicionarla en el árbol. este dato es menor que 87 por lo que nos desplaza por la izquierda hacia abajo. Utilizando un árbol binario es posible mantener un conjunto e números clasificados de manera ascendente sin necesidad de rutinas de ordenamiento para el ejemplo tenemos un conjunto de números se ordenaran de manera ascendente y que de estar repetidos serán rechazados. así mismo al leer el 8 este debe ser colocado a la izquierda del 23 y por ultimo al leer el 92 lo colocaremos a la derecha del 87 ya que es mayor. UTLIDAD Una de las principales utilidades que encontramos a la hora de usar arboles binarios es clasificar un conjunto de números.48 .

Becerra) . ³buscar sitio para insertar n´ este ciclo direcciona el apuntador al nodo en el cual se almacenara el apuntador al nuevo nodo insertado. } Ahora determinaremos si podemos o no insertar n en el árbol: if(p->info = = n) cout<<´repetido´ else insertar n. Rutina general:3 #include <stdio.h> #include <stdlib. if (n<p->info) q=q->izq. struct nodo *izq. teniendo un apuntador q que examina cada nodo. struct nodo *der.h> #define nodo_arbol (struct nodo *)malloc(sizeof(struct nodo)) struct nodo{ int info. }. else ins_der(p. El proceso de insertar n consiste en conectar un nodo que contenga n ya sea por la izquierda o por la derecha del nodo indicado por p así: if (n < p->info) ins_izq(p. 3 Estructuras de datos en C++ (Cesar A. while (q!=NULL && p->info !n) { p=q. desde la raíz hasta cuando encuentre el sitio apropiado para insertar n y un apuntador p que avanza tras de del ciclo que encuentra un lugar apropiado para insertar n es: q=p=raiz.Antes del while tenemos creado un árbol cuya raíz es 87 y tanto izquierda como derecha apuntan al NULL.n). else q=q->der.n).

else q=q->der. void main(){ struct nodo *raiz. int n).n). while (q!=NULL && p->info !n) { p=q. if (n<p->info) q=q->izq.void ins_izq(struct nodo *p. int lea_entero(). printf(³de numero \n´). void ins_der(struct nodo *p.n). while(n!=9999){ q=p=raiz.*q. int n. } printf(³de numero \n´). int n). else ins_der(p. } } . } if(p->info = = n) printf(³numero repetido \n´). raiz->izq=NULL. lea_ entero (). n= lea entero(). raiz=nodo_arbol. else { if(n < p->info) ins_izq(p. printf(³de numero \n´). n= lea_entero(). raiz->der=NULL. raiz->info=n.*p.

lea_ entero () { char línea[10]. } . return(converi(linea)). } void ins_der(struct nodo *p. p->der = nuevo. p->izq = nuevo. por ejemplo el ciclo siguiente puede servir: p=NULL. int n) { struct nodo *nuevo. q=q->izq. nuevo->izq =NULL. nuevo->der = NULL. while(q) { p=q. nuevo = nodo_arbol. texto(línea. nuevo = nodo_arbol. para escribir el contenido de la hoja que está en el extremo izquierdo es necesario desplazar un apuntador desde la raíz hasta el nodo. } void ins_izq(struct nodo *p. Luego debemos escribir el contenido del nodo padre para luego escribir en inorden el árbol de la derecha. int n) { struct nodo *nuevo.10). // nodo_arbol macro instrucción explicada más adelante nuevo->info = n. // nodo_arbol macro instrucción explicada más adelante nuevo->info = n. q=raiz. nuevo->der = NULL. } IMPRESIÓN DE UN ARBOL EN INORDEN Observando el proceso lo primero que se escribe siempre es el contenido del nodo de la extrema izquierda del árbol. nuevo->izq =NULL.

ahora debemos imprimir el nodo padre. while(q) { ins_pila(&pila. para resolver este problema podemos utilizar una pila entonces la pila para el ultimo nodo Debe contener: 4 D A B C Donde cada elemento de la pila contiene la dirección de cada nodo Que se debió visitar para llegar a la hoja indicada para cargar la pila con esta información el ciclo puede ser el siguiente: p=raiz. } El siguiente paso sería retirar de la pila el último componente y escribir el contenido en esa dirección así: retira_pila(&pila. 25 y 1 D la Pila así: .Luego lo imprimimos p ya que q tiene el valor en NULL. Y escribir o imprimir p->info en este momento tenemos escrito: 8.p) //función para agregar un dato en este caso dirección a la pila p=p->izq. 23 y la pila asi: 2 D A Comprobamos una vez más si existe un árbol a la derecha de este nodo y tenemos como resultado que p=NULL por lo tanto retiramos nuevamente de la pila la dirección del nodo padre y imprimimos p->info en este momento tenemos escrito: 8.23.&p) printf(³%d´. pero nos damos cuenta que no dejamos indicado el camino por el cual llegamos a a ultima hoja lo cual hace imposible regresar para continuar el proceso.&p).p->info) //rutina para retirar un dato de la pila y en este caso // asignarle a p la dirección donde está el dato a imprimir Siguiendo este ejemplo tendríamos impreso 8 y en la pila en el apuntador p existe la posición C ahora debemos Investigar si existe un árbol por la derecha de este nodo así: 3 D A B p=p->der. si p = NULL no existe por lo tanto debemos retirar de la pila la dirección del nodo padre así : retira_pila(&pila.

} else { *s=p->a[p->t-1]. } 2 D E En este momento la pila estaría asi: Ahora repetimos el proceso de retirar de la pila la dirección E y escribir el contenido en este caso 48 1 D Con lo que la pila nos quedaría Continuamos con los pasos de comprobación y impresión hasta imprimir la última hoja externa derecha del árbol con lo que nos quedaría la pila asi: 0 Y la escritura o impresión asi: 8.p). 23. p=p->izq. else { p->t++. } } void retira_pila(struct LIFO *p.Comprobamos una vez más si existe un árbol a la derecha de este nodo y tenemos como resultado que p es diferente de NULL así que tenemos que desplazarnos en inorden hasta la hoja externa izquierda de este nuevo árbol con: while(q) { ins_pila(&pila. 92 /* -----Pilas C++ ³Estructuras de datos en C++ (Cesar A. p->t--. La pila no puede soportar mas elementos´<<endl. } } */ . struct nodo *s) { if(pila_vacia(p)) { cout<<´La pila esta vacia´<<endl. Becerra)´ ---int ins_pila(struct LIFO *p) { if(p->t = = MAXIMO) cout<<´Esta Lleno. 48. 87. 25. *s=NULL. p->a[p->t-1].

mientras que con arboles binarios el número máximo de nodos recorridos es la posición dentro del árbol de la hoja más lejana. .CONCLUSIÓN Los arboles binarios facilitan u optimizan la utilización de recursos en el computador además es una manera más sencilla de manejar los datos a comparación de listas sencillas o dobles que para consultar un dato hay que pasar por lo menos una vez por cada nodo en casos donde el dato deseado esta al final de la lista.

ulpgc. Becerra Santamaría Árboles Binarios en C++ Laboratorio de Programación 1ºA E.com/c/curso/cc09.nachocabanes.T.S.dis.es/so/cpp/intro_c/introc75.pdf Curso de C Por Nacho Cabanes.90 pre4 http://www.uma.org/wiki/%C3%81rbol_binario Memoria dinámica: malloc y free http://sopa. versión 0. Informática Gestión José Luis Pastrana Brincones @ 2004 http://www.htm - .php Árbol binario http://es.lcc.es/~pastrana/LP/curso0304/P19_04.BIBLIOGRAFÍA ± INFOGRAFÍA - Estructuras de datos en C++ 4ª Edición Autor: César A.wikipedia.I.

Sign up to vote on this title
UsefulNot useful