EstructurasDeDatos Java

download EstructurasDeDatos Java

of 33

Transcript of EstructurasDeDatos Java

  • 7/31/2019 EstructurasDeDatos Java

    1/33

    Estructuras de Datos en Java1.Antecedentes

    Introduccin a la Orientacin a Objetos

    La programacin orientada a objetos (POO) es una nueva manera deenfocar la programacin. Desde sus comienzos, la programacin ha estadogobernada por varias metodologas. En cada punto crtico de la evolucin dela programacin se creaba un nuevo enfoque para ayudar al programador amanejar programas cada vez ms complejos. Los primeros programas secrearon mediante un proceso de cambio de los conmutadores del panelfrontal de la computadora. Obviamente, este enfoque solo es adecuado para

    programas pequeos. A continuacin se invento el lenguaje ensamblador quepermiti escribir programas ms largos. El siguiente avance ocurri en losaos 50 cuando se invento el primer lenguaje de alto nivel (FORTRAN).

    Mediante un lenguaje de alto nivel, un programador estaba capacitadopara escribir programas que tuvieran una longitud de varios miles de lneas.Sin embargo, el mtodo de programacin usado en el comienzo era unenfoque adhoc que no solucionaba mucho. Mientras que esto esta bien paraprogramas relativamente cortos, se convierte en cdigo espagueti ilegible ydifcil de tratar cuando se aplica a programas ms largos. La eliminacin delcdigo espagueti se consigui con la creacin de los lenguajes de

    programacin estructurados en los aos sesenta. Estos lenguajes incluyenALGOL y PASCAL. En definitiva, C es un lenguaje estructurado, y casi todos lostipos de programas que se han estado haciendo se podran llamar programasestructurados.

    Los programas estructurados se basan en estructuras de control biendefinidas, bloques de cdigo, la ausencia del GOTO, y subrutinasindependientes que soportan recursividad y variables locales. La esencia de laprogramacin estructurada es la reduccin de un programa a sus elementosconstitutivos. Mediante la programacin estructurada un programador medio

    puede crear y mantener programas de una longitud superior a 50,000 lneas.

    Aunque la programacin estructurada nos ha llevado a excelentesresultados cuando se ha aplicado a programas moderadamente complejos,llega a fallar en algn punto cuando el programa alcanza un cierto tamao.Para poder escribir programas de mayor complejidad se necesitaba de unnuevo enfoque en la tarea de programacin. A partir de este punto nace laprogramacin orientada a objetos (POO). La POO toma las mejores ideasincorporadas en la programacin estructurada y las combina con nuevos ypotentes conceptos que permiten organizar los programas de forma msefectiva. La POO permite descomponer un problema en subgrupos

    relacionados. Cada subgrupo pasa a ser un objeto autocontenido que contienesus propias instrucciones y datos que le relacionan con ese objeto. De esta

  • 7/31/2019 EstructurasDeDatos Java

    2/33

    manera, la complejidad se reduce y el programador puede tratar programasms largos.

    Todos los lenguajes de POO comparten tres caractersticas:encapsulacin, polimorfismo y herencia.

    Encapsulacin.

    La encapsulacin es el mecanismo que agrupa el cdigo y los datos quemaneja y los mantiene protegidos frente a cualquier interferencia y mal uso.En un lenguaje orientado a objetos, el cdigo y los datos suelen empaquetarsede la misma forma en que se crea una caja negra autocontenida. Dentro dela caja son necesarios tanto el cdigo como los datos. Cuando el cdigo y losdatos estn enlazados de esta manera, se ha creado un objeto. En otraspalabras, un objeto es el dispositivo que soporta encapsulacin.

    En un objeto, los datos y el cdigo, o ambos, pueden ser privados paraese objeto o pblicos. Los datos o el cdigo privado solo los conoce o sonaccesibles por otra parte del objeto. Es decir, una parte del programa queesta fuera del objeto no puede acceder al cdigo o a los datos privados.Cuando los datos o el cdigo son pblicos, otras partes del programa puedenacceder a ellos, incluso aunque este definido dentro de un objeto.Normalmente, las partes pblicas de un objeto se utilizan para proporcionaruna interfaz controlada a las partes privadas del objeto.

    Para todos los propsitos, un objeto es una variable de un tipo definidopor el usuario. Puede parecer extrao que un objeto que enlaza cdigo ydatos se pueda contemplar como una variable. Sin embargo, en programacinorientada a objetos, este es precisamente el caso. Cada vez que se define unnuevo objeto, se esta creando un nuevo tipo de dato. Cada instanciaespecfica de este tipo de dato es una variable compuesta.

    Polimorfismo.

    Polimorfismo (del Griego, cuyo significado es muchas formas) es lacualidad que permite que un nombre se utilice para dos o ms propsitos

    relacionados pero tcnicamente diferentes. El propsito del polimorfismoaplicado a la POO es permitir poder usar un nombre para especificar una clasegeneral de acciones. Dentro de una clase general de acciones, la accinespecfica a aplicar est determinada por el tipo de dato. Por ejemplo, en C,que no se basa significativamente en el polimorfismo, la accin de valorabsoluto requiere tres funciones distintas: abs(), labs() y fabs(). Estas tresfunciones calculan y devuelven el valor absoluto de un entero, un entero largoy un valor real, respectivamente. Sin embargo, en C++, que incorporapolimorfismo, a cada funcin se puede llamar abs().

    El tipo de datos utilizado para llamar a la funcin determina que

    versin especfica de la funcin se esta usando, es decir, es posible usar un

  • 7/31/2019 EstructurasDeDatos Java

    3/33

    nombre de funcin para propsitos muy diferentes. Esto se llama sobrecargade funciones.

    De manera general, el concepto de polimorfismo es la idea de unainterfaz, mltiples mtodos. Esto significa que es posible disear una

    interfaz genrica para un grupo de actividades relacionadas. Sin embargo, laaccin especfica ejecutada depende de los datos. La ventaja delpolimorfismo es que ayuda a reducir la complejidad permitiendo que la mismainterfaz se utilice para especificar una clase general de accin. Es trabajo delcompilador seleccionar la accin especfica que se aplica a cada situacin. Elprogramador no necesita hacer esta seleccin manualmente, solo necesitarecordar y utilizar la interfaz general.

    El polimorfismo se puede aplicar tanto a funciones como a operadores,prcticamente todos los lenguajes de programacin contienen una aplicacinlimitada de polimorfismo cuando se relaciona con los operadores aritmticos,

    por ejemplo, en C, el signo + se utiliza par aadir enteros, enteros largos,caracteres y valores reales. En estos casos, el compilador automticamentesabe que tipo de aritmtica debe aplicar, en C++, se puede ampliar esteconcepto a otros tipos de datos que se definan, este tipo de polimorfismo sellama sobrecarga de operadores.

    Herencia.

    La herencia es el proceso mediante el cual un objeto puede adquirir laspropiedades de otro. Mas en concreto, un objeto puede heredar un conjunto

    general de propiedades a alas que puede aadir aquellas caractersticas queson especficamente suyas. La herencia es importante porque permite que unobjeto soporte el concepto de clasificacin jerrquica. Mucha informacin sehace manejable gracias a esta clasificacin, por ejemplo, la descripcin deuna casa. Una casa es parte de una clase general llamada edificio, a su vez,edificio es una parte de la clase mas general estructura, que es parte de laclase aun ms general de objetos que se puede llamar obra-hombre.

    En cualquier caso, la clase hija hereda todas las cualidades asociadas conla clase padre y le aade sus propias caractersticas definitorias. Sin el uso declasificaciones ordenadas, cada objeto tendra que definir todas las

    caractersticas que se relacionan con l explcitamente.

    Sin embargo, mediante el uso de la herencia, es posible describir unobjeto estableciendo la clase general (o clases) a las que pertenece, juntocon aquellas caractersticas especficas que le hacen nico.

    Tipos de Datos Abstractos

    Abstraccin: consiste en ignorar los detalles de la manera particular enque est hecha una cosa, quedndonos solamente con su visin general. Tipode Dato Abstracto (TDA) se define como un conjunto de valores que pueden

    tomar los datos de ese tipo, junto a las operaciones que los manipulan.

  • 7/31/2019 EstructurasDeDatos Java

    4/33

    Un TDA es un modelo matemtico de estructuras de datos que especifican lostipos de datos almacenados, las operaciones definidas sobre esos datos y lostipos de parmetros de esas operaciones.

    TAD = Valores (tipo de dato) + operaciones

    Un TDA define lo que cada operacin debe hacer, ms no como la debehacer. En un lenguaje de programacin como Java un TDA puede serexpresado como una interface, que es una simple lista de declaraciones demtodos.

    Un TDA es materializado por una estructura de datos concreta, en Java,es modelada por una clase. Una clase define los datos que sern almacenadosy las operaciones soportadas por los objetos que son instancia de la clase. Alcontrario de las interfaces, las clases especifican como las operaciones sonejecutadas (implementacin).

    Ejemplos de tipos de datos abstractos son las Listas, Pilas, Colas, etc., que sediscutirn ms adelante.

    Estructuras de Datos

    En programacin, una estructura de datos es una forma de organizar unconjunto de datos elementales (un dato elemental es la mnima informacinque se tiene en el sistema) con el objetivo de facilitar la manipulacin deestos datos como un todo y/o individualmente.

    Una estructura de datos define la organizacin e interrelacionamiento deestos, y un conjunto de operaciones que se pueden realizar sobre l. Lasoperaciones bsicas son:

    Alta, adicionar un nuevo valor a la estructura. Baja, borrar un valor de la estructura. Bsqueda, encontrar un determinado valor en la estructura para se

    realizar una operacin con este valor, en forma SECUENCIAL o BINARIO(siempre y cuando los datos estn ordenados).

    Otras operaciones que se pueden realizar son:

    Ordenamiento, de los elementos pertenecientes a la estructura. Apareo, dadas dos estructuras originar una nueva ordenada y que

    contenga a las apareadas.

    Cada estructura ofrece ventajas y desventajas en relacin a la simplicidady eficiencia para la realizacin de cada operacin. De esta forma, la eleccinde la estructura de datos apropiada para cada problema depende de factorescomo las frecuencias y el orden en que se realiza cada operacin sobre losdatos.

    Algunas estructuras de datos utilizadas en programacin son:

  • 7/31/2019 EstructurasDeDatos Java

    5/33

    Arrays (Arreglos)o Vectoreso Matrices

    Listas Enlazadaso Listas simpleso Listas dobleso Listas Circulares

    Pilas Colas rboles

    o rboles binarioso rboles Multicamino

    Conjuntos Grafos Montculos

    Acceso directo y secuencial a los datos

    Secuencial. Para acceder a un objeto se debe acceder a los objetosalmacenados previamente en el archivo. El acceso secuencial exigeelemento a elemento, es necesario una exploracin secuencialcomenzando desde el primer elemento.

    Directo o Aleatorio. Se accede directamente al objeto, sin recorrer losanteriores. El acceso directo permite procesar o acceder a un elemento

    determinado haciendo una referencia directamente por su posicin en elsoporte de almacenamiento.

    Resumen de Java

    2.Arreglos

    Arreglos lineales

    Un arreglo se usa para agrupar, almacenar y organizar datos de un mismotipo. En un arreglo cada valor se almacena en una posicin numeradaespecfica dentro del arreglo. El nmero correspondiente a cada posicin seconoce como ndice.

    La estructura de un arreglo es:

  • 7/31/2019 EstructurasDeDatos Java

    6/33

    Normalmente el primer objeto del arreglo tiene el ndice 0, aunque esto varade lenguaje en lenguaje.

    Declaracin:

    Como se sabe, hay 2 tipos de datos en Java: primitivos (como int y double) yobjetos. En muchos lenguajes de programacin (an en Orientados a Objetoscomo C++) los arreglos son tipos primitivos, pero en Java son tratados comoobjetos. Por consiguiente, se debe utilizar el operador new para crear unarreglo:

    int miArreglo[]; // define la referencia a un arreglomiArreglo = new int[100]; // crea el arreglo y establece miArreglo

    // como referencia a l

    O el equivalente a hacerlo dentro de una misma sentencia

    int miArreglo[] = new int[100];

    El operador [] es la seal para el compilador que estamos declarando unarreglo (objeto) y no una variable ordinaria. Dado que un arreglo es unobjeto, el nombre miArreglo-, en el ejemplo anterior- es una referencia a un arregloy no el nombre del arreglo como tal. El arreglo es almacenado en unadireccin de memoria x, y miArreglo almacena solo esa direccin de memoria.

    Los arreglos tienen el mtodo length, el cual se utiliza para encontrar eltamao de un arreglo:

    int tamao = miArreglo.length; // arroja el tamao del arreglo

    Para acceder a los elementos de un arreglo se debe utilizar los corchetes, muysimilar a otros lenguajes de programacin:

    temp = miArreglo[4]; // guarda en temp el valor del cajn 4 del arreglomiArreglo[8] = 50; // almacena en el cajon 8 del arreglo el valor 50

    Es preciso recordar que en Java, como en C y C++, el primer elemento delarreglo es el 0. Luego entonces, los ndices de un arreglo de 10 elementos vandel 0 al 9.

    Ejemplo:

  • 7/31/2019 EstructurasDeDatos Java

    7/33

    // array.java// demonstrates Java arrays////////////////////////////////////////////////////////////////class ArrayApp{public static void main(String[] args) {

    int[] arr; // referencearr = new int[100]; // make arrayint nElems = 0; // number of itemsint j; // loop counterint searchKey; // key of item to search for

    //--------------------------------------------------------------arr[0] = 77; // insert 10 itemsarr[1] = 99;arr[2] = 44;arr[3] = 55;arr[4] = 22;arr[5] = 88;arr[6] = 11;

    arr[7] = 00;arr[8] = 66;arr[9] = 33;nElems = arr.length; // now 10 items in array

    //-------------------------------------------------------------for (j=0; j

  • 7/31/2019 EstructurasDeDatos Java

    8/33

    Found 6677 99 44 22 88 11 0 66 33

    Operaciones sobre arreglos

    Se pueden implementar una serie de operaciones bsicas sobre losarreglos, a saber:

    - Insertar elementos- Bsqueda de elementos- Eliminar elementos- Mostrar los elementos- Ordenar los elementos- Modificar algn elemento

    Arreglos bidimensionales

    Un arreglo de dos dimensiones, tambin llamado tabla o matriz, donde cadaelemento se asocia con una pajera de ndices, es otro arreglo simple.Conceptualizamos un arreglo bidimensional como una cuadrcula rectangularde elementos divididos en filas y columnas, y utilizamos la notacin (fila,columna) para identificar un elemento especfico. La siguiente figura muestrala visin conceptual y la notacin especfica de los elementos:

    El trabajo con los arreglos bidimensionales es muy parecido a los arregloslineales, la declaracin de uno de ellos se da de la siguiente manera:

    double [][] temperatures = new double [2][2]; // Dos filas y dos columnas.

    La asignacin de datos, se hace de una forma similar a los arreglos lineales:

    temperatures [0][0] = 20.5; // Populate row 0temperatures [0][1] = 30.6;temperatures [0][2] = 28.3;

    temperatures [1][0] = -38.7; // Populate row 1

    temperatures [1][1] = -18.3;temperatures [1][2] = -16.2;

  • 7/31/2019 EstructurasDeDatos Java

    9/33

    Las operaciones con las matrices son muy variadas, desde las bsicas comoinsertar y eliminar elementos hasta multiplicaciones de matrices, entre otras.

    3.Listas ligadas

    Definicin

    En el captulo anterior, vimos a la estructura llamada arreglos ovectores. Esta estructura presenta ciertas desventajas:

    o en un arreglo desordenado, la bsqueda es lentao en un arreglo ordenado, la insercin es lentao en ambos casos, la eliminacin es lentao el tamao de un arreglo no puede cambiar despus que se cre

    Ahora veremos una estructura de datos que resuelve los problemas anteriores,llamada lista ligada. Las listas ligadas, son probablemente, la segundaestructura de almacenamiento de propsito general ms comnmenteutilizadas, despus de los arreglos.

    Una lista ligada es un mecanismo verstil conveniente para su uso en muchostipos de bases de datos de propsito general. Tambin puede reemplazar a losarreglos como base para otras estructuras de almacenamiento como pilas y

    colas.La ventaja ms evidente de utilizar estructuras ligadas, es que permiteoptimizar el uso de la memoria, pues no desperdiciamos el espacio delocalidades vacas:

    La desventaja ms grande de las estructuras ligadas es que deben serrecorridas desde su inicio para localizar un dato particular. Es decir, no hayforma de acceder al i-simo dato de la lista, como lo haramos en un arreglo.

    Algunas listas ms complejas son las listas doblemente ligadas o las listascirculares, por nombrar algunas.

  • 7/31/2019 EstructurasDeDatos Java

    10/33

    Lista doblemente ligada

    Lista circular

    Listas desordenadas

    Desde el punto de vista de programacin, una lista es una estructura dedatos dinmica que contiene una coleccin de elementos homogneos, conuna relacin lineal entre ellos. Una relacin lineal significa que cadaelemento (a excepcin del primero) tiene un precedente y cada elemento (aexcepcin del ltimo) tiene un sucesor.

    Grficamente, una lista se puede conceptualizar de la siguiente forma:

    Lgicamente, una lista es tan solo un objeto de una clase Lista que seconforma de un tope (posicin de inicio) de lista y un conjunto de mtodospara operarla.

    Se pueden implementar listas estticas utilizando arreglos de N elementosdonde se almacenen los datos. Recordemos la desventaja de esto.

    Tope de la Lista

  • 7/31/2019 EstructurasDeDatos Java

    11/33

    Listas ordenadasUna lista ordenada, es una extensin de las listas normales con la cualidad

    de que todos sus datos se encuentran en orden. Como al igual que las listas sedebe poder insertar datos, hay dos formas de garantizar el orden de los

    mismos:

    o crear un mtodo de insercin ordenadao crear un mtodo de ordenamiento de la lista

    Operaciones sobre listas

    Los distintos mtodos de la clase Lista deben asegurarnos poder insertar,eliminar u obtener un dato en cualquier posicin de la lista.

    Como se mencion, una lista se compone de

    - un tope de la lista, que es un objeto de la clase NodoDeLista- un conjunto de instrucciones que controlen su estructura

    La clase NodoDeLista debe contener al menos un espacio de almacenamientode datos y un objeto de la clase NodoDeLista no necesariamente instanciado.La clase NodoDeLista debe ser nuestra clase base, que incorporar losconstructores necesarios para inicializar nuestros datos. El objetivo es unaestructura de clase que nos represente:

    Ejemplo clase NodoDeLista

    La clase Lista

    La clase lista contiene:

    o un objeto de tipo NodoDeLista que ser la primera referencia denuestra lista

    Nuestro Dato

    public class NodoDeLista{String dato;NodoDeLista siguiente;public NodoDeLista(){

    dato = ;siguiente = null;

    }public NodoDeLista(String d){

    dato = d;siguiente = null;

    }}

  • 7/31/2019 EstructurasDeDatos Java

    12/33

    o un grupo de constructores para inicializarlao un grupo de operaciones para el control de la lista, tales como:

    insertar un nuevo NodoDeLista buscar un NodoDeLista eliminar un NodoDeLista obtener un NodoDeLista en alguna posicin mostrar la lista

    Se crearn los mtodos uno a uno. La primera aproximacin quedara as:

    public class Lista{NodoDeLista tope;public Lista(){}void insertar(int){}void eliminar(int){}int buscar(int){}boolean vacia();

    void mostrar(){}}

    En el ejemplo, se incluye un constructor que crea una lista vaca.

    Insertar en una lista

    Insertar un dato en una lista se refiere a recorrerla para agregar un dato alfinal de la lista (listas desordenadas) o en una posicin determinada (listasordenadas). En este caso, insertamos el NodoDeLista al final de la lista. Elrecorrido se inicia haciendo actual = tope:

    1. Crear un nuevo NodoDeLista

    2. Recorrer la lista hasta el final, es decir, cuando el valor del camposiguiente del nodo es NULL

    3. El nuevo NodoDeLista ahora es parte de la lista

    Consideraciones:

    a) qu pasa si la lista esta vaca?

    NULLTope de la lista

    Tope de la lista

    NULL

  • 7/31/2019 EstructurasDeDatos Java

    13/33

    Eliminar un nodo de la lista

    Eliminar un nodo significa quitarlo, no importando su posicin, pero cuidandoque no se pierdan los datos. Para eliminar un nodo, primero debemosencontrarlo. El recorrido se inicia haciendo igual = tope:

    1. Localizar el nodo que queremos eliminar

    2. Localizando el nodo de la lista, cambiar el campo siguiente del nodoanterior hacia el siguiente del nodo a eliminar.

    3. Como ningn objeto hace referencia al nodo, este se eliminar alterminar de ejecutarse el mtodo.

    Mostrar la lista

    El mtodo mostrar escribe a pantalla el contenido de la lista, demanera que podamos confirmar su contenido. El mtodo es tan sencillo comorecorrer la lista elemento a elemento y escribir su contenido en la pantalla,hasta que encontremos el final de la lista. El recorrido, como todos se iniciahaciendo actual = tope.

    Funciones adicionales

    Se pueden construir un grupo de funciones adicionales que nosproporcionen informacin sobre la lista, tales como:

    a) tamao de la listab) lista vaca

    Tope de lalista

    null

    Nodo que seeliminar

    Tope de lalista

    null

    Nodo que seeliminar

    Tope de lalista

    null

    Nodo que seeliminar

  • 7/31/2019 EstructurasDeDatos Java

    14/33

    c) fin de la listad) insertar en una lista ordenadae) ordenar una lista desordenadaf) buscar un elemento de la lista

    4.Pilas

    Definicin

    Considere los elementos de la figura siguiente:

    Aunque los objetos son todos diferentes, todos ilustran el concepto de pila(stack). Una pila, es una particularizacin de las listas y se puede definir comouna estructura en la cual los elementos son agregados y eliminados en el topede la lista. Es una estructura LIFO (Last In First Out el primero que llega es el ltimoque sale).

    Por ejemplo, si nuestra camisa favorita azul se encuentra debajo de lavieja camisa roja que se encuentra en el tope de las camisas, primerodebemos sacar a la camisa roja. Solamente as podremos sacar a la camisaazul, la cual ahora esta en el tope de la pila de camisas. Una ves sacada lacamisa azul, podemos regresar a la vieja camisa roja al tope de la pila.

    Las pilas cuentan solo con 2 operaciones, conocidas como PUSH, insertarun elemento en el tope de la pila, y POP, leer el elemento del tope de la pila.Veamos como funcionan estos mtodos:

  • 7/31/2019 EstructurasDeDatos Java

    15/33

    PUSH

    1.- Crear un NodoDeLista nuevo

    2.- Hacer el siguiente de nuevo igual al tope

    3.- Hacer el tope de la pila igual al nuevo nodo

    Se ha agregado el dato a la pila!!

    POP

    1.- Crear un nodo temporal que se instancia al tope de la pila

    Topede lapila

    Topede lapila

    Tope de la pila

    Tope aux

  • 7/31/2019 EstructurasDeDatos Java

    16/33

    2.- Hacer el tope de la pila igual al siguiente del temporal

    3.- Regresar el valor del nodo temporal antes que desaparezca

    Implementacin de pilas

    Para trabajar con pilas, utilizaremos la misma base con la que trabajamospara las listas. Dispondremos de 2 clases: Pila y NodoDePila. Con la primeracrearemos a la pila y las operaciones sobre ella y con la segundainstanciaremos a cada uno de los nodos de la pila.

    public class Pila{NodoDePila tope;public Pila(){}void Push(){}int Pop(){}void mostrar(){}

    }

    Tope

    Tope

    class NodoDePila{int num;NodoDeLista sig;public NodoDePila(){

    num = 0;sig = null;

    }public NodoDePila(int n){

    num = n;sig = null;

    }public NodoDePila(int n,NodoDePila s){

    num = n;sig = s;

    }}

  • 7/31/2019 EstructurasDeDatos Java

    17/33

    5.Colas

    Definicin

    Una cola es una estructura de datos similar a una lista con restriccionesespeciales. Los elementos son agregados en la parte posterior de la cola y soneliminados por el frente. Esta estructura es llamada FIFO (F irst In, First Out elprimero que llega, es el primero en salir). Considere la siguiente figura:

    Si una persona ha elegido sus libros dentro de la librera y desea pasar apagarlos, debe hacer cola para poder efectuar el pago. La cajera atendera cada persona en el orden en que llegaron.

    A nivel de lgico, podemos representar a una cola de la siguiente manera:

    ltimo primero

  • 7/31/2019 EstructurasDeDatos Java

    18/33

    Construccin de colas

    Implementar colas involucra el uso clases similares a una lista. Lasoperaciones sobre esta estructura son idnticas: insertar y eliminar, con las

    consideraciones pertinentes.

    Insertar

    Insertar un dato en una cola es muy similar a hacerlo en una pila o unalista, la diferencia es que tendremos que hacerlo por el final de la cola. Aeste proceso se le llama encolar.

    1.- Cola inicial

    2.- Creamos el nuevo nodo

    3.- Hacemos que ltimo apunte al nuevo nodo

    Eliminar

    Para extraer un dato de la cola, es necesario modificar el valor del nodoprimero, de manera que deje de apuntar al primer elemento de la cola. De la

    misma manera que con las pilas, se extrae el valor antes de que se pierda. Se

    ltimo primero

    ltimo primero

    ltimo primero

  • 7/31/2019 EstructurasDeDatos Java

    19/33

    hace que el nodo primero ahora apunte al nuevo elemento (anterior de lacola).

    1.-

    2.-

    3.-

    ltimo primero

    ltimo ltimo

    ltimo primero

  • 7/31/2019 EstructurasDeDatos Java

    20/33

    6.rboles

    Recursin

    Alguna vez hemos visto ese conjunto de muecos de madera de origen ruso(matrioshkas) en la que uno se encuentra dentro de otro. Dentro del primermueco, se encuentra un mueco menor, y dentro de ese mueco, hay otromueco de menor tamao y as sucesivamente. Un mtodo recursivo es comolos muecos rusos: se reproducen a s mismo con versiones ms y mspequeas.

    Recursin es la capacidad de un mtodo o funcin de invocarse a s mismopara resolver un problema [1]. Cada vez que un mtodo se llama a s mismo,se enva una parte ms pequea del problema, a fin de encontrar una solucina la misma.

    En Java, un mtodo puede llamar a otros mtodos, pero adems, sepuede llamar a s mismo! Haciendo una llamada recursiva.

    La recursin se forma de dos elementos:

    - Caso base. El momento en que se detiene la recursin- Llamada recursiva. Invocacin del mtodo a s mismo

    Cuando se alcanza el caso base, la recursin comienza un proceso llamadobacktracking (retroceso), resolviendo las llamadas anteriores de s mismo.

    Ejemplo clsico de recursin

    El calculo del factorial de un nmero, es el mtodo ms recurrido paraexplicar la recursin. Supongamos que solamente sabemos la definicin defactorial:

    o El factorial de 0 (cero), es igual a 1 (caso base)o El factorial de N, es igual a N multiplicado por el factorial de N-1

    (llamada recursiva)

  • 7/31/2019 EstructurasDeDatos Java

    21/33

    Calculemos el factorial de 3

    Factorial(3) = 3 x Factorial(3-1) // por definicinFactorial(3) = 3 x Factorial(2)

    Pero ahora nos damos cuenta que desconocemos el factorial de 2, as queprocedemos a calcularlo

    Factorial(2) = 2 x Factorial(2-1) // por definicinFactorial(2) = 2 x Factorial(1)

    Seguimos sin conocer el factorial de 3, de 2, y ahora de 1. As que pasamosa calcular el factorial de 1

    Factorial(1) = 1 x Factorial(1-1) // por definicinFactorial(1) = 1 x Factorial(0)

    Conocemos el factorial de 0 (cero) que es 1 (nuestro caso base), por lo quecomenzamos a resolver e iniciar el backtracking.

    Factorial(1) = 1 x Factorial(0) = 1 x 1 = 1Factorial(2) = 2 x Factorial(1) = 2 x 1 = 2Factorial(3) = 3 x Factorial(2) = 3 x 2 = 6

    El factorial de 3, es igual a 6 ( 3 x 2 x 1).

    Para programar recursin, debemos tener en cuenta que siempre debeexistir una forma de llegar al caso base, de lo contrario, las llamadasrecursivas seran infinitas. La recursin se utiliza siempre que deseemosresolver un problema a travs de l mismo, mediante fracciones ms sencillasde l.

    Existen diversas aplicaciones para la recursin, tales como clculosmatemticos, trabajo con listas o rboles, etc. Ejemplos:

    Sucesin de Fibonacci Encontrar un nodo hoja en rboles Recorrer una lista Etc

  • 7/31/2019 EstructurasDeDatos Java

    22/33

    Definicin

    Un rbol es una estructura no lineal en la que cada nodo puede apuntar auno o varios nodos. Tambin se suele dar una definicin recursiva: un rbol es

    una estructura compuesta por un dato y varios rboles. La forma grfica sepuede apreciar como sigue:

    En relacin con los nodos, debemos definir algunos conceptos como: Nodo hijo: cualquiera de los nodos apuntados por uno de los

    nodos del rbol. En el ejemplo, L y M son hijos de G. Nodo padre: nodo que contiene un puntero al nodo actual. En el

    ejemplo, A es padre de B, C y D.

    En cuanto a la posicin dentro del rbol, tenemos: Nodo raz: nodo que no tiene padre. Este es el nodo que

    usaremos para acceder al rbol. En el ejemplo, ese nodo es A. Nodo hoja: nodo que no tiene hijos. En el ejemplo, hay varios:

    K, M, O, etc. Nodo rama: aunque esta definicin apenas la usaremos, estos

    son los nodos que no pertenecen a ninguna de las dos categorasanteriores. En el ejemplo B, G, D, J, etc.

    Existen otros conceptos que definen las caractersticas del rbol, enrelacin a su tamao:

    Orden: es el nmero potencial de hijos que puede tener cadaelemento del rbol. De este modo, diremos que un rbol en elque cada nodo puede apuntar a otros dos, es de orden dos, sipuede apuntar a tres, es de orden tres, etc.

    Grado: es el nmero de hijos que tiene el elemento con mshijos dentro del rbol. En el rbol de ejemplo, el grado es tres,ya que tanto A como D tienen tres hijos y no existenelementos con ms de tres hijos.

    Nivel: se define para cada elemento del rbol como la distanciaa la raz, medida en nodos. El nivel de la raz es cero, y el de sushijos uno, as sucesivamente. En el ejemplo, el nodo D tienenivel uno, el nodo G tiene nivel dos, el nodo N nivel tres.

  • 7/31/2019 EstructurasDeDatos Java

    23/33

    Altura: la altura de un rbol se define como el nivel del nodo demayor nivel. Como cada nodo de un rbol puede considerarse asu vez como la raz de un rbol, tambin podemos hablar dealtura de ramas. El rbol de ejemplo, tiene altura tres, la ramaB tiene altura dos, la rama G tiene altura uno, la H cero,

    etc.

    rboles binarios

    Los rboles de orden dos son bastante especiales, de hecho lesdedicaremos varios captulos. Estos rboles se conocen tambin como rbolesbinarios.

    Un rbol binario, requiere de una estructura de NODO que permitaalmacenar el dato correspondiente, adems de una referencia al hijoizquierdo y una ms al hijo derecho. El rbol ser una liga al nodo raz, apartir del cual, se podr acceder al resto de la estructura.

    Operaciones bsicas con rboles

    Salvo que trabajemos con rboles especiales, como los que veremos msadelante, las inserciones sern siempre en punteros de nodos hoja o enpunteros libres de nodos rama. Con estas estructuras no es tan fcilgeneralizar, ya que existen muchas variedades de rboles.

    De nuevo tenemos casi el mismo repertorio de operaciones de las quedisponamos con las listas:

    public class NodoDeArbol {int dato;NodoDeArbol izq;NodoDeArbol der;

    }

    public class Arbol {NodoDeArbol raiz;public Arbol() {

    raiz = null;}public Arbol(int d) {

    raiz = new NodoDeArbol(d);}public Arbol(NodoDeArbol n) {

    raiz = n;}

    }

  • 7/31/2019 EstructurasDeDatos Java

    24/33

    Aadir o insertar elementos. Buscar o localizar elementos. Borrar elementos. Moverse a travs del rbol. Recorrer el rbol completo.

    Los algoritmos de insercin y borrado dependen en gran medida del tipo derbol que estemos implementando, de modo que por ahora los pasaremos poralto y nos centraremos ms en el modo de recorrer rboles.

    Recorridos

    El modo evidente de moverse a travs de las ramas de un rbol essiguiendo los punteros (referencias), del mismo modo en que nos movamos atravs de las listas.

    Esos recorridos dependen en gran medida del tipo y propsito del rbol,pero hay ciertos recorridos que usaremos frecuentemente. Se trata deaquellos recorridos que incluyen todo el rbol.

    Hay tres formas de recorrer un rbol completo, y las tres se suelenimplementar mediante recursividad. En los tres casos se sigue siempre apartir de cada nodo todas las ramas una por una.

    Supongamos que tenemos un rbol de orden tres, y queremos recorrerlo

    por completo. Partiremos del nodo raz:RecorrerArbol(raiz);

    La funcin RecorrerArbol, aplicando recursividad, ser tan sencilla comoinvocar de nuevo a la funcin RecorrerArbol para cada una de las ramas:

    void RecorrerArbol (NodoDeArbol aux) {if (aux == NULL) return;RecorrerArbol(aux.der);RecorrerArbol(aux.izq);

    }

    Lo que diferencia los distintos mtodos de recorrer el rbol no es elsistema de hacerlo, sino el momento que elegimos para procesar el valor decada nodo con relacin a los recorridos de cada una de las ramas.

  • 7/31/2019 EstructurasDeDatos Java

    25/33

    Los tres tipos son:

    Pre-orden:

    En este tipo de recorrido, el valor del nodo se procesa antes de recorrerlas ramas:

    void PreOrden(NodoDeArbol a) {if (a == NULL) return;Procesar(dato); //mtodo que lee el datoRecorrerArbol(a.izq);RecorrerArbol(a.centro);RecorrerArbol(a.der);

    }

    Si seguimos el rbol del ejemplo en pre-orden, y el proceso de los datos essencillamente mostrarlos por pantalla, obtendremos algo as:

    A B E K F C G L M D H I J N O

    In-orden:

    En este tipo de recorrido, el valor del nodo se procesa despus de recorrerla primera rama y antes de recorrer la ltima. Esto tiene ms sentido en elcaso de rboles binarios, y tambin cuando existen ORDEN-1 datos, en cuyocaso procesaremos cada dato entre el recorrido de cada dos ramas (este es elcaso de los rboles-b):

    void InOrden(NodoDeArbol a) {if (a == NULL) return;RecorrerArbol(a.izq);Procesar(dato); //mtodo que lee el datoRecorrerArbol(a.centro);RecorrerArbol(a.der);

    }

    Si seguimos el rbol del ejemplo en in-orden, y el proceso de los datos essencillamente mostrarlos por pantalla, obtendremos algo as:

  • 7/31/2019 EstructurasDeDatos Java

    26/33

    K E B F A L G M C H D I N J O

    Post-orden:

    En este tipo de recorrido, el valor del nodo se procesa despus de recorrer

    todas las ramas:

    void PostOrden(NodoDeArbol a) {if (a == NULL) return;RecorrerArbol(a.izq);RecorrerArbol(a.centro);RecorrerArbol(a.der);Procesar(dato); //mtodo que lee el dato

    }

    Si seguimos el rbol del ejemplo en post-orden, y el proceso de los datos

    es sencillamente mostrarlos por pantalla, obtendremos algo as:

    K E F B L M G C H I N O J D A

    Arboles ordenados

    Un rbol ordenado, en general, es aquel a partir del cual se puede obteneruna secuencia ordenada siguiendo uno de los recorridos posibles del rbol:

    inorden, preorden o postorden.En estos rboles es importante que la secuencia se mantenga ordenadaaunque se aadan o se eliminen nodos.

    Existen varios tipos de rboles ordenados, que veremos a continuacin:

    rboles binarios de bsqueda (ABB): son rboles de orden 2 quemantienen una secuencia ordenada si se recorren en inorden.

    rboles AVL: son rboles binarios de bsqueda equilibrados, es decir,los niveles de cada rama para cualquier nodo no difieren en ms de 1.

    rboles perfectamente equilibrados: son rboles binarios de bsquedaen los que el nmero de nodos de cada rama para cualquier nodo nodifieren en ms de 1. Son por lo tanto rboles AVL tambin.

    rboles 2-3: son rboles de orden 3, que contienen dos claves en cadanodo y que estn tambin equilibrados. Tambin generan secuenciasordenadas al recorrerlos en inorden.

    rboles-B: caso general de rboles 2-3, que para un orden M, contienenM-1 claves.

  • 7/31/2019 EstructurasDeDatos Java

    27/33

    rboles binarios de bsqueda (ABB)

    Se trata de rboles de orden 2 en los que se cumple que para cadanodo, el valor del nodo raz del subrbol izquierdo es menor que el valor delnodo raz y que el valor del nodo raz del subrbol derecho es mayor que el

    valor del nodo raz.

    Operaciones en ABB.

    El conjunto de operaciones que se pueden realizar sobre un ABB essimilar al que se realiza sobre otras estructuras de datos, ms alguna otrapropia de rboles:

    Buscar un elemento. Insertar un elemento. Eliminar un elemento. Movimientos a travs del rbol:

    oIzquierda.oDerecha.oRaz.

    Informacin:oComprobar si un rbol est vaco.oCalcular el nmero de nodos.oComprobar si el nodo es hoja.oCalcular el nivel de un nodo.oCalcular la altura de un rbol.

    Buscar un elemento.

    Partiendo siempre del nodo raz, el modo de buscar un elemento sedefine de forma recursiva como:

    Si el rbol est vaco, terminamos la bsqueda: el elemento no esten el rbol.

    Si el valor del nodo raz es igual que el del elemento que buscamos,terminamos la bsqueda con xito.

    Si el valor del nodo raz es mayor que el elemento que buscamos,continuaremos la bsqueda en el rbol izquierdo.

  • 7/31/2019 EstructurasDeDatos Java

    28/33

    Si el valor del nodo raz es menor que el elemento que buscamos,continuaremos la bsqueda en el rbol derecho.

    El valor de retorno de una funcin de bsqueda en un ABB puede ser unpuntero al nodo encontrado, o NULL, si no se ha encontrado.

    Insertar un elemento.

    Para insertar un elemento nos basamos en el algoritmo de bsqueda. Siel elemento est en el rbol no lo insertaremos. Si no lo est, lo insertaremosa continuacin del ltimo nodo visitado. Para ello, se necesita un punteroauxiliar para conservar una referencia al padre del nodo raz actual. El valorinicial para ese puntero es NULL.

    Padre = NULL nodo = Raiz Bucle: mientras actual no sea un rbol vaco o hasta que se encuentre

    el elemento.o Si el valor del nodo raz es mayor que el elemento que

    buscamos, continuaremos la bsqueda en el rbol izquierdo:

    Padre=nodo, nodo=nodo->izquierdo.

    o Si el valor del nodo raz es menor que el elemento quebuscamos, continuaremos la bsqueda en el rbol derecho:

    Padre=nodo, nodo=nodo->derecho. Si nodo no es NULL, el elemento est en el rbol, por lo tanto salimos. Si Padre es NULL, el rbol estaba vaco, por lo tanto, el nuevo rbol

    slo contendr el nuevo elemento, que ser la raz del rbol. Si el elemento es menor que el Padre, entonces insertamos el nuevo

    elemento como un nuevo rbol izquierdo de Padre. Si el elemento es mayor que el Padre, entonces insertamos el nuevo

    elemento como un nuevo rbol derecho de Padre.

    Este modo de actuar asegura que el rbol sigue siendo ABB.

    Eliminar un elemento.

    Para eliminar un elemento tambin nos basamos en el algoritmo debsqueda. Si el elemento no est en el rbol no lo podremos borrar. Si est,hay dos casos posibles:

    1. Se trata de un nodo hoja: en ese caso lo borraremos directamente.2. Se trata de un nodo rama: en ese caso no podemos eliminarlo, puesto

    que perderamos todos los elementos del rbol de que el nodo actual espadre. En su lugar buscamos el nodo ms a la izquierda del subrbolderecho, o el ms a la derecha del subrbol izquierdo eintercambiamos sus valores. A continuacin eliminamos el nodo hoja.

  • 7/31/2019 EstructurasDeDatos Java

    29/33

    Necesitamos un puntero auxiliar para conservar una referencia al padredel nodo raz actual. El valor inicial para ese puntero es NULL.

    Padre = NULL Si el rbol est vaco: el elemento no est en el rbol, por lo tanto

    salimos sin eliminar ningn elemento. (*) Si el valor del nodo raz es igual que el del elemento que buscamos,

    estamos ante uno de los siguientes casos:o El nodo raz es un nodo hoja:

    Si 'Padre' es NULL, el nodo raz es el nico del rbol, porlo tanto el puntero al rbol debe ser NULL.

    Si raz es la rama derecha de 'Padre', hacemos que esarama apunte a NULL.

    Si raz es la rama izquierda de 'Padre', hacemos que esarama apunte a NULL.

    Eliminamos el nodo, y salimos.o El nodo no es un nodo hoja:

    Buscamos el 'nodo' ms a la izquierda del rbol derecho deraz o el ms a la derecha del rbol izquierdo. Hay quetener en cuenta que puede que slo exista uno de esosrboles. Al mismo tiempo, actualizamos 'Padre' para queapunte al padre de 'nodo'.

    Intercambiamos los elementos de los nodos raz y 'nodo'. Borramos el nodo 'nodo'. Esto significa volver a (*), ya que

    puede suceder que 'nodo' no sea un nodo hoja. Si el valor del nodo raz es mayor que el elemento que buscamos,

    continuaremos la bsqueda en el rbol izquierdo. Si el valor del nodo raz es menor que el elemento que buscamos,continuaremos la bsqueda en el rbol derecho.

    Ejemplos de eliminacin en un ABB.

    Ejemplo 1: Eliminar un nodo hoja

    En el rbol de ejemplo, eliminar el nodo 3.

    1. Localizamos el nodo a borrar, al tiempo que mantenemos un puntero

    a 'Padre'.2. Hacemos que el puntero de 'Padre' que apuntaba a 'nodo', ahoraapunte a NULL.

    3. Borramos el 'nodo'.

  • 7/31/2019 EstructurasDeDatos Java

    30/33

    Ejemplo 2: Eliminar un nodo rama con intercambio de un nodo hoja.

    En el rbol de ejemplo, eliminar el nodo 4.

    1. Localizamos el nodo a eliminar (nodo raz).2. Buscamos el nodo ms a la derecha del rbol izquierdo de 'raz',en este caso el 3, al tiempo que mantenemos un puntero a 'Padre' a'nodo'.

    3. Intercambiamos los elementos 3 y 4.4. Hacemos que el puntero de 'Padre' que apuntaba a 'nodo', ahora

    apunte a NULL.5. Borramos el 'nodo'.

    Ejemplo 3: Eliminar un nodo rama con intercambio de un nodo rama.

    Para este ejemplo usaremos otro rbol. En ste borraremos el elemento 6.

  • 7/31/2019 EstructurasDeDatos Java

    31/33

    1. Localizamos el nodo a eliminar (nodo raz).2. Buscamos el nodo ms a la izquierda del rbol derecho de 'raz',

    en este caso el 12, ya que el rbol derecho no tiene nodos a suizquierda, si optamos por la rama izquierda, estaremos en un casoanlogo. Al mismo tiempo que mantenemos un puntero a 'Padre' a

    'nodo'.3. Intercambiamos los elementos 6 y 12.4. Ahora tenemos que repetir el bucle para el nodo 6 de nuevo, ya

    que no podemos eliminarlo.

    5. Localizamos de nuevo el nodo a eliminar (nodo raz).6. Buscamos el nodo ms a la izquierda del rbol derecho de 'raz',

    en este caso el 16, al mismo tiempo que mantenemos un puntero a'Padre' a 'nodo'.

    7. Intercambiamos los elementos 6 y 16.8. Hacemos que el puntero de 'Padre' que apuntaba a 'nodo', ahora

    apunte a NULL.9. Borramos el 'nodo'.

    Este modo de actuar asegura que el rbol sigue siendo ABB.

    Movimientos a travs de un rbol

    No hay mucho que contar. Nuestra estructura se referenciar siempremediante un puntero al nodo Raz, este puntero no debe perderse nunca.

    Para movernos a travs del rbol usaremos punteros auxiliares, de modo que

    desde cualquier puntero los movimientos posibles sern: moverse al nodo raz

  • 7/31/2019 EstructurasDeDatos Java

    32/33

    de la rama izquierda, moverse al nodo raz de la rama derecha o moverse alnodo Raz del rbol.

    Informacin

    Hay varios parmetros que podemos calcular o medir dentro de un rbol.Algunos de ellos nos darn idea de lo eficientemente que est organizado o elmodo en que funciona.

    Comprobar si un rbol est vaco.

    Un rbol est vaco si su raz es NULL.

    Calcular el nmero de nodos.

    Tenemos dos opciones para hacer esto, una es llevar siempre la cuenta denodos en el rbol al mismo tiempo que se aaden o eliminan elementos. Laotra es, sencillamente, contarlos.

    Para contar los nodos podemos recurrir a cualquiera de los tres modos derecorrer el rbol: inorden, preorden o postorden, como accin sencillamenteincrementamos el contador.

    Comprobar si el nodo es hoja.

    Esto es muy sencillo, basta con comprobar si tanto el rbol izquierdo como elderecho estn vacos. Si ambos lo estn, se trata de un nodo hoja.

    Calcular el nivel de un nodo.

    No hay un modo directo de hacer esto, ya que no nos es posible recorrer elrbol en la direccin de la raz. De modo que tendremos que recurrir a otratcnica para calcular la altura.

    Lo que haremos es buscar el elemento del nodo de que queremos averiguar laaltura. Cada vez que avancemos un nodo incrementamos la variable que

    contendr la altura del nodo.

    Empezamos con el nodo raz apuntando a Raiz, y la 'Altura' igual a cero. Si el valor del nodo raz es igual que el del elemento que buscamos,

    terminamos la bsqueda y el valor de la altura es 'Altura'. Incrementamos 'Altura'. Si el valor del nodo raz es mayor que el elemento que buscamos,

    continuaremos la bsqueda en el rbol izquierdo. Si el valor del nodo raz es menor que el elemento que buscamos,

    continuaremos la bsqueda en el rbol derecho.

  • 7/31/2019 EstructurasDeDatos Java

    33/33

    rboles degenerados

    Los rboles binarios de bsqueda tienen un gran inconveniente. Por ejemplo,supongamos que creamos un ABB a partir de una lista de valores ordenada:

    2, 4, 5, 8, 9, 12

    Difcilmente podremos llamar a la estructura resultante un rbol:

    Esto es lo que llamamos un rbol binario de bsqueda degenerado, y en elsiguiente captulo veremos una nueva estructura, el rbol AVL, que resuelve

    este problema, generando rboles de bsqueda equilibrados.

    Bibliografa

    [1] Nell Dale, Object-oriented Data Structures using Java, Jones and BartlettPublishers, 2002.[2] Robert Lafore, Data Structures and Algorithms in Java, Sams, 1998.