76
1 1 INTRODUCCION En la presente guía del curso de estructuras de datos se desarrollan los temas del curso y al final se presenta un taller de cada tema. Cada estudiante matriculado en el curso está en la obligación de leer cada tema y desarrollar los talleres que se plantean al final de cada capítulo, para garantizar su aprendizaje y aprobación del curso. Listado de libros de estructura de datos que se encuentran en la biblioteca de la institución Antonio Jose Camacho A continuación se presenta el listado de libro que se encuentran en la biblioteca de la institución y que pueden servir como libros guías 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 más 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 diseño de estructuras. Y algoritmos Autor: Lewis chase Editorial: Addison Wesley 5. Estructuras de datos- teoría y problemas resueltos Autor: Symout Lipchutz Editorial: mc graw hill 6. Estructuras de datos en java Autor: Adan Drozdek Editorial: Thomson 7. Introducción a las estructuras de datos, aprendizaje basado en casos Autor: jorge Villalobos Editorial:prentice hall

Guia e Structur Asded a to s

Embed Size (px)

Citation preview

Page 1: Guia e Structur Asded a to s

1

1

INTRODUCCION En la presente guía del curso de estructuras de datos se desarrollan los temas del curso y al final se presenta un taller de cada tema. Cada estudiante matriculado en el curso está en la obligación de leer cada tema y desarrollar los talleres que se plantean al final de cada capítulo, para garantizar su aprendizaje y aprobación del curso. Listado de libros de estructura de datos que se encuentran en la biblioteca de la institución Antonio Jose Camacho A continuación se presenta el listado de libro que se encuentran en la biblioteca de la institución y que pueden servir como libros guías 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 más 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 diseño de estructuras. Y algoritmos Autor: Lewis chase Editorial: Addison Wesley 5. Estructuras de datos- teoría y problemas resueltos Autor: Symout Lipchutz Editorial: mc graw hill 6. Estructuras de datos en java Autor: Adan Drozdek Editorial: Thomson 7. Introducción a las estructuras de datos, aprendizaje basado en casos Autor: jorge Villalobos Editorial:prentice hall

Page 2: Guia e Structur Asded a to s

2

2

1. MÉTODOS: Son bloques de código que tienen nombre, tipo de acceso, tipo de retorno y lista de argumentos o parámetros. El código de un método va encerrado entre llaves { } Sintaxis Tipo nombre(lista de parámetros) { Cuerpo del método } Tipo: especifica el tipo de datos devuelto por el método nombre: nombre que identifica al método Lista parámetros: secuencia de parejas de identificadores y tipos de datos separados por comas, los parámetros son variables que reciben el valor de los argumentos pasados al método cuando este es llamado. Si el método no tiene Parámetros, entonces la lista de parámetros será vacía Si un método no retorna ningún valor, entonces el tipo de datos devuelto por el método es void. Una clase contiene métodos, el método principal se llama main. Los métodos pueden ser llamados desde cualquier otro método. En Java, todos los métodos deben estar declarados y definidos dentro de la clase, y hay que indicar el tipo y nombre de los argumentos o parámetros que acepta. Los argumentos son como variables locales declaradas en el cuerpo del método que están inicializadas al valor que se pasa como parámetro en la invocación del método. La ejecución del programa siempre empieza desde main. Llamada a un método Los métodos para poder ser ejecutados, han de ser llamados o invocados.

Page 3: Guia e Structur Asded a to s

3

3

En Java se puede invocar un método de clase utilizando el nombre de la clase, el operador punto y el nombre del método. MiClase.miMetodoDeClase(); Nota La palabra Static; permite hacer referencia a los métodos de una clase sin necesidad de instanciar un objeto, para llamarlos. ACCESO A LOS METODOS Public() publico se puede llamar por cualquier código que tenga accesos a la clase. Private() privado solo se puede llamar desde otro método de la clase en que se define el método privado. Protected ()protegido se puede llamar desde cualquier parte de la clase en que el método esta definido y por cualquier otro método de las clase que heredan de la clase en que esta definido el método. También esta disponible en cualquier objeto de las clases pertenecientes al mismo paquete que la clase en que esta definido el método. Si no se especifica ningún tipo de acceso, se utiliza el acceso por defecto que significa que el método 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 método, mientras que si se modifica una variable pasada por referencia, la variable original del método de llamada se vera afectada de los cambios que se produzcan en el método al que se le ha pasado como argumento.

Page 4: Guia e Structur Asded a to s

4

4

METODOS PARA LECTURA DE DATOS Aquí hemos definido la clase Lectura con los métodos 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 métodos, 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

Page 5: Guia e Structur Asded a to s

5

5

String N=JOptionPane.showInputDialog(mensaje); float n= Float.parseFloat (N); return n } 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 número que se saque de una bolsa

en el momento de cancelar la compra, el descuento se realizara así:

Si de la bolsa saca un número menor que 74 el descuento sobre la compra

es del 15%, y si el número 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 cuál es el descuento que debe hacer a sus clientes, conociendo

el valor de la compra y el número sacado de la bolsa.

2. Se requiere crear un método que reciba como entrada un número n (que es

la cantidad de datos que se van a pedir luego). El método debe pedir al

usuario el que ingrese n datos y mostrar en pantalla el cuadrado de cada

número ingresado.

SOLUCION Se ha implementado métodos para resolver cada problema se utilizara los métodos ya implementados para lectura de datos.

public class Main { public static void descuentoSupermercado () //metodo para calcular el descuento que se hace en un supermercado

Page 6: Guia e Structur Asded a to s

6

6

{ double descuento=0, compra=0; int n=0; n=Lectura.leerEntero("digite nùmero"); 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 métodos descuentoSupermercado(); cuadrados(4); } }

Page 7: Guia e Structur Asded a to s

7

7

TALLER 1: METODOS

