Estructuras de datos. Estructuras de datos



Documentos relacionados
Estructura de datos y de la información Boletín de problemas - Tema 10

Árboles. Árboles. Árboles binarios de búsqueda. Árboles. Inserción en un árbol. Árbol binario de búsqueda

Estructura de Datos. Temario Unidad VI. Árboles Árboles Binarios

El método main de la clase PruebaArbol, empieza creando una instancia de un objeto Árbol vacío y asigna su referencia a la variable árbol

Temario. Tema 5. Estructuras de Datos no Lineales. 5.1 Árboles Binarios 5.2 Árboles n-arios

TEMA 3. Árboles. Objetivos. Contenidos. Bibliografía. Básica

A) PREORDEN B) INORDEN C) POSTORDEN D) NIVELES

Programación II Árboles binarios de búsqueda (ABB)

Análisis y Complejidad de Algoritmos. Arboles Binarios. Arturo Díaz Pérez

INGENIERIA DE SISTEMAS 19 ESTRUCTURAS DE DATOS (Listas simples) ARBOLES

Estructura de Datos. Árboles Binarios de Búsqueda ABB. Primer Semestre, 2010

Estructura de Datos Tema 6. Árboles. Contenido 14/06/2018

Tema 09: TAD Árbol binario

Árboles Binarios Ordenados Árboles AVL

UNIVERSIDAD NACIONAL AUTÓNOMA DE MÉXICO

Árbol ABB equilibrado. Lección: Árboles. Algorítmica II (Tema 4) Lenguajes y Sistemas Informáticos, Universidad Pablo de Olavide 1/ 58

Estructura de Datos. Unidad V Estructuras no lineales estáticas y dinámicas. (Árboles y grafos)

Estructura de Datos Unidad 6: ARBOLES

ÁRBOL BINARIO. T der. Árbol binario homogéneo es aquel cuyos nodos tienen grado 0 ó 2(no hay ninguno de grado 1).

ESTRUCTURAS DE DATOS Y ALGORITMOS

Estructuras de Datos Clase 14 Árboles binarios de búsqueda

Tema Árboles generales. 9.2 Árboles binarios 9.3 Árboles de búsqueda

1. Leer el primer número y almacenarlo en la raíz del árbol. 2. Repetir hasta encontrar un duplicado o el árbol esté vacío.

Estructuras de datos utilizando JAVA

Programación de sistemas Árboles

Programación Estructuras Arborescentes

Árboles. Cursos Propedéuticos Dr. René Cumplido M. en C. Luis Rodríguez Flores

Ejercicio 2 Considere la representación para Lista de Naturales y Árbol Binario de Naturales de la Figura 1.

PRÁCTICA No. 9 RECORRIDOS EN ÁRBOLES BINARIOS

Programación 2 Práctico 9 - TADs Árbol Binario de Búsqueda, Árbol Finitario y Árbol n-ario

Programación II Arboles Binarios(AB)

El TAD Árbol. El TAD Árbol

Arboles Binarios de Búsqueda en C++

Para la resolución de los ejercicios, se dispone de una implementación de árbol binario a través de la clase BinTree con la siguiente especificación.

Árboles binarios. Franco Guidi Polanco Escuela de Ingeniería Industrial Pontificia Universidad Católica de Valparaíso, Chile

Sólo una opción es correcta en cada pregunta. Cada respuesta correcta suma 1 4. puntos. Cada respuesta incorrecta resta 1 12

Definición recursiva de los árboles

Tema 10: Árbol binario de búsqueda

NIVEL 15: ESTRUCTURAS RECURSIVAS BINARIAS

IMPLEMENTACIÓN DE PILAS CON LISTAS EN C++

Tema 6: Estructuras de datos recursivas

Introducción a Árboles Árboles Binarios

DEFINICION. Ing. M.Sc. Fulbia Torres Asignatura: Estructuras de Datos Barquisimeto 2006

Algoritmos y Programación II Curso 2006

324 MR Versión 1 Prueba Integral 1/3 Semana 10 Lapso

Contenido PARTE II: ESTRUCTURAS DE DATOS AVANZADAS

Estructura de Datos. Índice

