Guia e Structur Asded A To S
Guia e Structur Asded A To S
Guia e Structur Asded A To S
de cada tema. Cada estudiante matriculado en el curso est en la obligacin de leer cada tema y desarrollar los talleres que se plantean al final de cada captulo, para garantizar su aprendizaje y aprobacin del curso.
Listado de libros de estructura de datos que se encuentran en la biblioteca de la institucin Antonio Jose Camacho A continuacin se presenta el listado de libro que se encuentran en la biblioteca de la institucin y que pueden servir como libros guas para el desarrollo del curso, es posible que algunos temas del curso se describan mejor en algunos texto que en otros. 1. Estructuras de datos en Java Autor: Luis Joyanes Aguilar e Ignacio Zahonero Notas: Este libro es muy bueno para los temas en que estamos, es el ms recomendado. 2. Estructuras. De datos Autor: Carro Guardatu Editorial: Mc Graw Hill 3. Estructuras de datos Autor: Nell Dale y Susan C. Lily Editorial: mcgraw hill 4. Estructuras de datos con java diseo de estructuras. Y algoritmos Autor: Lewis chase Editorial: Addison Wesley 5. Estructuras de datos- teora y problemas resueltos Autor: Symout Lipchutz Editorial: mc graw hill 6. Estructuras de datos en java Autor: Adan Drozdek Editorial: Thomson 7. Introduccin a las estructuras de datos, aprendizaje basado en casos Autor: jorge Villalobos Editorial:prentice hall
2 1. MTODOS:
Son bloques de cdigo que tienen nombre, tipo de acceso, tipo de retorno y lista de argumentos o parmetros. El cdigo de un mtodo va encerrado entre llaves { Sintaxis Tipo nombre(lista de parmetros) { Cuerpo del mtodo } Tipo: especifica el tipo de datos devuelto por el mtodo nombre: nombre que identifica al mtodo Lista parmetros: secuencia de parejas de identificadores y tipos de datos separados por comas, los parmetros son variables que reciben el valor de los argumentos pasados al mtodo cuando este es llamado. Si el mtodo no tiene Parmetros, entonces la lista de parmetros ser vaca Si un mtodo no retorna ningn valor, entonces el tipo de datos devuelto por el mtodo es void. Una clase contiene mtodos, el mtodo principal se llama main. Los mtodos pueden ser llamados desde cualquier otro mtodo. En Java, todos los mtodos deben estar declarados y definidos dentro de la clase, y hay que indicar el tipo y nombre de los argumentos o parmetros que acepta. Los argumentos son como variables locales declaradas en el cuerpo del mtodo que estn inicializadas al valor que se pasa como parmetro en la invocacin del mtodo. La ejecucin del programa siempre empieza desde main. }
Llamada a un mtodo Los mtodos para poder ser ejecutados, han de ser llamados o invocados.
3 En Java se puede invocar un mtodo de clase utilizando el nombre de la clase, el operador punto y el nombre del mtodo. MiClase.miMetodoDeClase();
Nota La palabra Static; permite hacer referencia a los mtodos de una clase sin necesidad de instanciar un objeto, para llamarlos. ACCESO A LOS METODOS Public() publico se puede llamar por cualquier cdigo que tenga accesos a la clase. Private() privado solo se puede llamar desde otro mtodo de la clase en que se define el mtodo privado. Protected ()protegido se puede llamar desde cualquier parte de la clase en que el mtodo esta definido y por cualquier otro mtodo de las clase que heredan de la clase en que esta definido el mtodo. Tambin esta disponible en cualquier objeto de las clases pertenecientes al mismo paquete que la clase en que esta definido el mtodo. Si no se especifica ningn tipo de acceso, se utiliza el acceso por defecto que significa que el mtodo es accesible a todas las clases contenidas en el mismo paquete, pero no es accesible fuera de ese paquete.
Si se modifica una variable que haya sido pasada por valor, no se modificara la variable original que se haya utilizado para invocar al mtodo, mientras que si se modifica una variable pasada por referencia, la variable original del mtodo de llamada se vera afectada de los cambios que se produzcan en el mtodo al que se le ha pasado como argumento.
4 METODOS PARA LECTURA DE DATOS Aqu hemos definido la clase Lectura con los mtodos necesarios para la lectura de datos, de aqu en adelante, cada vez que se necesite leer datos de java solo se realizara el llamado a estos mtodos, incluyendo esta clase en el proyecto. public class Lectura { /////////////////Entrada y salida de datos////////////// //metodo para mostrar un mensaje public static void mostrar(String mensaje) { JOptionPane.showMessageDialog(null,mensaje); } public static int leerEntero(String mensaje) //metodo para leer un dato de tipo string y convertirlo a entero { String N=JOptionPane.showInputDialog(mensaje); int n=Integer.parseInt(N); return n; }
public static double leerDoble(String mensaje) //metodo para leer un dato string y convertirlo a double { String N=JOptionPane.showInputDialog(mensaje); double n= Double.parseDouble(N); return n; }
public static long leerLong(String mensaje) {//metodo para leer un dato string y convertirlo a long String N=JOptionPane.showInputDialog(mensaje); long n= Long.parseLong(N); return n } public static float leerFloat( String mensaje ) {//metodo para leer un dato string y convertirlo a float 4
public static char leerChar( String mensaje ) {//metodo para leer un dato string y convertirlo a char String N=JOptionPane.showInputDialog(mensaje); char n= N charAt(0); return n } }
EJEMPLOS DE METODOS 1. Un supermercado desea realizar un descuento a una compra que realiza un cliente, este descuento depende de un nmero que se saque de una bolsa en el momento de cancelar la compra, el descuento se realizara as: Si de la bolsa saca un nmero menor que 74 el descuento sobre la compra es del 15%, y si el nmero es mayor o igual a 74 el valor del descuento es del 20%. Realice un programa en Java para el supermercado que le permita determinar cul es el descuento que debe hacer a sus clientes, conociendo el valor de la compra y el nmero sacado de la bolsa. 2. Se requiere crear un mtodo que reciba como entrada un nmero n (que es la cantidad de datos que se van a pedir luego). El mtodo debe pedir al usuario el que ingrese n datos y mostrar en pantalla el cuadrado de cada nmero ingresado. SOLUCION Se ha implementado mtodos para resolver cada problema se utilizara los mtodos ya implementados para lectura de datos. public class Main {
public static void descuentoSupermercado () //metodo para calcular el descuento que se hace en un supermercado 5
6 { double descuento=0, compra=0; int n=0; n=Lectura.leerEntero("digite nmero"); compra=Lectura.leerDoble("digite valor de la compra"); if (n<74) { descuento=compra*0.15; } else { descuento=compra*0.2; } Lectura.mostrar("el valor del descuento es " + descuento); }
public static void cuadrados(int n) { //calcula el cuadrado de n datos double cuadrado=0; for(int i=1; i<=n; i++) { int c= Lectura.leerEntero("digite numero"); cuadrado=c*c; Lectura.mostrar("el valor del cuadrado de " + c + "es" + cuadrado); } }
public static void main(String[] args) { //metodo principal //aqui se llaman los mtodos descuentoSupermercado(); cuadrados(4); } }
7 TALLER 1: METODOS
Importante: cada uno de los ejercicios planteados deben ir dentro de un mtodo y desde el main del programa solo debe aparecer el llamado a los mtodos, no se acepta todo el cdigo escrito en el main().
1. En una Universidad existen tres programas acadmicos que son: Licenciatura Matemticas, Tecnologa en Electrnica, y Tecnologa de Sistemas, los cuales tienen un costo de 1.000.000 para Tecnologa Electrnica, $1.200.000 para Matemticas y $1.300.000 para Tecnologa de Sistemas, adems de esto los estudiantes tienen un descuento del 10% si pertenecen a estrato 2 y del 20% si pertenecen a estrato 1: Hacer un programa que dado el estrato al cual pertenece el estudiante y la carrera que quiere estudiar determine el costo de su matrcula. (Utilice mtodos). 2. Realizar un programa que incluya un mtodo que calcule la suma de los primeros n nmeros pares. 3. Realizar un programa que pida un valor para n e imprima una figura dependiendo del valor de n. Por ejemplo para n= 4 imprime: * ** *** **** ***** 4. Realizar un programa que pida un valor para n e imprima una figura dependiendo del valor de n. Por ejemplo para n= 5 imprime: ***** **** *** ** * 5. Realizar un mtodo que calcule el factorial de un nmero.
6. Resolver tres ejercicios ms con ciclos, de un libro de la biblioteca, anotar la bibliografa del libro (nombre, autor, editorial), ejercicio. (No se acepta de internet). pgina y nmero del
Java requiere que cada clase pblica sea almacenada en un archivo con el nombre de la clase, lo cual implica que no podremos poner ms de una clase pblica por archivo. O sea, si tenemos una clase pblica llamada Figura, la misma deber ser almacenada en un archivo llamado Figura.java A su vez las clases se agrupan en paquetes. El concepto de paquete en Java es similar al de unit en Pascal y al de namespace en C++. Los paquetes pueden nombrarse con varios nombres unidos por puntos, un nombre de paquete vlido sera por ejemplo algo3.fiuba.ejemplos.
Para indicar que una clase A pertenece a un paquete xxx.yyy , basta con incluir la sentencia package xxx.yyy; al comienzo del archivo de la clase A. Todas las clases que forman parte de un mismo paquete, deben estar en un mismo directorio con el nombre del paquete. Los puntos en el nombre del paquete determinan una estructura de directorios. Veamos un ejemplo: la clase A perteneciente al paquete xxx.yyy, determina la existencia de una archivo A.java, dentro de un directorio llamado yyy, dentro de un directorio xxx, osea xxx\yyy\A.java.
La utilizacin de paquetes permite que existan clases con el mismo nombre, siempre y cuando pertenezcan a distintos paquetes. Personalmente siempre suelo decir que el nombre completo de una clase es: nombre paquete + nombre clase. Cuando desde una clase queremos utililizar otra clase perteneciente a un paquete distinto, debemos importar la clase. Para ello incluiremos la sentencia import seguida por el nombre completo de la clase que deseemos importar. En caso de querer importar todas las clases de un paquete xxx, podremos incluir la sentencia import xxx.*;
9 En nuestro ejemplo tenemos el proyecto arreglo, dentro del cual tenemos la clase Lectura y la clase vectores, la clase vectores tiene mtodos que utilizan los mtodos de la clase Lectura. Como todo esta agrupado en el mismo paquete, pues no hay que importar ningn paquete.
Pero cuando realice otro ejercicio, si deseo utilizar una clase que est en otro proyecto
Se hace clic derecho sobre el proyecto actual
En la opcin Libraries, seleccionamos Add Project (adicionar proyecto) y buscamos el proyecto que se quiere adicionar. Ya en la clase donde necesitemos usar alguna clase de un paquete de este proyecto lo importamos escribiendo:
import arreglos.Lectura; Lectura es la clase que voy a utilizar y se encuentra dentro del paquete arreglos.
10
No ubicamos con el cursor en la posicin desde donde vamos a empezar a ejecutar el programa Hacemos clic en la opcin Debug->Run to cursor
Y con F8 vamos corriendo cada lnea. Cuando no queremos entrar en el cuerpo de algn mtodo, hacemos F7, Por ejemplo en los mtodos de lectura de datos o los propios de java, o sencillamente en algn mtodo que ya funcione bien y no queramos examinarlo paso a paso.
Preguntas:
Ir al proyecto programa de arreglos Ubicarse en el main() que est en la clase vectores.java Empezar a correr paso a paso el programa
Preguntas: Despus de pasar por la lnea int vec1[]=new int[t]; Con que valores queda la variable vec1? Despus de pasar por la lnea vec1=llenarArreglo(t) Como quedo el vector? Explique que se hace en esta lnea
10
11 2. ARREGLOS UNIDIMENSIONALES O VECTORES Un Array o arreglo es una secuencia de datos del mismo tipo y se numeran consecutivamente. Los arreglos pueden ser de una o varias dimensiones, los arreglos en una dimensin se conocen como vectores y los arrglos de dos dimensiones de conocen como matrices. Un array puede contener la edad de los alumnos de una clase, las temperaturas de cada da de una ciudad en un mes etc. Los valores de un array se numeran consecutivamente 0,1,2,3, (posiciones en el arreglo) P Valores guardados
en el arreglo
Ejemplo: P Posiciones en el 25 0 34 1 5 2 7 3 6 4 7 5
arreglo
Tipo nombrearreglo[]; Ejemplos Int v[]; v es un arreglo de enteros char cad[]; cad es una variable (arreglo) de tipo char. Los arrays se deben declarar antes de utilizarlos Para indicar el nmero de elementos que tiene un array se usa el operador new. Ejemplo float [] notas; notas=new float[26]; Int a[]=new int[10]; Para crear un array de diez variables de tipo entero. Tamao de los arrays
11
12 Java considera un array como un objeto, debido a ello se puede conocer el nmero de elementos de un array accediendo al campo length del objeto. double v[]=new double [15]; System.out.print(v.length); escribe 15
Inicializacon de una array Se deben asignar valores a los elementos del array antes de utilizarlos, tal como se asignan valores a las variables. int precio[]=new int[4]; //Cuando se inicializa el arreglo, asigna 0 a cada posicin del arreglo. Si se quiere asignar valores a cada elemento del array se puede hacer as: precio[0]=10; precio[1]=20; precio[3]=30; precio[4]=40; Pero esto no es prctico cuando contienen muchos elementos. Tambin se puede inicializar el array as: Int precios[]={10,20,30,40}; Ejemplos Int n={3,4,5} define un array de 3 elementos Char c[]={L, u, i, s}; Define un array de cuatro elementos.
static int[] llenarArreglo(int tamao) { //mtodo para inicializar el arreglo, recibe como parmetro a tamao que es el nmero de elementos //que va a tener el arreglo 12
13 int n; int vector[]=new int[tamao]; //se define el arreglo //se llena el arreglo for (int i=0; i<tamao; i=i+1) { n=Lectura.leerEntero("Digite el elemento de la posicin " + i); vector[i]= n; } return vector; }
static void mostrarArreglo(int v[]) { //metodo para mostrar el contenido del arreglo String mensaje=""; int tamao=v.length; //mostrar el arreglo con sus elementos for (int i=0; i<tamao; i=i+1) { //se van mostrando todos los elementos del arreglo y se unen en un solo mensaje //para mostrarlo finalmente en la ventana de dialogo mensaje= mensaje+"\n El nmero en la posicin "+i+" es "+v[i]; } Lectura.mostrar(mensaje); }
static int sumaElementosArreglo(int v[]) { //mtodo para sumar los elementos de un arreglo int suma=0; for (int i=0; i<v.length; i=i+1) { suma=suma+v[i]; } return suma; }
13
14 static void menorArreglo(int v[]) { //metodo para encontrar el elemento menor de un arreglo int menor=v[0]; for (int i=1; i<v.length; i=i+1) { if (v[i]<menor) menor=v[i]; } Lectura.mostrar("el elemento menor del arreglo es " + menor); }
public static void main (String []args){ int t=Lectura.leerEntero("Digite cuantos elementos va a tener el arreglo"); int vec[]=new int[t]; vec=llenarArreglo(t);//se llama al mtodo que inicializa el arreglo mostrarArreglo(vec); //llamado al mtodo para mostrar los elementos del arreglo menorArreglo(vec); Lectura.mostrar("La suma del los elementos del arreglo es igual a " + sumaElementosArreglo(vec) ); } }
TALLER 2: VECTORES
1. Realice un programa en Java que permita realizar cada uno de los siguientes mtodos, adems debe contener un men para que el usuario seleccione la opcin a realizar. a) Escribir un mtodo que calcule el producto escalar de dos vectores. Si v y w son los vectores y n su tamao, el producto escalar se calcula como la sumatoria de v(i)*w(i) b) Implementar un mtodo calcule el producto de un nmero por un vector (devuelve el vector resultante de multiplicar todas las componentes del vector inicial por un nmero) 14
15 c) Escribir un mtodo que calcule el vector resultante de sumar a cada una de las componentes de un vector dado, un nmero real d) Desarrollar un mtodo que devuelva el mnimo de los elementos de un vector. e) Escribir un programa que devuelva el mximo de los elementos de un vector. 2. Realice un programa que contenga mtodos para: a) Guardar las temperaturas del mes de febrero (de este ao) con valores dados por el usuario b) Mostar La temperatura mayor c) Mostrar La temperatura menor d) Calcule y diga cul es la temperatura promedio para este mes. e) Extienda el mtodo para que funcione para cualquier mes. 3. En un vector de 20 posiciones se almacenan los sueldos de n empleados, de los cuales se desea saber: a) Cuantos empleados ganan ms del mnimo b) Cuntos ganan menos que el sueldo mnimo c) Haga un mtodo que reciba como dato de entrada el vector de los sueldos de los empleados y retorne y muestre un vector con los sueldos menos el 10% de cada sueldo.
15
16
3. METODOS DE ORDENAMIENTO El propsito principal de un ordenamiento es el de facilitar las bsquedas de los elementos del conjunto ordenado METODO DE SELECCIN El algoritmo de ordenamiento por seleccin se basa en la idea de tener dividido el arreglo que se est ordenando en dos partes: una, con un grupo de elementos ya ordenados, que ya encontraron su posicin. La otra con los elementos que no han sido todava ordenados. En cada iteracin, localizamos el menor elemento de la parte no ordenada, lo intercambiamos con el primer elemento de esta misma regin en indicamos que la parte ordenada ha aumentado un elemento. static void ordenarSeleccion(int v[]) { int min=0, pos=0, aux=0; for (int i=0; i<v.length-1;i++) { min=v[i]; pos=i; for (int j=i+1; j<= v.length-1; j++) { //en este ciclo se saca el menor del vector if (v[j]<min) { min=v[j]; pos=j; } }
P El objetivo del ciclo interior es buscar el menor valor de la parte si ordenar. Dicha parte comienza en la posicin i y va hasta el final del ciclo, deja en la variable min el menor valor encontrado y en la variable pos la posicin del elemento menor (min)
//aqu se intercambian las posiciones, el menor pasa a la primera posicin del vector //y el elemento que estaba all pasa a la posicin donde estaba el menor. aux=v[i]; v[i]=min; v[pos]=aux;
16
v 6 0 5 0 4 0 3 0
min
0 60
0 0
50
2 40<50
40
3 30<40 //
30 3 0 5 0 4 0 6 0
3 60 1
50 40 3 0 4 0 5 0 6 0 50
1 2
2 3 4 50 2
40<50 60<40 //
VERDADER O FALSO
3 4
60<50 //
FALSO
17
18 METODO DE LA BURBUJA (INTERCAMBIO) Se basa en la idea de intercambiar todo par de elementos consecutivos que no se encuentran en orden. Al final de cada pasada haciendo ese intercambio, un nuevo elemento queda ordenado y todos los dems elementos se acercan a su posicin final
static void ordenBurbuja(int v[]) { int aux=0; for(int i=v.length-1; i>=0;i--) { for (int j=0; j<i; j++) { if (v[j]>v[j+1]) { aux=v[j]; v[j]=v[j+1]; v[j+1]=aux; } } } } El mtodo se llama burbuja, porque hace que los elementos vayan subiendo poco a poco hasta ocupar su posicin final. Al final de la primera iteracin el ltimo elemento se encuentra ya ordenado. Al final de cada iteracin, en la parte final del arreglo estn los elementos ya ordenados, los cuales adems son mayores que todos los elementos que faltan por ordenar. Notemos que cuando se llaman los mtodos de ordenamiento, si miramos el vector que se envi como parmetro en el llamado del mtodo esta ordenado (en el main), es decir se modific la variable, esto se debe a que los vectores son datos que se envan por referencia. Recordemos que: P Si la posicin j es mayor que la posicin j+1, se intercambian.
Paso por valor significa que cuando un argumento se pasa a una funcin, la funcin recibe una copia del valor original. Por lo tanto, si la funcin modifica el parmetro, slo la copia cambia y el valor original permanece intacto. 18
19 Paso por referencia significa que cuando un argumento se pasa a una funcin, la funcin recibe la direccin de memoria del valor original, no la copia del valor. Por lo tanto, si la funcin modifica el parmetro, el valor original en el cdigo que llam a la funcin cambia.
19
20 PRUEBA PASO A PASO DEL METODO DE LA BURBUJA v 60 50 40 30 50 60 40 30 50 40 60 30 aux 0 60 1 60 2 50 40 30 60 60 2 40 50 30 60 40 30 50 60 30 40 50 60 50 50 1 40 0 // 1 2 0 1 50>30 // 40>30 // VERDADERO VERDADERO 3 0 // 50>40 VERDADERO 60>30 VERDADERO 60>50 i 3 j 0 60>50 VERDADERO
METODO INSERCION static void ordenInsercion(int v[]) { int aux=0; for(int i=0; i<v.length-1; i++) { for (int j=i+1; j>0; j--) { if (v[j-1]>v[j]) { aux=v[j-1]; v[j-1]=v[j]; v[j]=aux; } } }
20
21
PRUEBA PASO A PASO DEL INSERCION v 12 2 5 10 5 10 1 2 5 12 10 1 0 3 12 2 5 10 12 2 1 0 3 5>10 f 2>5 f i 0 j 1 12 2 12 0 2 12 2>5 f 12>10 v 12>5 v aux 12>2 v
TALLER 3: METODOS DE ORDENAMIENTO 1) Investigar el mtodo de insercin, hacer un ejemplo y la prueba paso a
2)
Utilizando el computador ordnelo por el mtodo de seleccin, burbuja e insercin y compare los tiempos de ejecucin, concluir cual es ms rpido.
21
22 4. PILAS Una pila (stack) es una coleccin ordenada de elementos a los que solo se puede acceder por un nico lugar o extremo de la pila. Los elementos de la pila se aaden o quitan (borran) solo por su parte superior. Se conocen tambin como estructuras LIFO (last in first-out, ltimo en entrar, primero en salir). Ejemplo pila de platos, pila de libros etc. Una pila se puede implementar mediante arrays en cuyo caso su longitud o dimensin es fija, y mediante listas enlazadas, en cuyo caso se utiliza memoria dinmica y no existe limitacin en su tamao, excepto la memoria del ordenador. Cuando un programa intenta sacar un elemento de una pila vaca, se producir un error, una excepcin, debido a que esa operacin es imposible. Por el contrario, si un programa intenta poner un elemento en una pila llena se produce un error llamado desbordamiento (overflow) o rebosamiento. Para evitar estas situaciones se disean mtodos que comprueban si la pila est llena o vaca Las pilas se pueden implementar con arrays o con listas enlazadas, una implementacin esttica se realiza utilizando un array de tamao fijo y una implementacin dinmica mediante una lista enlazada. Aplicaciones de las Pilas Las pilas son utilizadas ampliamente para solucionar una variedad de problemas. Se utilizan en compiladores, sistemas operativos y en programas de aplicacin. Veamos algunas de las aplicaciones ms interesantes. Llamadas a mtodos.- Cuando se realizan llamadas a mtodos, el programa principal debe recordar el lugar donde se hizo la llamada, de modo que pueda retornar all cuando el mtodo se haya terminado de ejecutar. Almacenamiento temporal de pginas Web.- Los navegadores de Internet almacenan las direcciones de las pginas recientemente visitadas en una pila, cada vez que un usuario visita un nuevo sitio, las direcciones son introducidas en la pila de direcciones. El navegador despus permite al usuario volver a las pginas visitadas previamente usando el botn de ir atras. El mecanismo de deshacer-rehacer en los editores de texto.- Los editores de texto utilizan usualmente un mecanismo de deshacer (undo) que cancela las operaciones editadas actualmente para volver a las operaciones previas, para ello se utiliza una pila. Otra aplicacin es la la evaluacin de expresiones algebraicas, como veremos en la siguiente seccin. 22
23
IMPLEMENTACIN DE UNA PILA EN JAVA USANDO ARREGLOS Se ha definido la clase Pila, aqu ya necesitamos los conceptos de programacin orientado objetos.
package pila;
String vectorPila[]; //vector donde se almacenan los elementos de la pila int elementos;//cantidad de elementos actuales en la pila int tamao;// tamao mximo de la pila int cima; //posicin de donde esta el ultimo elemento de la pila (tope de la pila) public Pila(int cantidad){ elementos=0; //los elementos que hay actualmente en la pila tamao=cantidad; //el tamao de la pila vectorPila= new String[tamao]; //recibe el tamao mximo de la pila cima=-1; // se utiliza el valor -1 para indicar que no hay elementos } public boolean pilallena(){ if(cima==tamao-1) //verifica si la pila est llena { return true; } else { return false; } } public boolean pilaVacia() //verifica si la pila esta vacia { if(cima==-1) return true; else return false; } public void entraElemento(String elem) { //ingresa un elemento a la pila
23
24 if(pilallena()==false) { cima++; vectorPila[cima]=elem; elementos++; } } public String Vercima() { //Muestra elemento que se encuentra en la cima return(vectorPila[cima]); } public String sacarElemento() { //saca un elemento de la pila String aux=""; if (pilaVacia()!=true) { aux=vectorPila[cima]; cima--; elementos--; } return aux; }
public static void main(String[] args) { Pila p=new Pila(4); p.entraElemento("elemento 1"); p.entraElemento("elemento 2"); p.entraElemento("elemento 3"); Lectura.mostrar("el elemento de la cima es " + p.Vercima()); Lectura.mostrar("la pila tiene "+ p.elementos + " elementos"); //muestra la cantidad de elementos en la pila
} }
24
Notaciones infija y postfija Existen bsicamente tres formas diferentes de escribir una expresin algebraica. Notacin prefija, notacin infija y notacin postfija, en funcin de la situacin concreta en la que se pongan los operadores respecto de los operandos. As la expresin algebraica que representa la suma entre un cierto valor A y otro B se podra escribir de la siguiente forma: + A B Notacin prefija A + B Notacin infija A B + Notacin postfija La notacin utilizada habitualmente es la infija. Si observamos un ejemplo adicional de notacin infija en la que se utilicen ms de un operador podemos observar que para realizar correctamente la operacin tenemos que conocer una informacin adicional acerca de los operadores que aparezcan: La prioridad. Dependiendo de la prioridad del operador, la operacin se realizar antes o despus, dando como consecuencia un resultado distinto si variamos la prioridad de los operadores. As, en A + B * C, se realizar primero la multiplicacin y a continuacin la suma. Si deseamos variar la prioridad, y en consecuencia el orden de evaluacin de las operaciones, hay que aadir una informacin adicional que son los parntesis. Si en el ejemplo deseamos realizar primero la suma entonces deberemos incluirla entre parntesis (A + B) * C. Esta inclusin de parntesis no es necesaria en notacin prefija o postfija. En nuestro caso nos centraremos en la notacin infija (la notacin habitual) y la postfija (ms conveniente para uso interno en el ordenador.) Notacin infija Notacin postfija A+B*CABC*+ (A + B) * C A B + C * La conversin entre la expresin en notacin infija y postfija se puede realizar de forma sencilla mediante la utilizacin de una pila y considerando las prioridades entre los operadores que aparecen en la expresin. Por ejemplo, supongamos que queremos pasar la expresin infija A+B*C-D a postfija. El proceso sera el siguiente: Iniciamos la pila a vaca (pila = <>.) Obtenemos el primer elemento de la expresin (A). Como es un operando, pasa automticamente a la salida (Salida = A.)
25
26 Miramos el siguiente elemento (+). Como es un operador, comparamos su prioridad con la del ltimo operador de apilado en la pila. Como la pila est vaca, el operador se apila en la pila (pila = <+>.) El siguiente elemento es la B, un operando. Como antes pasa directamente a la salida (Salida = A B.) Ahora el elemento es *, un operador. Comparamos su prioridad con la del operador de la cima de la pila. Como el * es ms prioritario que el +, lo apilamos, en espera de obtener la otra parte de la operacin (pila = <+, *>.) El siguiente elemento es C. Va directamente a la salida (Salida = A B C.) Luego tenemos el . Comparamos su prioridad con la cima de la pila. El tiene menor prioridad que el *, luego desapilamos el asterisco, que va a la salida (pila = <+>, Salida = A B C *). Comparamos la prioridad del ahora con la de la cima de la pila (que es el +.) Como la prioridad es la misma, desapilamos el + y va a la salida (Salida = A B C * +.) La pila esta vaca con lo que no podemos seguir comparando y apilamos el (pila = <>.) El siguiente elemento de la expresin es la D. Va directamente a la salida (Salida = A B C * + D) Como ya no hay ms elementos en la expresin, nos limitamos a desapilar todos los elementos restantes de la pila y los ponemos en la salida (pila = <>, Salida = A B C * + D .) El proceso con parntesis sera similar, pero teniendo en cuenta que un parntesis abierto nunca tiene precedencia sobre ningn elemento, de manera que siempre se apila, y el parntesis cerrado desapila todos los smbolos hasta encontrar el parntesis abierto, que tambin se desapila. Los parntesis, no deben salir ya en la expresin postfija. Evaluacin de una expresin algebraica en notacin postfija Una vez transformada la expresin a notacin postfija se realizar un algoritmo que la evalu y d su resultado. La idea bsica del algoritmo es ir apilando los operandos y resultados parciales en una pila e ir desapilndolos a medida que van siendo necesarios (cuando encontremos en la expresin un cierto operador.) Supongamos la expresin 13 7 3 * + 5 (en infija sera 13 + 7 * 3 5 que tiene como resultado 29.) La manera de evaluarla ser: Iniciamos la pila a vaca (pila = <>) Obtenemos el primer valor. Como es un entero, lo apilamos (pila = <13>) Obtenemos el segundo elemento y el tercero, que tambin son enteros y los apilamos (pila = <13, 7, 3>)
26
27 Obtenemos el siguiente elemento que es un *. Como es un operador, necesitamos obtener los dos operandos involucrados que son los dos ltimos de la pila, el 3 y el 7 que desapilamos. Los operamos con el * y obtenemos 21. El valor 21 lo apilamos (pila = <13, 21>) El siguiente elemento es el +. Necesita de nuevo dos operandos que sern los dos ltimos de la pila, el 21 y el 13, que desapilamos. Los operamos con + y apilamos el resultado (pila = <34>) Despus obtenemos el 5 en la expresin. Lo apilamos (pila = <34, 5>) Finalmente obtenemos de la expresin el . Desapilamos el 5 y el 34, restamos (34-5=29) y apilamos el resultado (pila = <29>) Como ya hemos llegado al final de la expresin, el resultado de la operacin es lo que est en la cima de la pila. Si en algn momento nos quedamos sin operandos en la pila cuando es necesario desapilar dos elementos, se ha producido un error. Si al finalizar el proceso, queda ms de un elemento en la pila tambin se ha producido un error. En ambos casos la expresin estaba mal escrita. IMPLEMENTACION EN JAVA Para esto utilizaremos la implementacin de una pila, donde la pila tiene un vector de caracteres, que sern los elementos de la expresin. Necesitamos la clase Lectura, con sus mtodos, los cuales ya han sido explicados antes. Tambin necesitamos una clase Pila, public class Pila { char vectorPila[]; int elementos;//cantidad de elementos actuales en la pila int tamao;// tamao mximo de la pila int cima; public Pila(int cantidad){ elementos=0; //los elementos que hay actualmente en la pila tamao=cantidad; vectorPila= new char[tamao]; //recibe el tamao mximo de la pila cima=-1; } public boolean pilallena() { //si la pila esta llena devuelve true en caso contrario devuelve false if(cima==tamao-1){ return(true); } return(false); } 27
28
public boolean pilaVacia() { //si la pila esta vacio devuelve true en caso contrario devuelve false if(cima==-1){ return(true); } return(false); } public void entraElemento(char elem) { //mete un elemento en la pila if(pilallena()==false){ cima++; vectorPila[cima]=elem; elementos++; } } public char Vercima() { //muestra el elemento que se encuentra en la cima return(vectorPila[cima]); } public char sacarElemento() { //saca un elemento de la pila char aux='0'; if(!pilaVacia()){ aux=vectorPila[cima]; cima--; elementos--; } return(aux); }
/* public static void main(String[] args) { //metodo principal String expresionInfija=""; String expresionPostfija=""; expresionInfija=Lectura.leerMensaje("Digite la expresion en infijo, sin parentesis y dejando espacios entre operadores y operandos"); expresionPostfija=Postfija.convertir(expresionInfija); //se llama al mtodo para convertir de infija apostfija. Lectura.mostrar("La expresion en postfijo es " + expresionPostfija); 28
29
}*/ }
Luego Hacemos otra clase Postfija, con los mtodos necesarios para pasar una expersion de infijo a postfijo import java.util.Scanner;
static public int prioridad (char operador) { //retorna un valor de prioridad para un operador matematico int priori=0; if (operador=='+' || operador=='-') priori=1; if (operador=='*' || operador=='/') priori=2; if (operador=='!') priori=3; return priori;
static public String convertir(String infi) { //Este metodo recibe la expresion en infija, sin parentesis y con espacios entre operadores y operandos // y la transforma en postfija int n=infi.length(); //se obtiene el tamao de la cadena infi, que esta en infijo String elemento; String salida=""; Pila p=new Pila(n); // la pila donde se van guardando los operadores de la expresin
29
30
//Vamos a utilizar la clase Scaner que permite tomar una cadena e ir recorriendo o tomando subcadenas dentro de ella. Scanner s=new Scanner(infi); while(s.hasNext()) //Va recorriendo las subcadenas separadas por espacios. { elemento=s.next(); //retorna el proximo elemento //elemento=elemento.toString(); if (elemento.length()>1) //revisa si la cadena leida tiene mas de dos caracteres, en este caso es un operando { //y pasa a la salida salida=salida+elemento+" "; } else if (elemento.length()==1) // si es de tamao 1 puede ser operando u operador { if (elemento.charAt(0)>='0' && elemento.charAt(0)<='9') // revisa si el caracter es un numero, en este caso salida=salida+elemento+" "; //pasa a la salida if (((elemento.charAt(0)=='+' ) || (elemento.charAt(0)=='')||(elemento.charAt(0)=='*' ) || (elemento.charAt(0)=='/') ||(elemento.charAt(0)=='!') )&& p.pilaVacia()==true) { p.entraElemento(elemento.charAt(0)); // si es operador y la pila esta vacia, el operador se mete a la pila } else if (((elemento.charAt(0)=='+' ) || (elemento.charAt(0)=='')||(elemento.charAt(0)=='*' ) || (elemento.charAt(0)=='/') ||(elemento.charAt(0)=='!') )&& p.pilaVacia()==false) { // si es operdor pero la pila no esta vacia, se compara con el elemento de la cima char c=p.Vercima(); // se guarda en c el elemento de la cima if (Postfija.prioridad(elemento.charAt(0))>Postfija.prioridad(c)) // se compara la prioridad entre la cima y el operador p.entraElemento(elemento.charAt(0)); // de la esxpresion si es mayor, se mete en la pila else { // si es menor la prioridad y la pila no esta vacia, se sigue comparando con los todos los operadores que ya estan en la pila 30
31 while ((Postfija.prioridad(elemento.charAt(0))<=c) && p.pilaVacia()==false) { salida=salida+p.sacarElemento(); // y se van pasando los operadores de la pila a la salida } if (p.pilaVacia()==true) // cuando la pila queda vacia se mete el operador a la pila p.entraElemento(elemento.charAt(0)); } } } } // cuando se termina de recorrer la expresion, y quedan elementos en la pila estos pasan a la salida. while (p.pilaVacia()==false) { salida= salida+p.sacarElemento()+" "; } return salida; } public static void main(String[] args) { //metodo principal String expresionInfija=""; String expresionPostfija=""; expresionInfija=Lectura.leerMensaje("Digite la expresion en infijo, sin parentesis y dejando espacios entre operadores y operandos"); expresionPostfija=Postfija.convertir(expresionInfija); //se llama al mtodo para convertir de infija apostfija. Lectura.mostrar("La expresion en postfijo es " + expresionPostfija);
} }
31
32
TALLER NOTACIN POSTFIJA 1. Analizar y entender el cdigo anterior 2. Dentro de la clase postfija, implementar un mtodo que evalu una expresin postfija y muestre el resultado 3. Si la expresin infija contiene parntesis, adecue los mtodos para que convierta la expresin infija con parntesis en postfija.
32
33 5. ARRAYS MULTIDIMENSIONALES El uso ms importante es para resolver ecuaciones lineales de muchas variables en forma sistemtica y compacta. Es posible crear arrays de tantas dimensiones como requieran las aplicaciones 3, 4 o ms dimensiones. Si tiene ms de una dimensin en consecuencia tiene ms de un ndice. Los arrays ms usuales 2 Columnas 0 0 Filas 1 2 3 n 1 2
Los arreglos de dos dimensiones son conocidos tambin por el nombre de tablas o matrices. Para localizar un elemento ser por las coordenadas representadas por el nmero de la fila y el nmero de columna (a, b) El nmero de elementos que tendr el array ser el resultado del producto (m+1)* (n+1)
Sintaxis para la declaracin de un array de dos dimensiones. <Tipo de datos elementos > <nombre del array> [] [];
O bien <tipo de datosElementos> [] [] <nombre array>; Ejemplo Char pantalla [] []; Int puestos [] []; double matriz [] []; 33
34
Estas declaraciones no reservan memoria para los elementos de la matriz o tabla, realmente son referencias. Para reservar memoria y especificar el nmero de filas y de columnas se utiliza el operador new. Pantalla=new char[80] [24]; //matriz con 80 filas y 24 columnas Puesto=new int [10] [5]; //matriz con 10 filas y 5 columnas
El operador new se puede aplicar a la vez que se hace la declaracin. La sintaxis para definir una matriz
Nota: Java requiere que cada dimensin este encerrada entre corchetes. int equipos [][]=new int[4,5]; Esto No es valido
Un array de dos dimensiones en realidad es un array de arrays. Es decir es un array unidimensional y cada elemento, es otro array. Los elementos de los arrays se almacenan en memoria de modo que el subndice ms prximo al nombre del array es la fila y el otro subndice, la columna Se pueden tener matrices donde el nmero de columnas de cada fila es diferente, ejemplo: double t[][]=new double[2][]; se define una matriz de dos filas y no se especifica en nmero de columnas. t[0]=new double[4]; luego por cada fila, se inicializa el nmero de columnas. t[1]=new double[3]; quedando la fila 0 con 4 columnas y la fila 1 con 3 columnas.
34
35 Inicializacion de arrays Multidimensionales Encerrando entre llaves la lista de constantes separadas por comas de que consta cada fila, como en los ejemplos siguientes: Int tabla[][]={{51,52,53}, {54,55,56}}; Se ha definido una matriz de dos filas por tres columnas. Se pueden crear arrays no cuadrados double tb [] []={{1.5, -2.5}, {5.0, -0.0, 1.5}} Matriz de dos filas, la primera con dos columnas y la segunda con tres En un array bidimensional, al ser un array de arrays, el atributo length de tabla contiene el numero de filas y el atributo length de cada array fila, contiene el numero de columnas para ese fila. Flota ventas [] []={{0,0,0}, {1,1},{-1.0}}; ventas.length; es igual a 3 ventas[0].length es igual a 3 ventas[1].length es igual a 2 ventas[2].length es igual a 1 En la definicin de un array bidimensional no es posible omitir el nmero de filas, as la declaracin double vt [][]=new double[][4]; es errnea ya que no se ha especificado el numero de filas y el tamao queda indeterminado. Matriz.length da el nmero de filas Matriz[0].length nos da el numero de columnas de la fila 0 El ltimo elemento de una matriz es matriz[matriz.length-1][matriz[0].length-1] El compilador deduce automticamente las dimensiones del array IMPLEMENTACION DE ARREGLOS BIDIMENSIONALES EN JAVA
public static double [][] InicializarMatriz() { //metodo para inicializar una matriz con elementos dados por el usuario int numfil= leerEntero("digite numero de filas"); int numcol=leerEntero("digite numero de columnas"); double matriz[][]=new double[numfil][numcol];//se declara e inicializa una matriz de tamao numfil x numcol for(int fil=0; fil<numfil;fil++)//se va llenando la matriz, ciclo de las filas { 35
36 for(int col=0; col<numcol; col++)//ciclo de las columnas { matriz [fil][col]= leerDoble("digite el elemento " + fil +","+ col); } //cierra for de columnas }//cierra for de filas return (matriz); } public static double [][] sumaMatrices(double A [][] ,double B [][] ) // { //metodo para sumar dos matrices double C[][]= new double[A.length][A[0].length];//matriz para guardar el resultado //las matrices que se suman deben tener igual nmero de filas e igual nmero de columnas if ((A.length==B.length) && (A[0].length==B[0].length)) { for(int fil=0; fil<A.length;fil++) //ciclo de la filas { for(int col=0; col<A[fil].length; col++) //ciclo de columnas { C[fil][col]= A[fil][col]+B[fil][col];//se suman y se guarda en la matriz C } } } //si no cumple la condicin se muestra un mensaje else mostrar("Las matrices deben tener igual nmero de filas y columnas"); return (C); }
static void mostrarMatriz(double A[][] ) //muestra los elemento del arreglo de dobles { String mensaje=""; //variable para almacenar el mensaje de los elementos de la matriz for(int fil=0; fil<A.length;fil++) //ciclo de las filas { 36
37 for(int col=0; col<A[fil].length; col++) //ciclo de las columnas { mensaje= mensaje+"\n "+fil+","+col+" es "+A[fil][col]; } //cierra for de columnas mensaje= mensaje+"\n "; }//cierra for de filas
// se llama el metodo mostrar para que presente por pantalla el mensaje mostrar(mensaje); } public static double[][] multiplicarMatrices(double A[][], double B[][]) { double suma = 0; double c[][] = new double[A.length][B[0].length]; if (A.length == B[0].length) { for (int fila = 0; fila < A.length; fila++) //el ciclo externo depende del nmero de filas de A { for (int columna = 0; columna < B[0].length; columna++) //este es el ciclo para cada columna de B { suma = 0; for (int k = 0; k < B.length; k++) //en este ciclo se multiplica cada valor de la fila de A por la columna de B y depende del numero de filas de B { suma = suma + A[fila][k] * B[k][columna]; //se va acumulando los resultados de la multiplicacin, en suma } c[fila][columna]=suma; //el resultado de la suma de guarda en la matriz resultado } } } else { Lectura.mostrar("El nmero de filas de la primera matriz debe ser igual en nmero de columnas de la segunda matriz"); } return c; }
37
38
public static void main (String []args) //metodo principal { double m[][], n[][],s[][], mult[][]; //se inicializan las matrices llamando al mtodo InicializarMatriz m=InicializarMatriz(); n=InicializarMatriz(); s= sumaMatrices(m,n); // se llama al metodo sumaMatrices para sumar las dos matrices anteriores //el resultado de la suma se guarda en s mostrarMatriz(s); //se muestra el resultado de la suma mult=multiplicarMatrices (m,n); mostrarMatriz(mult); //se muestra el resultado de la multiplicacin
38
39
39
40
static public double [ ][ ] traspuesta (double A[][] ) { double aux ; for ( int i = 0 ; i < A.length ; i++ ) { for ( int j = 0 ; j < A[0].length ; j++ ) { if ( i < j ) { aux = A[i][j] ; A[i][j] = A[j][i] ; A[j][i] = aux ; } } } return A; b) Despus de haber realiza el paso anterior concluya que hace este mtodo.
2. Se tiene en una matriz donde se almacenan las notas de los estudiantes del curso de estructura de datos, solo se matricularon 7 estudiantes y las notas son: Primer parcial, segundo parcial, tercer parcial, y talleres
As:
Pedro Martnez Juan Valds Esteban Corales Miguel Prez Diana Ros Laura Gmez 4,3
40
41 a) Las notas definitivas de los estudiantes si se sabe que el primer parcial vale el 20%, el segundo parcial el 25%, el tercer parcial el 30% y los talleres 25%. Estas notas definitivas deben ser almacenada en un vector. b) Realice un mtodo para saber cul fue el estudiante que obtuvo la nota ms alta por cada una de las pruebas realizadas. c) Realice un mtodo que muestre cuantos estudiantes ganaron y cuanto perdieron la materia. Nota Pensando en cursos futuros el programa debe funcionar para cualquier cantidad de estudiantes. 3. Realice un programa que contenga un mtodo que llene una matriz nXm con nmeros. Luego debe crear otra matriz de tamao n+1Xm+1 y llenarla con los elementos de la matriz anterior y en la ltima columna de la nueva matriz deben quedar los resultados de la suma de los elementos de cada una de las filas de la matriz de entrada y en la ltima fila debe quedar la suma de las columnas de la matriz de entrada; Adems la suma total de todos los elementos de la matriz se almacenar en el elemento de la esquina inferior derecha de la matriz. Ejemplo: Si la matriz que ingresa es: 372 6 464 8 246 8 La matriz que se crea queda as: 3 7 2 6 18 4 6 4 8 22 2 4 6 8 60 9 17 12 22 160
41
42 6. LISTAS ENLAZADAS
Las estructuras enlazadas de datos son fundamentales para el desarrollo de software, especialmente en el diseo e implementacin de colecciones. Una estructura enlazada es una estructura de datos que utiliza variables de referencia a objetos con el fin de crear enlaces entre objetos. Una variable de referencia a objeto almacena la direccin de un objeto, que indica donde est almacenado en la memoria. Considere una situacin en la que una clase definida como dato, instancia una referencia a otro objeto de la misma clase. Por ejemplo, suponga que tenemos una clase denominada Person que contiene el nombre, la direccin y otra informacion relevante acerca de una persona y adems tambin contiene una variable de referencia a otro objeto Person. Public class Person { Private String name; Private String address; Private Person next; // un enlace a otro objeto Person //resto del cdigo } Utilizando exclusivamente esta clase, podemos crear una estructura enlazada. Cada objeto Person contendr un enlace a un segundo objeto Person. Este segundo objeto tambin contendr una referencia a un objeto Person, que a su vez contendr otra, etc Este tipo de objetos se denomina en ocasiones autoreferencial. Este tipo de relacin forma la base de lo que se denomina lista enlazada, que es una estructura enlazada en la que cada objeto hace referencia al siguiente, creando una ordenacin lineal de los objetos de la lista. Los objetos almacenados en una lista se denominan, de modo genrico, nodos de la lista. Una lista enlazada est compuesta de objetos, cada uno de los cuales apunta al siguiente objeto en la lista. A diferencia de las matrices, que tiene un tamao fijo, las listas enlazadas no tienen ningn lmite superior en lo que respecta a su capacidad, salvo las limitaciones de memoria de la propia computadora. Una lista enlazada se considera como una estructura dinmica, porque su tamao crece y se contrae
42
43 segn sea necesario para albergar todos los elementos que haya que almacenar. En java todos los objetos se crean dinmicamente a partir de un rea de memoria denominada cmulo del sistema o almacn de espacio libre. Al crear la lista insertamos los elementos por la cabeza. Cuando insertamos nuevos nodos podemos hacerlo por la cabeza o en cualquier posicin de la lista. En la Lista enlazada la coleccin de elementos (denominados nodos) estn dispuestos uno a continuacin del otro, y cada uno de ellos conectados al siguiente elemento por un enlace o referencia. La primera parte o campo contiene informacin y es por consiguiente una valor de tipo genrico (denominada dato, Tipo Elemento, Info, etc) y la segunda parte o campo es una referencia (denominada enlace o siguiente) que apunta al siguiente elemento de la lista.
Nodo
referen ciacia
Nod o
Nod o
El primer nodo se enlaza al segundo, el segundo nodo se enlaza al tercero y as sucesivamente hasta llegar al ltimo El final se identifica como el nodo cuyo campo referencia tiene el valor null. La lista se recorre desde el primero al ltimo nodo, en cualquier punto del recorrido la posicin actual se referencia por la referencia actual En caso de que la lista no contenga ningn nodo (est vaca), la cabeza es nulo Operaciones con listas Definicin de la clase nodo y referencia a nodo Inicializacin o creacin de la lista Insertar elementos en una lista Eliminar elementos de una lista Buscar elementos de una lista Recorrer una lista enlazada (visitar cada nodo de la lista) Comprobar que la lista est vaca.
43
44
Definicin de un nodo Cada nodo es una combinacin de dos partes: un tipo de dato (entero, doble, carcter o referencia) y un enlace al siguiente nodo Class nodo { Int dato } La construccin y manipulacin de una lista requiere el acceso a los nodos de la lista a travs de una o ms referencia a nodos. Normalmente se incluye una refencia al primer nodo (cabeza) y una referencia al ltimo nodo (cola) El ltimo elemento de la lista contiene una referencia nulo (null) que seala el final de la lista. Se puede utilizar null para cualquier valor de referencia que no apunte a ningn sitio.
La referencia null se utiliza, normalmente en dos situaciones: Usar la referencia nulo en el campo enlace o siguiente del nodo final de una lista enlazada. Cuando una lista enlazada no tienen ningn nodo, se utiliza la referencia null como referencia de cabeza y de cola. La lista se denomina lista vaca.
La referencia de cabeza y de cola en una lista enlazada puede ser null lo que indica que la lista esta vaca (no tiene nodos). Este suele ser un mtodo usual para construir una lista. Pasos para la construccin de una lista Definir la clase nodo (definir la clase elemento) Definir la clase lista, con la variable instancia referencia a nodo cabeza o primero Definir el mtodo constructor de lista que inicialice primero a null, lista vacia. Definir el mtodos crearLista(), de tal forma que cree iterativamente el primer elemento (primero) y los elementos sucesivos de una lista enlazada simplemente. Repetir hasta que no haya ms entrada para el elemento. 44
45
Null es una constante especifica de java. Se puede utilizar null para cualquier valor de referencia que no apunte a ningn sitio Insertar un elemento en una lista Vara dependiendo de la posicin en la que se desea insertar el elemento. Esta puede ser: En la cabeza (elemento primero) de la lista En el final (elemento ultimo) Antes de un elemento especificado Despus de un elemento especificado
Pasos para Insertar un elemento en la cabeza de una lista: Ms fcil y ms eficiente insertar el elemento nuevo en la cabeza de la lista Crear un nuevo nodo Hacer que el campo enlace del nuevo nodo apunte a la cabeza (primero nodo) de la lista original Hacer que el primero apunte al nuevo nodo que se ha creado
Pasos para la Insercin de un nuevo nodo que no est en la cabeza de la lista Crear un nodo con el nuevo elemento y el campo enlace a null La referencia al nodo creado se asigna a nuevo. Hacer que el campo enlace del nuevo nodo apunte al nodo que va despus de la de la lista. Hacer que el anterior. enlace apunte al nuevo nodo que se acaba de crear.
Pasos para la bsqueda de un elemento El algoritmo de bsqueda del elemento comienza con el recorrido de la lista mediante un ndice que comienza apuntando al nodo cabeza de la lista, que se corresponde con el miembro de la clase Listaprimero A cada iteracin del bucle se mueve la referencia ndice de un nodo hacia delante. El bucle termina cuando se alcanza la posicin deseada y el ndice apunta al nodo El bucle tambin se puede terminar si el ndice apunta a null,(lo que indicara que la posicin solicitada era mayor que el numero de nodo de la lista)
46
La operacin de eliminar un nodo de una lista enlazada supone unir el nodo anterior con el nodo siguiente al que se desea eliminar y liberar la memoria que ocupa. El algoritmo para eliminar un nodo que contienen un dato se puede expresar en estos pasos Bsqueda del nodo que contienen el dato. Se ha de tener la direccin del nodo a eliminar y la direccin del nodo anterior. La referencia enlace del nodo anterior ha de apuntar al enlace del nodo a eliminar En caso de que el nodo a eliminar sea el inicial, primero, se modifica el primero para que tenga la direccin del nodo siguiente. Por ltimo la memoria ocupada por el nodo la libera el sistema al dejar de estar referenciado Clasificacin de las listas: Lista simplemente enlazadas Listas doblemente enlazadas Listas circulares simple enlazadas Listas circular doblemente enlazada IMPLEMENTACION DE LAS LISTAS ENLAZADAS EN JAVA public class Nodo //definicion de la clase nodo { int informacion; Nodo enlace;
public Nodo(int x) //metodo constructor de la clase nodo recibe como parametros { //un valor entero y una referencia al siguiente nodo informacion = x; //construye un nodo enlace = null; } }
package lista; public class Lista { Nodo primero; // referencia al primer nodo de la lista
46
47
public Lista() //Metodo constructor de la clase lista { primero = null; //crea una lista la referencia al primer nodo a null } public void insertarCabezaLista(int dato) //mtodo para insertar un nodo por la cabeza o inicio de la lista { Nodo nuevo; //nuevo es la variable de tipo nodo, para crear el nuevo nodo nuevo = new Nodo(dato); //se crea el nuevo nodo nuevo.enlace = primero; // el nuevo nodo que apuntando o enlazado al primero primero = nuevo; //primero queda ahora referenciando al nuevo nodo } public void CrearLista(int numNodos) //metodo para crear una lista { //recibe como parametros el nmero de nodos que va a tener la lista //los nodos se va agregando por la cabeza de la lista int x=0; for (int i = 1; i <= numNodos; i++) { x= Lectura.leerEntero("Digite el campo informacin del nodo"); insertarCabezaLista(x); } } public void mostrarLista() //mtodo para mostrar el campo informacin de cada nodo de la lista { Nodo n; String mensaje = " "; n = primero; //utilizamos la variable n para refenciar la cabeza de la lista while (n != null) //se recorre la lista hasta llegar al ltimo nodo { mensaje = mensaje + n.informacion + " "; //se va imprimiendo el campo informacion de cada nodo n = n.enlace; //n pasa a referenciar al siguiente nodo } Lectura.mostrar("La lista es " + mensaje); //se muestran toda la lista } 47
48
public void insertarOtraPosicion(int posicion, int dato) //metodo para insertar un nodo en cualquier // posicin de la lista, tiene como datos de entrada la posicin en //la que se va insertar el nuevo nodo y la informacin del nodo { if (numNodo() >= posicion) //se valida que la posicin exista { Nodo anterior, nuevo; anterior = primero; //se guarda la referencia del primer nodo de la lista for (int i = 1; i < posicin-1; i++)//se recorre la lista hasta llegar a la posicin { //anterior a donde se insertara el nodo anterior = anterior.enlace; } nuevo = new Nodo(dato);//se crea el nuevo nodo nuevo.enlace = anterior.enlace; //el nuevo nodo se enlaza a donde estaba enlazado //el nodo anterior a el anterior.enlace = nuevo; //y el nodo anterior queda ahora enlazado al nuevo nodo } } public void insertarUltimo(int dato) //mtodo para insertar un nodo en la ultima posicin //de la lista { Nodo ultimo; ultimo = primero; //se guarda la referencia al primer nodo while (ultimo.enlace != null) //se recorre la lista hasta llegar al ltimo nodo { ultimo = ultimo.enlace; } ultimo.enlace = new Nodo(dato); //se enlaza el ultimo nodo al nuevo nodo ultimo = ultimo.enlace; //queda de ultimo el nodo insertado } public int numNodo() //metodo para contar el nmero de nodos de una lista { 48
49 Nodo anterior = primero; // se guarda la referencia al primer nodo de la lista int cantidadNodos = 0; while (anterior != null) //se recorre la lista hasta el final { cantidadNodos = cantidadNodos + 1; anterior = anterior.enlace; } return cantidadNodos; //se retorna la cantidad de nodos de la lista } public static void main(String[] args) //punto de partida de la aplicacin {
Lista L = new Lista();// se crea un objeto L de la clase lista int n= Lectura.leerEntero("Con cuntos elementos va a crearla lista?"); L.CrearLista(n); L.mostrarLista(); n=Lectura.leerEntero("Digite en valor para insertar por la cabeza de la lista") ; L.insertarCabezaLista(n); L.mostrarLista(); n=Lectura.leerEntero("Digite una posicin en la que quiera insertar un elemento"); int m=Lectura.leerEntero("Que valor va a insertar?"); L.insertarOtraPosicion(n,m ); L.mostrarLista(); n=Lectura.leerEntero("Digite un elemento para insertar en la ultima posicin"); L.insertarUltimo(n); L.mostrarLista(); } }
TALLER LISTAS ENLAZADAS 1. a) Corra el programa anterior paso a paso en java, entindalo, analcelo y vea cmo cambian las variables. b) Mejore el programa para que sea el usuario el que ingrese la informacin del nodo a insertar o crear. 2. Agregue un mtodo para buscar un nodo en la lista, el mtodo debe tener como dato de entrada la informacin del nodo y se debe retornar la posicin en la que se encuentra el nodo con esta informacin (asumimos que no hay nodos repetidos).
49
50 3. Haga un mtodo que reciba dos listas y determine si las listas son iguales 4. Realice un programa que contenga una lista de estudiantes donde cada estudiante tiene su nombre, cdigo y tres notas. Haga mtodos para: a) Crear la lista b) Ingresar un nuevo estudiante a la lista c) Dado el cdigo retorne el promedio del estudiante d) Calcule el promedio de todo el curso 5. Realice un mtodo que reciba una lista y pase la informacin a un vector y retorne el vector
50
51
Cada elemento contiene dos referencias, aparte del valor almacenado en el elemento, una referencia apunta al siguiente elemento de la lista y la otra referencia apunta al elemento anterior. Insertar un elemento en una lista doblemente enlazada La clase listadoble encapsula las operaciones bsicas de las listas doblemente enlazadas. La clase tiene la variable cabeza, que hace referencia al primer nodo de la lista. El constructor de la clase inicializa la lista a (null) Para aadir un nuevo nodo se definen varios mtodos segn la posicin donde se inserte el nodo. La posicin de insercin puede ser: En la cabeza (elemento primero de la lista) En el final de la lista (elemento ultimo) Antes de un elemento especificado. Despus de un elemento especificado.
Insertar un elemento en la cabeza de una lista doble El proceso de insercin se puede resumir en: Crear un nodo con el nuevo elemento; asignar la referencia al nodo nuevo que es una variable referencia local. Hacer que el campo enlace adelante del nuevo nodo apunte a la cabeza (primer nodo) de la lista original, y que el campo enlace atrs del nodo cabeza apunte al nuevo nodo. El campo atrs del nodo siguiente al nuevo tiene que apuntar a nuevo. 51
52 La direccin del nodo que esta antes de la posicin deseada para el nuevo nodo est en la variable referencia anterior. Hacer que anterior.adelante apunte al nuevo nodo. El Enlace atrs del nuevo nodo debe apuntar al anterior. El mtodo insertar despus() que implementa el algoritmo, tiene dos argumentos, anterior que apunta al nodo a partir del cual se inserta, y entrada que es el elemento del nodo. Hacer que cabeza (referencia. cabeza apunte al nuevo nodo que se ha creado.)
Insercin de un nuevo nodo que no est en la cabeza de la lista Requiere las siguientes etapas: Crear un nodo con el nuevo elemento; asignarla referencia al nodo nuevo, que es una variable referencia local. Hacer que el campo adelante del nuevo nodo apunte al nodo que esta despus de la posicin del nuevo nodo (o bien null si no hay ningn nodo despus de la nueva posicin) El campo atrs del nodo siguiente al nuevo tiene que apuntar a nuevo. La direccin del nodo que esta antes de la posicin deseada para el nuevo nodo est en la variable referencia anterior. Hacer que anterior.adelante apunte al nuevo nodo. El enlace atrs del nuevo nodo debe apuntar a anterior.
El mtodo insertar despus() implementa al algoritmo, tienen dos argumentos, anterior que apunta al nodo a partir del cual no se inserta y entrada que es el elemento del nodo.
Borrado de un elemento de una lista doblemente enlazada. Supone realizar el enlace de dos nodos, el nodo anterior con el nodo siguiente al que se desea eliminar. La referencia adelante del nodo anterior debe apuntar al nodo anterior; la memoria que ocupa se libera automticamente en el nodo deja de ser referenciado. Pasos 52
53 Bsqueda del nodo que contiene el dato. Se ha de tener la direccin del nodo a eliminar y la direccin de anterior. La referencia adelante del nodo anterior tienen que apuntar a la referencia delante a eliminar, esto es el caso de no ser el nodo cabecera. La referencia atrs del nodo siguiente a borrar, tiene que apuntar a la referencia atrs del nodo a eliminar, esto es el caso de no ser el nodo ultimo. En el caso de que el nodo a eliminar sea el primero, cabeza, se modifica para que tenga la direccin del nodo siguiente. La memoria ocupada por el nodo es liberada automticamente.
En algunas aplicaciones podemos desear recorrer la lista hacia adelante y hacia atrs, o dado un elemento, podemos desear conocer rpidamente los elementos anterior y siguiente. En tales situaciones podramos desear darle a cada celda sobre una lista una referencia a las celdas siguiente y anterior en la lista tal y como se muestra en la figura.
IMPLEMENTACION DE LISTAS DOBLEMENTE ENLAZADAS EN JAVA public class ListaDoble { Nodo primero; // referencia al primer nodo de la lista
public class Nodo //definicin de la clase nodo para la lista doblemente enlazada { int informacion; Nodo adelante; Nodo atras; public Nodo(int x) //Metodo constructor de la clase nodo con un parametro, x de tipo entero { //construye un nodo que tiene null en su campo adelante y atras informacion = x; 53
} public ListaDoble() //Mtodo constructor de la clase lista Doble { primero = null; //crea una lista la referencia al primer nodo a null (cabeza de la lista) } public void CrearLista(int numNodos) //mtodo para crear una lista { //recibe como parmetros el nmero de nodos que va a tener la lista //los nodos se va agregando por la cabeza de la lista int x; for (int i = 1; i <= numNodos; i++) { String N = JOptionPane.showInputDialog("Digite el campo informacin del nodo"); x = Integer.parseInt(N); insertarCabezaLista(x); } }
public void mostrarLista() //metodo para mostrar el campo informacin de cada nodo de la lista { Nodo n; String mensaje = " "; n = primero; //utilizamos la variable n para refenciar la cabeza de la lista while (n != null) //se recorre la lista hasta llegar al ultimo nodo { mensaje = mensaje + n.informacion + " "; //se va imprimiendo el campo informacion de cada nodo n = n.adelante; //n pasa a referenciar al siguiente nodo } JOptionPane.showMessageDialog(null, "La lista es " + mensaje); //se muestran toda la lista }
54
55 public void insertarCabezaLista(int dato) //metodo para insertar un nodo por la cabeza de la lista Doble { Nodo nuevo; //nuevo es la variable de tipo nodo, para crear el nuevo nodo nuevo = new Nodo(dato); //se crea el nuevo nodo nuevo.adelante = primero; // el nuevo nodo que apuntando o enlazado al primero if (primero!=null) primero.atras=nuevo; primero = nuevo; //primero queda ahora referenciando al nuevo nodo } public void insertarDespues(int posicion, int dato) //metodo para insertar un nodo en cualquier // posicion despues de la posicion dada, tiene como datos de entrada la posicion despues en que se va a insertar // el nuevo nodo y la informacin del nodo { if (numNodo() >= posicion) //se valida que la posicin exista { Nodo anterior, nuevo; anterior = primero; //se guarda la referencia del primer nodo de la lista for (int i = 1; i < posicion; i++)//se recorre la lista hasta llegar a la posicin { //anterior a donde se insertara el nodo anterior = anterior.adelante; } nuevo = new Nodo(dato);//se crea el nuevo nodo nuevo.adelante = anterior.adelante; if (anterior.adelante!=null) anterior.adelante.atras=nuevo; anterior.adelante = nuevo; } }
public int numNodo() //metodo para contar el nmero de nodos de una lista { Nodo anterior = primero; // se guarda la refrencia al primer nodo de la lista int cantidadNodos = 0; while (anterior != null) //se recorre la lista hasta el final { cantidadNodos = cantidadNodos + 1; anterior = anterior.adelante; 55
public class Main { public static void main(String[] args) //punto de partida de la aplicacion { ListaDoble L = new ListaDoble();// se crea un objeto L de la clase lista //Doblemente enlazada L.CrearLista(3); L.mostrarLista(); L.insertarDespues(3, 11); L.mostrarLista(); L.insertarDespues(2, 12); L.mostrarLista(); } }
56
57 8. LISTAS CIRCULARES
En las listas lineales simples o en las dobles siempre hay un primer nodo y un ltimo nodo, que tienen el campo de enlace nulo, Una lista circular por su naturaleza no tiene principio ni fin. Sin embargo resulta til establecer un nodo del cual se accede a la lista y as poder acceder a los nodos. Se necesita la clase lista circular y la clase nodo. El constructor de la clase nodo vara respecto al de las listas no circulares, la referencia enlace en vez de inicializarse a null se inicializa para que apunte al mismo nodo, as forma una lista circular de un solo nodo
Insertar un elemento en una lista circular Este algoritmo vara dependiendo de la posicin en que se desee insertar el elemento. Consideremos que se hace como nodo anterior
IMPLEMENTACION DE LISTAS CIRCULARES EN JAVA //Definicion de la clase lista Circular public class ListaCircular { Nodo lc; // referencia al ultimo nodo de la lista
public class Nodo //definicion de la clase nodo { int informacion; Nodo enlace; public Nodo(int dato) //Metodo constructor de la clase nodo con un parametro, { informacion = dato; enlace = this; //el nodo apunta a el mismo } } public ListaCircular() //Metodo constructor de la clase lista circular { lc = null; //crea una lista la referencia al primer nodo a null 57
58 } public void CrearLista(int numNodos) //metodo para crear una lista { //recibe como parametros el nmero de nodos que va a tener la lista int x; for (int i = 1; i <= numNodos; i++) { String N = JOptionPane.showInputDialog("Digite el campo informacion del nodo"); x = Integer.parseInt(N); insertar(x); //se llama al metodo insertar } } public void mostrarLista() //metodo para mostrar el campo informacion de cada nodo de la lista circular { Nodo n; String mensaje = ""; if (lc!=null) { n = lc.enlace; do { mensaje = mensaje + n.informacion + " "; //se va imprimiendo el campo informacion de cada nodo n = n.enlace; //n pasa a referenciar al siguiente nodo } while (n!=lc.enlace); } else mensaje="Lista circular vacia"; JOptionPane.showMessageDialog(null, mensaje); //se muestran toda la lista */ }
public void insertar(int dato) //metodo para insertar un nodo por la cabeza de la lista { Nodo nuevo; //nuevo es la variable de tipo nodo, para crear el nuevo nodo nuevo = new Nodo(dato); //se crea el nuevo nodo if (lc!=null)//lista circular no vacia {
58
59 nuevo.enlace =lc.enlace; // el nuevo nodo queda apuntando o enlazado hacia donde apuntaba el ultimo lc.enlace= nuevo; //lc queda ahora referenciando al nuevo nodo } lc=nuevo; }
public static void main(String[] args) //punto de partida de la aplicacion { ListaCircular L=new ListaCircular();// se crea un objeto L de la clase lista L.CrearLista(3); L.mostrarLista(); L.mostrarLista(); L.insertar(10); L.mostrarLista(); } }
59
60 9. COLAS Una cola es una estructura de datos que almacena elementos en una lista y permite acceder a los datos por uno de los dos extremos de la lista. Un elemento se inserta en la cola (parte final) y se suprime o elimina por el frente (parte inicial) de la lista. Las aplicaciones utilizan una cola para almacenar elementos en su orden de aparicin o concurrencia. Los elementos se eliminan (se quitan) de la cola por el mismo orden en que se almacenan y, por consiguiente, una cola es una estructura de tipo FIFO (first in/first out, primero en entrar/primero en salir, o bien primero en llegar/primero en ser atendido) El servidor de atencin clientes en un almacn es un ejemplo tpico de cola. La accin de gestin de memoria intermedia (buffering) de trabajos o tareas de una impresora en un distribuidor de impresoras (spooler) es otro ejemplo tpico de cola de trabajos de modo que los trabajos se imprimen en el mismo orden en que se recibieron por la impresora. Este sistema tienen el gran inconveniente de que si un trabajo personal consta de una nica pagina para imprimir y delante de su peticin de impresin existe otra peticin para imprimir 300 paginas, deber esperar a la impresin de esas 300 pginas antes de que se imprima su pgina. Las acciones que estn permitidas son: Creacin de una cola vaca Verificacin de que una cola est vaca Aadir un dato al final de una cola. Eliminacin de los datos de la cabeza de la cola
//definicin de la clase NodoCola public class NodoCola //definicion de la clase nodo { int informacion; NodoCola enlace; public NodoCola(int x) //Metodo constructor de la clase nodo con un parametro, x de tipo entero { //construye un nodo que tiene null en su campo enlace
60
} //**************************************************** //definicin de la clase Cola public class Cola { NodoCola primero; //referencia al primer nodo de la lista NodoCola ultimo; // referencia al ltimo nodo de la lista
public Cola() //Metodo constructor de la clase Cola { primero = null; //crea una cola la referencia al primer y ultimo a null ultimo=null; } public void CrearCola(int numNodos) //metodo para crear una lista { //recibe como parametros el nmero de nodos que va a tener la cola NodoCola nuevo; int x; for (int i = 1; i <= numNodos; i++) { x=Lectura.leerEntero("Digite el campo informacion del nodo"); nuevo = new NodoCola(x); //creamos el nodo usando el metodo constructor if (primero==null) { primero=nuevo; } else { ultimo.enlace=nuevo; } ultimo=nuevo; } }
61
62 public void mostrarCola() //metodo para mostrar el campo informacion de cada nodo de la cola { NodoCola n; String mensaje = " "; n = primero; //utilizamos la variable n para refenciar la cabeza de la cola while (n != null) //se recorre la lista hasta llegar al ultimo nodo { mensaje = mensaje + n.informacion + " "; //se va imprimiendo el campo informacion de cada nodo n = n.enlace; //n pasa a referenciar al siguiente nodo } Lectura.mostrar("La cola es " + mensaje); // JOptionPane.showMessageDialog(null, "La cola es " + mensaje); //se muestran toda la cola } public void meter(int dato) //metodo para insertar un nodo { NodoCola nuevo; //nuevo es la variable de tipo nodo, para crear el nuevo nodo nuevo = new NodoCola(dato); //se crea el nuevo nodo ultimo.enlace=nuevo; ultimo=nuevo; //ultimo hace referencia al nuevo nodo } public void sacar() { primero=primero.enlace; }
public int numNodo() //metodo para contar el nmero de nodos de una cola { NodoCola anterior = primero; // se guarda la referencia al primer nodo de la cola int cantidadNodos = 0; while (anterior != null) //se recorre la cola hasta el final { cantidadNodos = cantidadNodos + 1; anterior = anterior.enlace; } return cantidadNodos; //se retorna la cantidad de nodos de la cola } 62
63
public static void main(String[] args) //punto de partida de la aplicacion { Cola L = new Cola();// se crea un objeto L de la clase lista int x=Lectura.leerEntero("Con cuantos elementos va a crear la cola?"); L.CrearCola(x); L.mostrarCola(); L.sacar(); //saca un elemento de la cola L.mostrarCola(); x=Lectura.leerEntero("Que elemento va a ingresar?"); L.meter(x); // L.mostrarCola(); } }
TALLER COLAS 1. Implemente la clase Cola Banco formada clientes, donde cada cliente es un nodo con la informacin de, nombre de la transaccin a realizar, y el tiempo de duracin de la transaccin. Como se muestra: Transaccin Retiro Depsito Consulta Actualizacin Pagos Tiempo 4 min 2 min 3.5 min 5 min 2 min
Realice mtodos para: a) Crear la cola para n personas. b) Calcule el tiempo total que se demora el cajero en atender a todas las personas en la cola c) Dado el nombre de una persona estime el tiempo que se demora en el banco. (Tenga en cuenta que el tiempo de permanencia de la persona en el 63
64 banco depende de la transaccin a realizar y de lo que espere en la cola a antes de ser atendido).
2. Implemente la clase cola, con sus respectivos mtodos, pero usando vectores.
64
65
10 RECURSIVIDAD Este tema se incluye dado la necesidad de saber programar recursivamente, para asi poder entender las estructuras de rboles que son estructuras recursivas. El concepto de recursividad va ligado al de repeticin. Son recursivos aquellos algoritmos que estando encapsulados dentro de una funcin, son llamados desde ella misma una y otra vez, en contraposicin a los algoritmos iterativos, que hacen uso de bucles while, do-while, for, etc. Definicin: algo es recursivo si se define en trminos de si mismo (cuando para definirse hace mencin as mismo). Para que una definicin recursiva sea vlida, la referencia as misma debe ser relativamente ms sencilla que el caso considerado. Ejemplos a) Calcula el factorial de un nmero int factorial(int n) { if(n==0) return 1; else return n*factorial(n-1); }
b) Permite obtener la divisin de un nmero por el mtodo de restas sucesivas int division (int a, int b) { if(b > a) return 0; else return division(a-b, b) + 1; } c) Calcula un trmino de la serie de fibonacci int fibonaci(int n) { if(n==1 || n==2) return 1; else return fibonaci(n-1)+fibonaci(n-2); }
65
66
d) Calcula el elemento menor de un vector int menorvec (int x [], int n, int menor) { if (n == 0) if (menor > x [n]) return x [0]; else return menor; else if (menor > x [n]) return menorvec (x, n - 1, x [n]); else return menorvec (x, n - 1, menor); }
TALLER RECURSIVIDAD 1) Implemente el mtodo para saber si un nmero es primo. Un nmero no es primo si tiene algn divisor diferente de 1 y del mismo nmero. (haga prueba paso a paso) 2) Realice un mtodo recursivo para calcular el elemento mayor de un vector.
66
67 11. ARBOLES
Las estructuras dinmicas lineales de datos tienen grandes ventajas de flexibilidad sobre las representaciones contiguas; sin embargo tienen un punto dbil, son listas secuenciales, es decir, estn dispuestas de modo que es necesario moverse a travs de ellas una posicin cada vez. En este captulo se trataran las estructuras de datos no lineales, que resuelven los problemas que plantean las listas lineales y en las que cada elemento puede tener diferentes elementos siguientes, que introducen el concepto de estructuras de bifurcacin. Las principales estructuras de este tipo son: rboles: los elementos estn organizados como un verdadero rbol. Grafos: los elementos estn organizados como una red de datos. rboles En su sentido amplio, un rbol permite almacenar informacin y organizarla de forma que tengan sucesores o elementos siguientes, como hijos en una forma de las ramas de un rbol.
rbol genealgico
Aplicaciones En computacin: los arboles sintcticos son utilizados para la representacin e interpretacin de trminos de un lenguaje o expresiones aritmticas, pasando por los arboles de activacin de procedimientos recursivos, hasta la representacin de datos que se desea mantener ordenados con un tiempo de acceso relativamente bajo. En las bases de datos relacionales para poder localizar en forma rpida un registro de una tabla a partir de una clave, se utilizaron objetos asociados a las 67
68 tablas llamados ndices, estos ndices son arboles binarios de bsqueda almacenados en disco, a partir de una clave indican donde se encuentra el registro correspondiente en la tabla. En teora de compiladores durante la fase de anlisis de cdigo fuente, los analizadores lxicos, sintcticos y semnticos utilizan tablas de smbolos, en donde se almacenan la palabra clave y las palabras reservadas y sus atributos, implementados por lo general como arboles binarios de bsqueda.
En sntesis se utiliza un rbol binario de bsqueda cuando se desea almacenar en una estructura de datos cierta informacin, a la cual luego se desea acceder en forma rpida a partir de una clave.
Conceptos
Raz.-Es el primer nodo del rbol y es por donde se accede a l (solo tiene sucesores), es decir, la cabeza del rbol siempre ser la raz. Nodo Hoja: Aquel nodo que no tiene hijos o sucesores. Nodo Interno.-Aquel nodo que tiene un antecesor y por lo menos un sucesor (ni raz ni hojas). Altura.- Es la cantidad de nodos que se recorren para llegar desde la raz hasta el nodo hoja ms alejado de todo el rbol. Grado.- Cantidad mxima de hijos que puede tener cualquier nodo. Nivel.- Numero de generaciones que se est de la raz. La raz est en un nivel = 0. Ruta.- Camino que se recorre para llegar de un nodo a otro. Subrbol.- Cualquier nodo puede ser considerado como la raz de un subrbol. Peso.- Es la cantidad de nodos hoja del rbol. Visita.- Cuando se accede al dato de un nodo. 68
69
Recorrido.- Cuando se visita todos los nodos de un rbol en algn orden en especial. Nodo completo.- Un nodo es completo cuando tiene todos sus hijos o no tiene a ninguno. rbol Completo.- Un rbol es completo cuando tiene todos sus nodos completos. rboles Binarios Los arboles binarios son un tipo especial de rbol donde cada nodo puede tener a lo mucho 2 hijos (grado = 2). Los dos hijos de cada nodo en un rbol binario son llamados hijo izquierdo e hijo derecho. Recorrido de un rbol binario Recorrer un rbol consiste en acceder una sola vez a todos sus nodos. Esta operacin es bsica en el tratamiento de arboles y nos permite, por ejemplo, imprimir toda la informacin almacenada en el rbol, o bien eliminar toda esta informacin o, si tenemos un rbol de nmeros, sumar todos los valores, etc. En el caso de los arboles binarios, el recorrido de sus distintos nodos se debe realizar en tres pasos: Visitar la raz. Visitar el subrbol izquierdo. Visitar el subrbol derecho. Estas tres acciones repartidas en diferentes ordenes proporcionan los diferentes recorridos del rbol: preorden, enorden y postorden. Su nombre refleja el momento en que se visita el nodo raz. Recorrido preorden Visitar la raz Recorrer el subrbol izquierdo en preorden Recorrer el subrbol derecho en preorden
Recorrido enorden Recorrer el subrbol izquierdo en inorden Visitar la raz Recorrer el subrbol derecho en inorden Recorrido postorden Recorrer el subrbol izquierdo en postorden Recorrer el subrbol derecho en postorden Visitar la raz
69
70
B F H
J K L
rboles Binarios de Bsqueda Son arboles binarios que tienen los datos ordenados de tal manera que todos los datos que estn en el subrbol izquierdo son menores que la raz y todos los datos que estn en el subrbol derecho son mayores o iguales que la raz. (Tomado de: Estructuras de datos en Java, Cristian Denis Mamani Torres)
70
71
public void preorden(NodoBinario nodo) { //recorrido en preorden System.out.println(nodo.informacion); //imprime la informacin de la raz if (nodo.Izquierdo!=null) { preorden(nodo.Izquierdo); //luego lo recorre el subarbo izquierdo en preorden } if (nodo.derecho!=null) { preorden(nodo.derecho); //luego se recorre el subarbol derecho en preorden } } public void inorden (NodoBinario nodo) { if (nodo.Izquierdo!=null) //si el subarbo izquierdo no est vacio, entonces se recorre el subarbol izquierdo en inorden { nodo.inorden(nodo.Izquierdo); } System.out.println(nodo.informacion);//se imprime la informacin de la raiz if (nodo.derecho!=null)//si el subarbo derecho no esta vacio, entonces se recorre el subarbol derecho en inorden { nodo.inorden(nodo.derecho); } }
public NodoBinario insertarNodo(int dato, NodoBinario nodo) //mtodo para insertar un elemento en un rbol de bsqueda { if (nodo==null) { NodoBinario nodoNuevo=new NodoBinario(dato); 71
72 nodo=nodoNuevo; } else if (nodo.informacion>dato) { nodo.Izquierdo=insertarNodo(dato,nodo.Izquierdo); } else if (nodo.informacion<dato) { nodo.derecho=insertarNodo(dato, nodo.derecho ); } return nodo; } public boolean buscar(int dato, NodoBinario nodo) { //mtodo para buscar un valor en un arbol boolean encontrado=false; if (nodo==null) { encontrado=false; } else if (nodo.informacion==dato) { System.out.println("encontrado"); encontrado=true; } else if (nodo.informacion>dato) { encontrado=buscar(dato,nodo.derecho); } else if (nodo.informacion<dato) { encontrado=buscar(dato, nodo.derecho); } return encontrado; }
72
73
public static void main(String[] args) { NodoBinario arbolito; int numNodos= Lectura.leerEntero("digite cantidad de elementos"); int dato= Lectura.leerEntero("digite la informacin de la raiz"); arbolito=new NodoBinario(dato); for (int i=1; i<numNodos;i++) { dato= Lectura.leerEntero("digite el dato"); arbolito.insertarNodo(dato, arbolito); } System.out.println("recorrido en preorden"); arbolito.preorden(arbolito); System.out.println("recorrido en inorden"); arbolito.inorden(arbolito); arbolito.buscar(4, arbolito);
} }
73
74
TALLER ARBOLES
1.
50,60, 70, -100,-201,-6,-8,-50,3/4,10/5,21,100,200,3,50,8 b) El rbol resultante recrralo en inorden c) El rbol resultante recrralo en preorden d) El rbol resultante recrralo en postorden
2. En una Universidad tienen un Listado de N estudiantes, los datos del estudiante estn compuestos por: CODIGO 52 11 22 44 12 101 .. .. NOMBRE CARLOS JUANA CARLOS JAIRO FERNANDO PILAR . .. TELEFONO 2520555 552255 887788 777997 442232 8799 . .
Se necesita guardar los datos de los estudiantes en un rbol binario, los nodos del rbol deben contemplar el cdigo, nombre y telfono del estudiante, la llave principal del rbol es el cdigo del estudiante. El programa de estudiantes debe tener un men con: a) insertar estudiante b) Consultar estudiante por su cdigo c) Lista estudiante(postorden) d) Actualizar nombre e) salir
3. El rbol genealgico de una familia se almacena en un rbol binario, la informacin que se almacena para cada miembro de la familia es el nombre de la persona, ao en que naci, ao en que muri (para identificar que la persona vive se le coloca un 0 en el campo ao en que muri), numero de cedula de la persona, color de ojos, estatura, color de cabello. Realizar un programa que permita
74
75 a) Buscar el nombre del padre de un miembro de la familia dado del nombre del hijo (se asume que en la familia no hay nombres repetidos) b) Dado el numero de cedula mostrar todas las caractersticas de la persona. c) Dado el numero de cedula decir a qu edad muri la persona en caso de ya haber fallecido.
75
76
TALLER FINAL TEMAS: LISTAS, COLAS, Y ARBOLES BINARIOS. 4. La profesora Marisol Se desea tener la informacin de los estudiantes del curso de estructura de datos, cada estudiante tiene su nombre, cdigo, nota primer parcial, nota segundo parcial, y talleres. La profesora necesita un programa en java que le permita: a) Llenar la lista con la informacin de sus estudiantes, b) Calcular el promedio del curso c) El nombre del estudiante que se destaco por su rendimiento d) Cuantos estudiantes perdieron la materia e) Cuantos estudiantes la ganaron f) Adems si un estudiante cancela el curso este debe ser sacado automticamente de la lista.
Implemente en java un programa que le ayude a su profesora a obtener estos resultados. 5. En la sala de sistemas del Camacho se tiene una impresora donde los estudiantes pueden ir a imprimir sus trabajos. Los usuarios envan los documentos para ser impresos cada 10 minutos, y se tiene una cola donde se va almacenando, la identificacin del documento y el tiempo que se va a demorar un documento en imprimirse (este valor siempre es menor de 10 minutos). El servicio de impresin en la sala de sistemas a veces dura una hora y otras veces esta por dos horas. El monitor de la sala requiere un programa que le permita: a) Almacenar los trabajos a imprimir en una cola, tenga en cuenta que el tamao de la cola es decir la cantidad de trabajos que se pueden imprimir depende del tiempo de servicio de la sala de sistemas. b) Calcular los tiempos en que la impresora est ocupada, c) Calcular el tiempo ocioso de la impresora es decir el tiempo que esta sin imprimir Implemente en java un programa que le permita al monitor de la sala satisfacer estas necesidades.
76