Importante: cada uno de los ejercicios planteados deben ir dentro de un método y desde el main del programa solo debe aparecer el llamado a los métodos, no se acepta todo el código escrito en el main().

1. En una Universidad existen tres programas académicos que son: Licenciatura Matemáticas, Tecnología en Electrónica, y Tecnología de Sistemas, los cuales tienen un costo de 1.000.000 para Tecnología Electrónica, $1.200.000 para Matemáticas y $1.300.000 para Tecnología de Sistemas, además 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 matrícula. (Utilice métodos).

2. Realizar un programa que incluya un método que calcule la suma de los primeros n números 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 método que calcule el factorial de un número.

6. Resolver tres ejercicios más con ciclos, de un libro de la biblioteca, anotar la

bibliografía del libro (nombre, autor, editorial), página y número del

ejercicio. (No se acepta de internet).

Page 8: Guia e Structur Asded a to s

8

8

Organización y convenciones del código en Java

Java requiere que cada clase pública sea almacenada en un archivo con el

nombre de la clase, lo cual implica que no podremos poner más de una clase

pública por archivo. O sea, si tenemos una clase pública 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 válido sería 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 utilización 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.*;

(tomado de:

http://materias.fi.uba.ar/7507/content/20101/lecturas/organizacion_del_c

odigo_en_java.pdf)

Page 9: Guia e Structur Asded a to s

9

9

En nuestro ejemplo tenemos el proyecto arreglo, dentro del cual tenemos la

clase Lectura y la clase vectores, la clase vectores tiene métodos que utilizan

los métodos de la clase Lectura. Como todo esta agrupado en el mismo

paquete, pues no hay que importar ningún paquete.

Pero cuando realice otro ejercicio, si deseo utilizar una clase que está en otro

proyecto

Se hace clic derecho sobre el proyecto actual

Aparece la siguiente ventana

Aparece la siguiente ventana

En la opción 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.

CORRER EL PROGRAMA PASO A PASO

Page 10: Guia e Structur Asded a to s

10

10

No ubicamos con el cursor en la posición desde donde vamos a empezar a ejecutar el programa

Hacemos clic en la opción Debug->Run to cursor

Y con F8 vamos corriendo cada línea. Cuando no queremos entrar en el cuerpo de algún método, hacemos F7, Por ejemplo en los métodos de lectura de datos o los propios de java, o sencillamente en algún método 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: Después de pasar por la línea int vec1[]=new int[t]; ¿Con que valores queda la variable vec1? Después de pasar por la línea vec1=llenarArreglo(t) ¿Como quedo el vector? Explique que se hace en esta línea

Page 11: Guia e Structur Asded a to s

11

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 dimensión 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 día de una ciudad en un mes etc. Los valores de un array se numeran consecutivamente 0,1,2,3, (posiciones

en el arreglo) Ejemplo:

25 34 5 7 6 7

0 1 2 3 4 5 Arreglo de 6 elementos, todos de tipo entero Declaración de un arreglo unidimensional en java 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 número 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. Tamaño de los arrays

P Posiciones en el

arreglo

P Valores guardados

en el arreglo

Page 12: Guia e Structur Asded a to s

12

12

Java considera un array como un objeto, debido a ello se puede conocer el número 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 posición 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 práctico cuando contienen muchos elementos. También 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. IMPLEMENTACION EN JAVA DE ARREGLOS UNIDIMENSIONALES

package arreglos; import javax.swing.JOptionPane; public class Main { static int[] llenarArreglo(int tamaño) { //método para inicializar el arreglo, recibe como parámetro a tamaño que es el

número de elementos //que va a tener el arreglo

Page 13: Guia e Structur Asded a to s

13

13

int n; int vector[]=new int[tamaño]; //se define el arreglo //se llena el arreglo for (int i=0; i<tamaño; i=i+1) { n=Lectura.leerEntero("Digite el elemento de la posición " + i); vector[i]= n; } return vector; } static void mostrarArreglo(int v[]) { //metodo para mostrar el contenido del arreglo String mensaje=""; int tamaño=v.length; //mostrar el arreglo con sus elementos for (int i=0; i<tamaño; 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 número en la posición "+i+" es "+v[i]; } Lectura.mostrar(mensaje); } static int sumaElementosArreglo(int v[]) { //método 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; }

Page 14: Guia e Structur Asded a to s

14

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 método que inicializa el arreglo mostrarArreglo(vec); //llamado al método 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 métodos, además debe contener un menú para que el usuario

seleccione la opción a realizar.

a) Escribir un método que calcule el producto escalar de dos vectores. Si v y w

son los vectores y n su tamaño, el producto escalar se calcula como la

sumatoria de v(i)*w(i)

b) Implementar un método calcule el producto de un número por un vector

(devuelve el vector resultante de multiplicar todas las componentes del

vector inicial por un número)

Page 15: Guia e Structur Asded a to s

15

15

c) Escribir un método que calcule el vector resultante de sumar a cada una de

las componentes de un vector dado, un número real

d) Desarrollar un método que devuelva el mínimo de los elementos de un vector.

e) Escribir un programa que devuelva el máximo de los elementos de un

vector.

2. Realice un programa que contenga métodos para:

a) Guardar las temperaturas del mes de febrero (de este año) con valores

dados por el usuario

b) Mostar La temperatura mayor

c) Mostrar La temperatura menor

d) Calcule y diga cuál es la temperatura promedio para este mes.

e) Extienda el método 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 más del mínimo

b) Cuántos ganan menos que el sueldo mínimo

c) Haga un método 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.

Page 16: Guia e Structur Asded a to s

16

16

3. METODOS DE ORDENAMIENTO El propósito principal de un ordenamiento es el de facilitar las búsquedas de los elementos del conjunto ordenado METODO DE SELECCIÓN El algoritmo de ordenamiento por selección 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 posición. La otra con los elementos que no han sido todavía ordenados. En cada iteración, localizamos el menor elemento de la parte no ordenada, lo intercambiamos con el primer elemento de esta misma región 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; } } //aquí se intercambian las posiciones, el menor pasa a la primera posición