Tema: ARBOLES. Instructor: MC. Gerardo Gálvez Gámez Junio de 2018 INTRODUCCIÓN:

Definición de árbol. Árboles

Estructuras de Datos II

Estructura de Datos. Temario Unidad VI. Árboles Árboles AVL

Tema 7: Árboles ESTRUCTURAS DE DATOS 1

Clase adicional 9. Listas enlazadas. Temas. Listas enlazadas Árboles Problemas de la clase adicional Ejercicios de diseño

Tema 10. Árboles. José M. Badía, Begoña Martínez, Antonio Morales y José M. Badía

Segundo parcial de Programación 2

ÁRBOLES BINARIOS DE BÚSQUEDA (ABB)

CAPÍTULO 2. ÁRBOLES 2.0. CONCEPTOS GENERALES

Tema: Arboles en C#. Objetivos Específicos. Materiales y Equipo. Introducción Teórica. Definición de Árbol Binario. Programación IV. Guía No.

Programación de sistemas

Capítulo 8. Árboles. Continuar

ÁRBOLES PARCIALMENTE ORDENADOS

Árboles n-arios de búsqueda. Lección 16

Estructuras de Datos Clase 20 Árboles de búsqueda

Estructuras de datos y algoritmos

Tema Árboles binarios fmap para árboles binarios Plegado de árboles binarios

ESTRUCTURA DE DATOS. ABB Arboles de Búsqueda Binaria

Listas Posicionales. Listas posicionales

Algoritmos y Estructuras de Datos. Guillermo Román Díez

Este material es de uso exclusivo para clase de algoritmos y estructura de datos, la

Estructuras de Datos y Algoritmos

Estructuras de Datos y Algoritmos (ITIS). TAD Tree. Estructuras de Datos y Algoritmos (ITIS) Ingeniería Técnica en Informática de Sistemas, Curso 2º

LECCION N 08 ARBOLES. Un árbol es un grafo A que tiene un único nodo llamado raíz que:

Árboles generales. Un árbol es una estructura no lineal acíclica utilizada para organizar información de forma eficiente. La definición es recursiva:

Árboles y esquemas algorítmicos. Tema III

Instituto de Computación. Facultad de Ingeniería. Universidad de la República Examen de Programación 2 03 de Agosto de 2006 Generalidades:

Tema 8. Listas. José M. Badía, Begoña Martínez, Antonio Morales y José M. Sanchiz

UNIVERSIDAD AUTONOMA DE MADRID ESCUELA POLITÉCNICA SUPERIOR ESTRUCTURAS DE DATOS Y ALGORITMOS

95.12 Algoritmos y Programación II Práctica 7: árboles

Programación Declarativa Universidad de Málaga

ARBOLES BINARIOS ORDENADOS. REPRESENTACIÓN Y OPERACIONES

Estructura de Datos. Listas Enlazadas

Carlos Delgado Kloos Mª Carmen Fernández Panadero Raquel M. Crespo García Ingeniería Telemática Univ. Carlos III de Madrid

1. Cuál es el número total máximo de nodos que tiene un árbol binario de N niveles? a. N 2-1 b. 2 N+1-1 c. 2 N d. 2 N+1 i.

Transcripción:

Un arbol es un conjunto de nodos que cumplen con las relaciones padre, hijo y hermano. Llamamos hijos de un nodo a todos los nodos que podemos llegar directamente por medio de un apuntador hacia ellos y descendencia a todos los que pudieramos llegar a traves de los hijos y su propia descendencia. Llamamos padre al nodo del cual proviene el nodo hijo. Existe un nodo que no tiene padre y le llamamos raiz del arbol. Llamamos hermanos a todos los nodos que tienen el mismo padre. Llamamos hoja al nodo que no tiene hijos. Podemos definir un árbol de manera recursiva diciendo que un árbol sin nodos esta vacío. Un arbol es un nodo llamado raiz cuyos hijos son tambien arboles(vacios o no). Notemos que una lista es un arbol cuyos nodos solo tienen un hijo. Un arbol binario es aquel cuyos nodos pueden tener a lo más dos hijos. 1