del vector //y el elemento que estaba allí pasa a la posición donde estaba el menor. aux=v[i]; v[i]=min; v[pos]=aux; } }

P El objetivo del ciclo interior es

buscar el menor valor de la

parte si ordenar. Dicha parte

comienza en la posición i y va

hasta el final del ciclo, deja en

la variable min el menor valor

encontrado y en la variable pos

la posición del elemento menor

(min)

Page 17: Guia e Structur Asded a to s

17

17

PRUEBA PASOS A PASO DEL METODO DE SELECCIÓN

v min pos

aux i j

60

50

40

30

0

0

0

0

60

0

1

50<60 VERDADER

O

50

1

2

40<50 VERDADER

O

40

2

3

VERDADERO

30<40 VERDADER

O

30

3

4

//

30

50

40

60

60

1

50

1

2

40<50 VERDADER

O

40

2

3

60<40 FALSO

4

//

30

40

50

60

50

2

50

2

3

60<50 FALSO

4 //

Page 18: Guia e Structur Asded a to s

18

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 demás elementos se acercan a su posición 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 método se llama burbuja, porque hace que los elementos vayan subiendo poco a poco hasta ocupar su posición final. Al final de la primera iteración el último elemento se encuentra ya ordenado. Al final de cada iteración, en la parte final del arreglo están los elementos ya ordenados, los cuales además son mayores que todos los elementos que faltan por ordenar.

Notemos que cuando se llaman los métodos de ordenamiento, si miramos el vector que se envió como parámetro en el llamado del método esta ordenado (en el main), es decir se modificó la variable, esto se debe a que los vectores son datos que se envían por referencia. Recordemos que:

Paso por valor significa que cuando un argumento se pasa a una función, la función recibe una copia del valor original. Por lo tanto, si la función modifica el parámetro, sólo la copia cambia y el valor original permanece intacto.

P Si la posición j es mayor

que la posición j+1, se

intercambian.

Page 19: Guia e Structur Asded a to s

19

19

Paso por referencia significa que cuando un argumento se pasa a una función, la función recibe la dirección de memoria del valor original, no la copia del valor. Por lo tanto, si la función modifica el parámetro, el valor original en el código que llamó a la función cambia.

Page 20: Guia e Structur Asded a to s

20

20

PRUEBA PASO A PASO DEL METODO DE LA BURBUJA

v aux i j

60 50 40 30

0

3

0

60>50 VERDADERO

50 60 40 30

60

1

60>50 50 40 60 30

60

2

60>30 VERDADERO

50 40 30 60

60

3

//

2

0

50>40 VERDADERO

40 50 30 60

50

1

50>30 VERDADERO

40 30 50 60

50

2

//

1

0

40>30 VERDADERO

30 40 50 60

40

1

//

0

//

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; } } } (Este es el método más rápido)

Page 21: Guia e Structur Asded a to s

21

21

PRUEBA PASO A PASO DEL INSERCION

v

i

j

aux

12 2 5 10

0

1

12>2 v

12 2 12 5 10

0

1

2

12>5 v 2 5 12 10

12

1

2>5 f

0

2

3

12>10 v

12

2 5 10 12

2

5>10 f

1

2>5 f

0

3

TALLER 3: METODOS DE ORDENAMIENTO

1) Investigar el método de inserción, hacer un ejemplo y la prueba paso a

paso para el vector

20 10 4 2

2) Para el siguiente vector:

V={100,99,98,97,96,95,94,93,92,90,89,88,87,86,85,84,83,82,81,80,79,78,77

,76,75,74,73,72,71,70,69,68,67,66,65,64,63,62,61,60,59,58,57,56,55,54,

53,52,51,50,49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,

30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6

,5,4,3,2,1}

Utilizando el computador ordénelo por el método de selección, burbuja e

inserción y compare los tiempos de ejecución, concluir cual es más rápido.

Page 22: Guia e Structur Asded a to s

22

22

4. PILAS

Una pila (stack) es una colección 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 añaden o quitan (borran) solo por su parte superior. Se conocen también 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 dimensión es fija, y mediante listas enlazadas, en cuyo caso se utiliza memoria dinámica y no existe limitación en su tamaño, excepto la memoria del ordenador. Cuando un programa intenta sacar un elemento de una pila vacía, se producirá un error, una excepción, debido a que esa operación 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 diseñan métodos que comprueban si la pila está llena o vacía Las pilas se pueden implementar con arrays o con listas enlazadas, una implementación estática se realiza utilizando un array de tamaño fijo y una implementación dinámica 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 aplicación. Veamos algunas de las aplicaciones más interesantes. Llamadas a métodos.- Cuando se realizan llamadas a métodos, el programa principal debe recordar el lugar donde se hizo la llamada, de modo que pueda retornar allí cuando el método se haya terminado de ejecutar.

Almacenamiento temporal de páginas Web.- Los navegadores de Internet almacenan las direcciones de las páginas 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 después permite al usuario volver a las páginas visitadas previamente usando el botón 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 aplicación es la la evaluación de expresiones algebraicas, como veremos en la siguiente sección.

Page 23: Guia e Structur Asded a to s

23

23

IMPLEMENTACIÓN DE UNA PILA EN JAVA USANDO ARREGLOS

Se ha definido la clase Pila, aquí ya necesitamos los conceptos de programación orientado objetos.

package pila; public class Pila { String vectorPila[]; //vector donde se almacenan los elementos de la pila int elementos;//cantidad de elementos actuales en la pila int tamaño;// tamaño máximo de la pila int cima; //posición 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 tamaño=cantidad; //el tamaño de la pila vectorPila= new String[tamaño]; //recibe el tamaño máximo de la pila cima=-1; // se utiliza el valor -1 para indicar que no hay elementos } public boolean pilallena(){ if(cima==tamaño-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

Page 24: Guia e Structur Asded a to s

24

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 } }

Page 25: Guia e Structur Asded a to s

25

25

UTILIZACIÓN PILAS EN LA EVALUACIÓN DE UNA EXPRESIÓN ALGEBRAICA

Notaciones infija y postfija

Existen básicamente tres formas diferentes de escribir una expresión algebraica. Notación prefija, notación infija y notación postfija, en función de la situación concreta en la que se pongan los operadores respecto de los operandos. Así la expresión algebraica que representa la suma entre un cierto valor A y otro B se podría escribir de la siguiente forma: + A B Notación prefija A + B Notación infija A B + Notación postfija

La notación utilizada habitualmente es la infija. Si observamos un ejemplo adicional de notación infija en la que se utilicen más de un operador podemos observar que para realizar correctamente la operación tenemos que conocer una información adicional acerca de los operadores que aparezcan: La prioridad. Dependiendo de la prioridad del operador, la operación se realizará antes o después, dando como consecuencia un resultado distinto si variamos la prioridad de los operadores. Así, en A + B * C, se realizará primero la multiplicación y a continuación la suma. Si deseamos variar la prioridad, y en consecuencia el orden de evaluación de las operaciones, hay que añadir una información adicional que son los paréntesis. Si en el ejemplo deseamos realizar primero la suma entonces deberemos incluirla entre paréntesis (A + B) * C. Esta inclusión de paréntesis no es necesaria en notación prefija o postfija. En nuestro caso nos centraremos en la notación infija (la notación habitual) y la postfija (más conveniente para uso interno en el ordenador.) Notación infija Notación postfija A + B * C A B C * + (A + B) * C A B + C * La conversión entre la expresión en notación infija y postfija se puede realizar de forma sencilla mediante la utilización de una pila y considerando las prioridades entre los operadores que aparecen en la expresión. Por ejemplo, supongamos que queremos pasar la expresión infija A + B * C - D a postfija. El proceso sería el siguiente: Iniciamos la pila a vacía (pila = <>.) Obtenemos el primer elemento de la expresión (A). Como es un operando, pasa automáticamente a la salida (Salida = “A”.)

Page 26: Guia e Structur Asded a to s

26

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á vacía, 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 más prioritario que el +, lo apilamos, en espera de obtener la otra parte de la operación (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 vacía con lo que no podemos seguir comparando y apilamos el „–‟ (pila = <–>.)

El siguiente elemento de la expresión es la D. Va directamente a la salida

(Salida = “A B C * + D”) Como ya no hay más elementos en la expresión, 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 paréntesis sería similar, pero teniendo en cuenta que un

paréntesis abierto nunca tiene precedencia sobre ningún elemento, de manera que siempre se apila, y el paréntesis cerrado desapila todos los símbolos hasta encontrar el paréntesis abierto, que también se desapila. Los paréntesis, no deben salir ya en la expresión postfija.

Evaluación de una expresión algebraica en notación postfija Una vez transformada la expresión a notación postfija se realizará un algoritmo

que la evalué y dé su resultado. La idea básica del algoritmo es ir apilando los operandos y resultados parciales en una pila e ir desapilándolos a medida que van siendo necesarios (cuando encontremos en la expresión un cierto operador.)

Supongamos la expresión “13 7 3 * + 5 –” (en infija sería “13 + 7 * 3 – 5” que tiene como resultado 29.)

La manera de evaluarla será:

Iniciamos la pila a vacía (pila = <>)

Obtenemos el primer valor. Como es un entero, lo apilamos (pila = <13>) Obtenemos el segundo elemento y el tercero, que también son enteros y los

apilamos (pila = <13, 7, 3>)

Page 27: Guia e Structur Asded a to s

27

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 serán los

dos últimos de la pila, el 21 y el 13, que desapilamos. Los operamos con + y apilamos el resultado (pila = <34>)

Después obtenemos el 5 en la expresión. Lo apilamos (pila = <34, 5>) Finalmente obtenemos de la expresión 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 expresión, el resultado de la operación es

lo que esté en la cima de la pila. Si en algún 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 más de un elemento en la pila también se ha producido un error. En ambos casos la expresión estaba mal escrita. IMPLEMENTACION EN JAVA Para esto utilizaremos la implementación de una pila, donde la pila tiene un vector de caracteres, que serán los elementos de la expresión.

Necesitamos la clase Lectura, con sus métodos, los cuales ya han sido explicados antes. También necesitamos una clase Pila,

public class Pila { char vectorPila[]; int elementos;//cantidad de elementos actuales en la pila int tamaño;// tamaño máximo de la pila int cima; public Pila(int cantidad){ elementos=0; //los elementos que hay actualmente en la pila tamaño=cantidad; vectorPila= new char[tamaño]; //recibe el tamaño máximo de la pila cima=-1; } public boolean pilallena() { //si la pila esta llena devuelve true en caso contrario devuelve false if(cima==tamaño-1){ return(true); } return(false); }

Page 28: Guia e Structur Asded a to s

28

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 método para

convertir de infija apostfija. Lectura.mostrar("La expresion en postfijo es " + expresionPostfija);

Page 29: Guia e Structur Asded a to s

29

29

}*/ } Luego Hacemos otra clase Postfija, con los métodos necesarios para pasar una

expersion de infijo a postfijo import java.util.Scanner; public class Postfija { 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 tamaño 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

expresión

Page 30: Guia e Structur Asded a to s

30

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 tamaño 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

Page 31: Guia e Structur Asded a to s

31

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 método para

convertir de infija apostfija. Lectura.mostrar("La expresion en postfijo es " + expresionPostfija); } }

Page 32: Guia e Structur Asded a to s

32

32

TALLER NOTACIÓN POSTFIJA 1. Analizar y entender el código anterior