Un arbol cuyos nodos tienen 0 o 2 hijos se llama estrictamente binario. Si algún nodo tiene un solo hijo ya no lo es. Llamamos nivel al numero de apuntadores que se tienen que recorrer para llegar a un nodo a partir la raiz, asi el nodo raiz esta en el nivel 0 y sus hijos en el nivel 1. La profundidad de un árbol es igual al mayor nivel de sus hojas Un árbol estrictamente binario cuyas hojas estan todas en el mismo nivel se llama arbol binario completo. Un arbol estrictamente binario cuyas hojas estan a lo más en dos niveles diferentes se llama arbol casi completo y se dice que el arbol esta balanceado. Los arboles binarios son muy importantes en las operaciones de busqueda y para ello deben mantenerse balanceados. 2

raiz 1 2 3 4 5 6 7 El nodo 1 es el nodo raiz. Los nodos 2 y 3 son el hijo izquierdo y el hijo derecho del nodo raiz. Los nodos 4, 5, 6 y 7 son las hojas del arbol. El padre del nodo 5 es 2 y del nodo 7 es 3. Los nodos 2 y 3 son hermanos. La profundidad del arbol es 2. El arbol de la lamina anterior tambien es un arbol estrictamente binario y ademas completo. Para mayores ejemplos de arboles binarios y su clasificación consultar el libro de Tenenbaum en el capítulo de arboles. 3