2. Dentro de la clase postfija, implementar un método que evalué una

expresión postfija y muestre el resultado

3. Si la expresión infija contiene paréntesis, adecue los métodos para que

convierta la expresión infija con paréntesis en postfija.

Page 33: Guia e Structur Asded a to s

33

33

5. ARRAYS MULTIDIMENSIONALES El uso más importante es para resolver ecuaciones lineales de muchas variables en forma sistemática y compacta. Es posible crear arrays de tantas dimensiones como requieran las aplicaciones 3, 4 o más dimensiones. Si tiene más de una dimensión en consecuencia tiene más de un índice. Los arrays más usuales

2

Filas Los arreglos de dos dimensiones son conocidos también por el nombre de tablas o matrices. Para localizar un elemento será por las coordenadas representadas por el número de la fila y el número de columna (a, b) El número de elementos que tendrá el array será el resultado del producto (m+1)* (n+1) Sintaxis para la declaración 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 [] [];

0

2

1

n

1

Columnas

3

0 1 2

Page 34: Guia e Structur Asded a to s

34

34

Estas declaraciones no reservan memoria para los elementos de la matriz o tabla, realmente son referencias. Para reservar memoria y especificar el número 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 En general NombreMatriz=new double [N][N]; El operador new se puede aplicar a la vez que se hace la declaración. La sintaxis para definir una matriz <tipodatoelemento> <nombrearray>[][]=new <tipodatoElemento> [#filas][#columnas];

Nota: Java requiere que cada dimensión 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 subíndice más próximo al nombre del array es la fila y el otro subíndice, la columna Se pueden tener matrices donde el número 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 número de columnas. t[0]=new double[4]; luego por cada fila, se inicializa el número de columnas. t[1]=new double[3]; quedando la fila 0 con 4 columnas y la fila 1 con 3 columnas.

Page 35: Guia e Structur Asded a to s

35

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 definición de un array bidimensional no es posible omitir el número de filas, así la declaración double vt [][]=new double[][4]; es errónea ya que no se ha especificado el numero de filas y el tamaño queda indeterminado. Matriz.length da el número 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 automáticamente 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 tamaño numfil x numcol for(int fil=0; fil<numfil;fil++)//se va llenando la matriz, ciclo de las filas {

Page 36: Guia e Structur Asded a to s

36

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 nùmero de filas e igual nùmero 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 condición se muestra un mensaje else mostrar("Las matrices deben tener igual número 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 {

Page 37: Guia e Structur Asded a to s

37

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 número 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 multiplicación, en suma } c[fila][columna]=suma; //el resultado de la suma de guarda en la matriz

resultado } } } else { Lectura.mostrar("El número de filas de la primera matriz debe ser igual en

número de columnas de la segunda matriz"); } return c; }

Page 38: Guia e Structur Asded a to s

38

38

public static void main (String []args) //metodo principal { double m[][], n[][],s[][], mult[][]; //se inicializan las matrices llamando al método 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 multiplicación }

Page 39: Guia e Structur Asded a to s

39

39

PRUEBA PASO A PASO DE MULTIPLICACION DE MATRICES A

B

fila columna k suma

C

1 2 3

5 1

38 44

7 4 5

6 8 0

0

0

94 84

7 9

0

1*5

1

1*5+2*6

2

1*5+2*6+3*7

3//

38

1

0

0

1*1

1

1*1+2*8

2

1*5+2*6+3*9

3//

44

0

1

0

0

0

7*5

1

7*5+4*6

2

7*5+4*6+5*7

3//

94

1

0

0

7*1

1

7*1+4*8

2

7*1+4*8+5*9

3//

84

2//

2//

Page 40: Guia e Structur Asded a to s

40

40

TALLER SOBRE MATRICES BIDIMENSIONALES

1. a) Digite y haga la prueba paso a paso al método siguiente, 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) Después de haber realiza el paso anterior concluya que hace este método. 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í:

Parcial1 Parcial2 Parcial3 Talleres Pedro Martínez 4,5 2,0 3,5 4,0 Juan Valdés 2,4 5,0 3,0 3,8 Esteban Corales 2,3 3,3 4,5 3,9 Miguel Pérez 4,1 3,5 4,8 2,5

Diana Ríos 3,2 4,2 4,6 3,5 Laura Gómez 4,3 3,4 2,4 1,6 Implemente un programa en Java que permita calcular:

Page 41: Guia e Structur Asded a to s

41

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 método para saber cuál fue el estudiante que obtuvo la nota más alta

por cada una de las pruebas realizadas.

c) Realice un método 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 método que llene una matriz nXm con

números. Luego debe crear otra matriz de tamaño 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; Además 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: 3 7 2 6 4 6 4 8 2 4 6 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

Page 42: Guia e Structur Asded a to s

42

42

6. LISTAS ENLAZADAS

Las estructuras enlazadas de datos son fundamentales para el desarrollo de software, especialmente en el diseño e implementación 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 dirección de un objeto, que indica donde está almacenado en la memoria. Considere una situación 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 dirección y otra informacion relevante acerca de una persona y además también 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 código } Utilizando exclusivamente esta clase, podemos crear una estructura enlazada. Cada objeto Person contendrá un enlace a un segundo objeto Person. Este segundo objeto también contendrá una referencia a un objeto Person, que a su vez contendrá otra, etc Este tipo de objetos se denomina en ocasiones auto-referencial. Este tipo de relación 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 ordenación lineal de los objetos de la lista. Los objetos almacenados en una lista se denominan, de modo genérico, 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 tamaño fijo, las listas enlazadas no tienen ningún límite 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 dinámica, porque su tamaño crece y se contrae

Page 43: Guia e Structur Asded a to s

43

43

según sea necesario para albergar todos los elementos que haya que almacenar. En java todos los objetos se crean dinámicamente a partir de un área de memoria denominada cúmulo del sistema o almacén 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 posición de la lista. En la Lista enlazada la colección de elementos (denominados nodos) están dispuestos uno a continuación del otro, y cada uno de ellos conectados al siguiente elemento por un enlace o referencia. La primera parte o campo contiene información y es por consiguiente una valor de tipo genérico (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.

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 posición actual se referencia por la referencia actual En caso de que la lista no contenga ningún nodo (está vacía), la cabeza es nulo Operaciones con listas Definición de la clase nodo y referencia a nodo Inicialización o creación 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á vacía.

Nod

o

Nod

o

referen

ciacia Nodo

Page 44: Guia e Structur Asded a to s

44

44

Definición de un nodo Cada nodo es una combinación de dos partes: un tipo de dato (entero, doble, carácter o referencia) y un enlace al siguiente nodo Class nodo { Int dato } La construcción y manipulación de una lista requiere el acceso a los nodos de la lista a través de una o más 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 señala el final de la lista. Se puede utilizar null para cualquier valor de referencia que no apunte a ningún 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 ningún nodo, se utiliza la referencia null como referencia de cabeza y de cola. La lista se denomina lista vacía.

La referencia de cabeza y de cola en una lista enlazada puede ser null lo que indica que la lista esta vacía (no tiene nodos). Este suele ser un método usual para construir una lista. Pasos para la construcción 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 método constructor de lista que inicialice primero a null, lista vacia.

Definir el métodos 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 más entrada para el elemento.

Page 45: Guia e Structur Asded a to s

45

45

Null es una constante especifica de java. Se puede utilizar null para cualquier valor de referencia que no apunte a ningún sitio Insertar un elemento en una lista Varía dependiendo de la posición 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

Después de un elemento especificado Pasos para Insertar un elemento en la cabeza de una lista: Más fácil y más 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 Inserción 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 después de la de la lista.

Hacer que el anterior. enlace apunte al nuevo nodo que se acaba de crear.

Pasos para la búsqueda de un elemento El algoritmo de búsqueda 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 iteración del bucle se mueve la referencia índice de un nodo hacia delante. El bucle termina cuando se alcanza la posición deseada y el índice apunta al nodo El bucle también se puede terminar si el índice apunta a null,(lo que indicara que la posición solicitada era mayor que el numero de nodo de la lista) Pasos para Borrado de un nodo en una lista

Page 46: Guia e Structur Asded a to s

46

46

La operación 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

Búsqueda del nodo que contienen el dato. Se ha de tener la dirección del nodo a eliminar y la dirección 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 dirección del nodo siguiente.

Por último la memoria ocupada por el nodo la libera el sistema al dejar de

estar referenciado

Clasificación 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

Page 47: Guia e Structur Asded a to s

47

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) //método 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 número 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 información del nodo"); insertarCabezaLista(x); } } public void mostrarLista() //método para mostrar el campo información 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 }

Page 48: Guia e Structur Asded a to s

48

48

public void insertarOtraPosicion(int posicion, int dato) //metodo para insertar un

nodo en cualquier // posición de la lista, tiene como datos de entrada la posición en //la que se va insertar el nuevo nodo y la información del nodo { if (numNodo() >= posicion) //se valida que la posición exista { Nodo anterior, nuevo; anterior = primero; //se guarda la referencia del primer nodo de la lista for (int i = 1; i < posición-1; i++)//se recorre la lista hasta llegar a la posición { //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) //método para insertar un nodo en la ultima

posición //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 nùmero de nodos de una lista {

Page 49: Guia e Structur Asded a to s

49

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 aplicación { Lista L = new Lista();// se crea un objeto L de la clase lista int n= Lectura.leerEntero("¿Con cuántos 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 posición 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 posición"); L.insertarUltimo(n); L.mostrarLista(); } }

TALLER LISTAS ENLAZADAS

1. a) Corra el programa anterior paso a paso en java, entiéndalo, analícelo y vea cómo cambian las variables.

b) Mejore el programa para que sea el usuario el que ingrese la información del nodo a insertar o crear.

2. Agregue un método para buscar un nodo en la lista, el método debe tener como dato de entrada la información del nodo y se debe retornar la posición en la que se encuentra el nodo con esta información (asumimos que no hay nodos repetidos).

Page 50: Guia e Structur Asded a to s

50

50

3. Haga un método 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, código y tres notas. Haga métodos para: a) Crear la lista b) Ingresar un nuevo estudiante a la lista c) Dado el código retorne el promedio del estudiante d) Calcule el promedio de todo el curso

5. Realice un método que reciba una lista y pase la información a un vector y retorne el vector

Page 51: Guia e Structur Asded a to s

51

51

TEMAS ADICIONALES

7. LISTAS DOBLEMENTE ENLAZADAS

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 básicas 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 añadir un nuevo nodo se definen varios métodos según la posición donde se inserte el nodo.

La posición de inserción puede ser:

En la cabeza (elemento primero de la lista)

En el final de la lista (elemento ultimo)

Antes de un elemento especificado.

Después de un elemento especificado.

Insertar un elemento en la cabeza de una lista doble

El proceso de inserción 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 atrás del nodo cabeza apunte al nuevo nodo.

El campo atrás del nodo siguiente al nuevo tiene que apuntar a nuevo.

Page 52: Guia e Structur Asded a to s

52

52

La dirección del nodo que esta antes de la posición deseada para el nuevo nodo está en la variable referencia anterior. Hacer que anterior.adelante apunte al nuevo nodo.

El Enlace atrás del nuevo nodo debe apuntar al anterior.

El método insertar después() 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.)

Inserción 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 después de la posición del nuevo nodo (o bien null si no hay ningún nodo después de la nueva posición)

El campo atrás del nodo siguiente al nuevo tiene que apuntar a nuevo.

La dirección del nodo que esta antes de la posición deseada para el nuevo nodo está en la variable referencia anterior. Hacer que anterior.adelante apunte al nuevo nodo.