Para implementar un arbol binario es necesario crear primero una clase Nodo_Arbol capaz de almacenar cualquier dato y que tenga dos apuntadores a los hijos izquierdo y derecho. template <class T> class Nodo_Arbol: public Nodo<T>{ public: Nodo_Arbol(T); T GetDato(){ return Nodo<T>::GetDato(); Nodo_Arbol* GetDer(){ return (Nodo_Arbol *)GetSiguiente();//cast de Nodo * a Nodo_Arbol * void SetDer(Nodo_Arbol *d){setsiguiente((nodo<t> *)d);//cast de Nodo_Arbol * a Nodo * Nodo_Arbol* GetIzq(){ return izq; void SetIzq(Nodo_Arbol *d){izq = d; private: Nodo_Arbol *izq; ; template <class T> Nodo_Arbol<T>::Nodo_Arbol(T x): Nodo<T>(x){ //manda a llamar al constructor de Nodo izq = NULL; La implementación de Nodo_Arbol usa herencia y hereda las caracteristicas de Nodo, es decir usa las propiedades y la interfaz de la clase Nodo que se uso para crear Listas. Para tener una nomenclatura consistente se renombro el apuntador siguiente para convertirlo en der, y se añadio el apuntador al nodo izq. Para ello fue necesario hacer conversiones de tipos o cast. Estas conversiones deben manejarse con cuidado para evitar referencias erroneas a la memoria. 4

La otra opción es crear la clase Nodo_Arbol desde cero como se explico en clase. Es decir se crea una clase que contenga espacio para almacenar un dato y los apuntadores der e izq hacia nodos del arbol. La interfaz resultaria muy parecida a la de los nodos de la clase Lista. Para evitar la conversión entre objetos de un tipo a otro puede llegar a preferirse este metodo, sobre todo tomando en cuenta la simplicidad de la clase Nodo_Arbol. Ahora podemos pasar a analizar las operaciones que se pueden hacer con un árbol. Inserta(ELEMENTO x, Nodo_Arbol t) inserta el elemento x en el arbol t. La regla es que todos los nodos se insertan como hojas, no puede haber nodos repetidos y todos los descendientes izquierdos de un nodo son menores a el y los derechos son mayores a ese mismo nodo. A un arbol de este tipo le llamamos arbol de busqueda binaria. 5

Anula(Nodo_Arbol *t) convierte el arbol t en un arbol vacío. El proceso de eliminación comienza en las hojas. Recorrer_en_orden(Nodo_Arbol *t) recorre los nodos del arbol de acuerdo a la siguiente regla recursiva: Recorrer_en_orden(SUBARBOL_IZQ); Raiz; Recorrer_en_orden(SUBARBOL_DER); Recorrer_en_preorden(Nodo_Arbol *t) recorre los nodos del arbol de acuerdo a la siguiente regla recursiva: Raiz; Recorrer_en_preorden(SUBARBOL_IZQ); Recorrer_en_preorden(SUBARBOL_DER); Recorrer_en_postorden(Nodo_Arbol *t) recorre los nodos del arbol de acuerdo a la siguiente regla recursiva: Recorrer_en_postorden(SUBARBOL_IZQ); Recorrer_en_postorden(SUBARBOL_DER); Raiz; 6

ELEMENTO Get_Dato(Nodo_Arbol *nd) devuelve el dato almacenado en el nodo nd. Nodo_Arbol *GetIzq(Nodo_Arbol *nd) devuelve un apuntador al hijo izquierdo del nodo nd. Nodo_Arbol *GetDer(Nodo_Arbol *nd) devuelve un apuntador al hijo derecho del nodo nd. BOOL SetDer(Nodo_Arbol *nd, ELEMENTO x) devuelve verdadero si pudo insertar un nuevo nodo conteniendo a x como hijo derecho del nodo nd. BOOL SetDer(Nodo_Arbol *nd, ELEMENTO x) igual que SetDer pero como hijo izquierdo del nodo nd. Nodo_Arbol *Padre(Nodo_Arbol *nd) devuelve un apuntador al padre del nodo nd. Nodo_Arbol *Hermano(Nodo_Arbol *nd) devuelve un apuntador al hermano del nodo nd. BOOL EsIzq(Nodo_Arbol *nd) devuelve verdadero si el nodo nd es hijo izquierdo. BOOL EsDer(Nodo_Arbol *nd) devuelve verdadero si el nodo nd es hijo derecho. BOOL EsHoja(Nodo_Arbol *nd) devuelve verdadero si el nodo nd es hoja. 7

La siguiente secuencia de inserciones generara el arbol de la siguiente figura. 6, 3, 9, 10, 5, 7, 2. aux raiz 6 3 9 2 5 7 10 El recorrido en orden del mismo seria: 2, 3, 5, 6, 7, 9, 10. El recorrido en preorden seria: 6, 3, 2, 5, 9, 7, 10. El recorrido en postorden seria: 2, 5, 3, 7, 10, 9, 6. Una llamada a Get_Dato(aux) devolveria 3. Una llamada a Padre(aux) devolveria un apuntador al nodo raiz. Una llamada a Hermano(aux) devolveria un apuntador al nodo que contiene al 9. 8

Un procedimiento inserta quedaria como sigue: template <class T> BOOL Arbol<T>::Inserta2(T x, Nodo_Arbol<T> *ptr){ if(ptr == NULL){//Arbol vacio raiz = creanodo(x); return VERDADERO; else{//arbol no vacio if(x > ptr->getdato())//el dato es mayor que el de el nodo actual if(ptr->getder() == NULL){//hijo derecho esta vacio ptr->setder(creanodo(x)); return VERDADERO; else//el hijo derecho no esta vacio return Inserta2(x, ptr->getder()); if(x < ptr->getdato())//el dato es menor que el de el nodo actual if(ptr->getizq() == NULL){//hijo izquierdo esta vacio ptr->setizq(creanodo(x)); return VERDADERO; else//hijo izquierdo no esta vacio return FALSO; return Inserta2(x, ptr->getizq()); Un procedimiento Anula quedaria como sigue: template <class T> void Arbol<T>::Anula(){ Nodo_Arbol<T> *aux1, *aux2; while(raiz!= NULL){//mientras el arbol no este vacio aux1 = raiz;//aux1 seria el nodo a eliminar while(!eshoja(aux1)){//minetras aux1 no sea una hoja aux2 = aux1;//aux2 es el padre de aux1 if (aux1->getizq()!= NULL)//buscar hoja izquierda aux1 = aux1->getizq(); else77buscar hoja derecha aux1 = aux1->getder(); if (aux1 == raiz){//caso especial, la raiz no tiene padrre delete aux1; raiz = NULL; break; if(aux2->getizq() == aux1)// es aux1 hijo izquierdo? aux2->setizq(null);//apuntar hijo izquierdo a NULL else aux2->setder(null);//apuntar hijo derecho a NULL delete aux1;//eliminar aux1 9