El enlace atrás del nuevo nodo debe apuntar a anterior.

El método insertar después() 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 automáticamente en el nodo deja de ser referenciado.

Pasos

Page 53: Guia e Structur Asded a to s

53

53

Búsqueda del nodo que contiene el dato. Se ha de tener la dirección del nodo a eliminar y la dirección 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 atrás del nodo siguiente a borrar, tiene que apuntar a la referencia atrás 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 dirección del nodo siguiente.

La memoria ocupada por el nodo es liberada automáticamente.

Existen operaciones de insertar y eliminar borrar en cada dirección..

En algunas aplicaciones podemos desear recorrer la lista hacia adelante y hacia atrás, o dado un elemento, podemos desear conocer rápidamente los elementos anterior y siguiente. En tales situaciones podríamos 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 //definición 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;

Page 54: Guia e Structur Asded a to s

54

54

adelante = null; atras=null; } } public ListaDoble() //Método 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) //método para crear una lista { //recibe como parámetros el número 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 información del

nodo"); x = Integer.parseInt(N); insertarCabezaLista(x); } } public void mostrarLista() //metodo para mostrar el campo información 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 }

Page 55: Guia e Structur Asded a to s

55

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 informaciòn del nodo { if (numNodo() >= posicion) //se valida que la posición 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 posiciòn { //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 nùmero 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;

Page 56: Guia e Structur Asded a to s

56

56

} return cantidadNodos; //se retorna la cantidad de nodos de la lista } } 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(); } } Investigar Borrado de un elemento de una lista doblemente enlazada.

Page 57: Guia e Structur Asded a to s

57

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 varía 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 varía dependiendo de la posición 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

Page 58: Guia e Structur Asded a to s

58

58

} public void CrearLista(int numNodos) //metodo para crear una lista { //recibe como parametros el nùmero 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 {

Page 59: Guia e Structur Asded a to s

59

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(); } }

Page 60: Guia e Structur Asded a to s

60

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 aparición 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 atención clientes en un almacén es un ejemplo típico de cola. La acción de gestión de memoria intermedia (buffering) de trabajos o tareas de una impresora en un distribuidor de impresoras (spooler) es otro ejemplo típico 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 petición de impresión existe otra petición para imprimir 300 paginas, deberá esperar a la impresión de esas 300 páginas antes de que se imprima su página. Las acciones que están permitidas son:

Creación de una cola vacía

Verificación de que una cola está vacía

Añadir un dato al final de una cola.

Eliminación de los datos de la cabeza de la cola IMPLEMENTACION DE LAS COLAS EN JAVA //definición 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

Page 61: Guia e Structur Asded a to s

61

61

informacion = x; enlace = null; } } //**************************************************** //definición 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 nùmero 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; } }

Page 62: Guia e Structur Asded a to s

62

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 nùmero 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 }

Page 63: Guia e Structur Asded a to s

63

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 información de, nombre de la transacción a realizar, y el tiempo de duración de la transacción.

Como se muestra:

Transacción Tiempo

Retiro 4 min

Depósito 2 min

Consulta 3.5 min

Actualización 5 min

Pagos 2 min

Realice métodos 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

Page 64: Guia e Structur Asded a to s

64

64

banco depende de la transacción a realizar y de lo que espere en la cola a antes de ser atendido).

2. Implemente la clase cola, con sus respectivos métodos, pero usando vectores.

Page 65: Guia e Structur Asded a to s

65

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 repetición. Son recursivos aquellos algoritmos que estando encapsulados dentro de una función, son llamados desde ella misma una y otra vez, en contraposición a los algoritmos iterativos, que hacen uso de bucles while, do-while, for, etc. Definición: algo es recursivo si se define en términos de si mismo (cuando para definirse hace mención así mismo). Para que una definición recursiva sea válida, la referencia así misma debe ser relativamente más sencilla que el caso considerado. Ejemplos a) Calcula el factorial de un número

int factorial(int n) {

if(n==0) return 1; else return n*factorial(n-1); } b) Permite obtener la división de un número por el método de restas sucesivas int division (int a, int b)

{ if(b > a) return 0;

else return division(a-b, b) + 1; }

c) Calcula un término de la serie de fibonacci int fibonaci(int n) {

if(n==1 || n==2) return 1; else return fibonaci(n-1)+fibonaci(n-2); }

Page 66: Guia e Structur Asded a to s

66

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 método para saber si un número es primo. Un número no es

primo si tiene algún divisor diferente de 1 y del mismo número. (haga prueba paso a paso)

2) Realice un método recursivo para calcular el elemento mayor de un vector.

Page 67: Guia e Structur Asded a to s

67

67

11. ARBOLES Las estructuras dinámicas lineales de datos tienen grandes ventajas de flexibilidad sobre las representaciones contiguas; sin embargo tienen un punto débil, son listas secuenciales, es decir, están dispuestas de modo que es necesario moverse a través de ellas una posición cada vez. En este capítulo 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 bifurcación. Las principales estructuras de este tipo son:

➢ Árboles: los elementos están organizados como un verdadero árbol.

➢ Grafos: los elementos están organizados como una red de datos.

Árboles En su sentido amplio, un árbol permite almacenar información y organizarla de forma que tengan sucesores o elementos siguientes, como hijos en una forma de las ramas de un árbol.

Árbol genealógico

Aplicaciones En computación: los arboles sintácticos son utilizados para la representación e interpretación de términos de un lenguaje o expresiones aritméticas, pasando por los arboles de activación de procedimientos recursivos, hasta la representación 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 rápida un registro de una tabla a partir de una clave, se utilizaron objetos asociados a las

Page 68: Guia e Structur Asded a to s

68

68

tablas llamados índices, estos índices son arboles binarios de búsqueda almacenados en disco, a partir de una clave indican donde se encuentra el registro correspondiente en la tabla. En teoría de compiladores durante la fase de análisis de código fuente, los analizadores léxicos, sintácticos y semánticos utilizan tablas de símbolos, en donde se almacenan la palabra clave y las palabras reservadas y sus atributos, implementados por lo general como arboles binarios de búsqueda. En síntesis se utiliza un árbol binario de búsqueda cuando se desea almacenar en una estructura de datos cierta información, a la cual luego se desea acceder en forma rápida a partir de una clave. Conceptos

Raíz.-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 raíz.

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 raíz ni hojas).

Altura.- Es la cantidad de nodos que se recorren para llegar

desde la raíz hasta el nodo hoja más alejado de todo el árbol. Grado.- Cantidad máxima de hijos que puede tener cualquier nodo. Nivel.- Numero de generaciones que se está de la raíz. La raíz está en un nivel

= 0. Ruta.- Camino que se recorre para llegar de un nodo a otro. Subárbol.- Cualquier nodo puede ser considerado como la raíz de un subárbol. Peso.- Es la cantidad de nodos hoja del árbol. Visita.- Cuando se accede al dato de un nodo.

Page 69: Guia e Structur Asded a to s

69

69

Recorrido.- Cuando se visita todos los nodos de un árbol en algún 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 operación es básica en el tratamiento de arboles y nos permite, por ejemplo, imprimir toda la información almacenada en el árbol, o bien eliminar toda esta información o, si tenemos un árbol de números, 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 raíz. ● Visitar el subárbol izquierdo. ● Visitar el subárbol 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 raíz. Recorrido preorden

✔ Visitar la raíz

✔ Recorrer el subárbol izquierdo en preorden

✔ Recorrer el subárbol derecho en preorden

Recorrido enorden

✔ Recorrer el subárbol izquierdo en inorden

✔ Visitar la raíz

✔ Recorrer el subárbol derecho en inorden

Recorrido postorden

✔ Recorrer el subárbol izquierdo en postorden

✔ Recorrer el subárbol derecho en postorden

✔ Visitar la raíz

Page 70: Guia e Structur Asded a to s

70

70

Ejemplo: Para el siguiente árbol: Los recorridos son : Inorden: D C E B F A T S U H G K J L Postorden : D E C F B T U S H K L J G A Preorden: A B C D E F G H S T U J K L Árboles Binarios de Búsqueda Son arboles binarios que tienen los datos ordenados de tal manera que todos los datos que están en el subárbol izquierdo son menores que la raíz y todos los datos que están en el subárbol derecho son mayores o iguales que la raíz. (Tomado de: Estructuras de datos en Java, Cristian Denis Mamani Torres) IMPLEMENTACIÓN EN JAVA DE ARBOLES BINARIOS

public class NodoBinario { int informacion; NodoBinario derecho; NodoBinario Izquierdo; public NodoBinario(int dato) //metodo constructor del arbol Binario { informacion=dato; }

A

B

C

D E

F

G

H J

S K

T U

L

Page 71: Guia e Structur Asded a to s

71

71

public void preorden(NodoBinario nodo) { //recorrido en preorden System.out.println(nodo.informacion); //imprime la información de la raíz 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 información 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) //método para insertar un elemento en un árbol de búsqueda { if (nodo==null) { NodoBinario nodoNuevo=new NodoBinario(dato);

Page 72: Guia e Structur Asded a to s

72

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) { //método 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; }

Page 73: Guia e Structur Asded a to s

73

73

public static void main(String[] args) { NodoBinario arbolito; int numNodos= Lectura.leerEntero("digite cantidad de elementos"); int dato= Lectura.leerEntero("digite la información 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);

}

}

Page 74: Guia e Structur Asded a to s

74

74

TALLER ARBOLES 1. a) Inserte los números de la serie en un árbol binario de búsqueda. 50,60, 70, -100,-201,-6,-8,-50,3/4,10/5,21,100,200,3,50,8 b) El árbol resultante recórralo en inorden c) El árbol resultante recórralo en preorden d) El árbol resultante recórralo en postorden 2. En una Universidad tienen un Listado de N estudiantes, los datos del

estudiante están compuestos por:

CODIGO NOMBRE TELEFONO

52 CARLOS 2520555

11 JUANA 552255

22 CARLOS 887788

44 JAIRO 777997

12 FERNANDO 442232

101 PILAR 8799

.. …. ….

.. ….. ….

Se necesita guardar los datos de los estudiantes en un árbol binario, los nodos del árbol deben contemplar el código, nombre y teléfono del estudiante, la llave principal del árbol es el código del estudiante. El programa de estudiantes debe tener un menú con: a) insertar estudiante b) Consultar estudiante por su código c) Lista estudiante(postorden) d) Actualizar nombre e) salir 3. El árbol genealógico de una familia se almacena en un árbol binario, la

información que se almacena para cada miembro de la familia es el nombre

de la persona, año en que nació, año en que murió (para identificar que la

persona vive se le coloca un 0 en el campo año en que murió), numero de

cedula de la persona, color de ojos, estatura, color de cabello.

Realizar un programa que permita

Page 75: Guia e Structur Asded a to s

75

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 características de la persona.

c) Dado el numero de cedula decir a qué edad murió la persona en caso de ya

haber fallecido.

Page 76: Guia e Structur Asded a to s

76

76

TALLER FINAL TEMAS: LISTAS, COLAS, Y ARBOLES BINARIOS. 4. La profesora Marisol Se desea tener la información de los estudiantes del

curso de estructura de datos, cada estudiante tiene su nombre, código, nota

primer parcial, nota segundo parcial, y talleres. La profesora necesita un

programa en java que le permita:

a) Llenar la lista con la información 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) Además si un estudiante cancela el curso este debe ser sacado

automáticamente 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 envían los

documentos para ser impresos cada 10 minutos, y se tiene una cola donde

se va almacenando, la identificación 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 impresión 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

tamaño 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.