Estructura de Datos Java 2008 I

121
UNIVERSIDAD PERUANA LOS ANDES FACULTAD DE INGENIERÍA ALGORITMOS Y ESTRUCTURA DE DATOS I MG. ABRAHAM ESTEBAN GAMARRA MORENO

Transcript of Estructura de Datos Java 2008 I

UNIVERSIDAD PERUANA LOS ANDES

FACULTAD DE INGENIERÍA

ALGORITMOS Y ESTRUCTURA DE DATOS I

MG. ABRAHAM ESTEBAN GAMARRA MORENO

CONTENIDO

UNIDAD ACADEMICA 1.............................................................................................................................. 4

INTRODUCCIÓN A LA PROGRAMACIÓN ORIENTADA A OBJETOS CON JAVA ....................... 4

1.1. EL ENTORNO GENERAL JAVA .......................................................................................................... 4 1.2. EL EDITOR JCREATOR...................................................................................................................... 5

1.2.1. Requerimientos del sistema ....................................................................................................... 5 1.2.2. Instalacion de Jcreator.............................................................................................................. 5

1.3. ESTRUCTURA DE UN PROGRAMA EN JAVA ....................................................................................... 6 1.4. COMO CREAR UN PROGRAMA .......................................................................................................... 7

1.4.1. Creación de una aplicación en el jcreator ................................................................................ 7 1.5. COMENTARIOS ................................................................................................................................ 9 1.6. MÉTODO MAIN ...............................................................................................................................10 1.7. IDENTIFICADORES ..........................................................................................................................11 1.8. VARIABLES ....................................................................................................................................11 1.9. TIPOS DE DATOS .............................................................................................................................12

1.9.1. Tipos de datos primitivos..........................................................................................................12 1.9.2. Tipos de datos referencia .........................................................................................................13

1.10. LITERALES .....................................................................................................................................13 1.11. OPERADORES .................................................................................................................................16

1.11.1. Operadores Aritméticos .......................................................................................................16 1.11.2. Operadores Relacionales.....................................................................................................17 1.11.3. Operadores Condicionales ..................................................................................................17 1.11.4. Operadores Lógicos y de Corrimiento (shift) ......................................................................17 1.11.5. Operadores de Asignación...................................................................................................18 1.11.6. Otros Operadores ................................................................................................................18

1.12. ENTRADA ESTANDAR .....................................................................................................................20 1.13. EXPRESIONES, SENTENCIAS Y BLOQUES ........................................................................................25 1.14. SENTENCIAS DE CONTROL DE FLUJO..............................................................................................25

1.14.1. Loop .....................................................................................................................................26 1.14.2. Toma de decisiones ..............................................................................................................29

1.15. MANEJO DE EXCEPCIONES ..............................................................................................................31 1.15.1. Procesamiento de excepciones ............................................................................................33 1.15.2. La cláusula finally ...............................................................................................................34 1.15.3. Excepciones más comunes ...................................................................................................35 1.15.4. Las cláusulas throw y throws...............................................................................................36 1.15.5. Bifurcación ..........................................................................................................................40

1.16. EL OPERADOR CONDICIONAL..........................................................................................................42 1.17. MÉTODOS.......................................................................................................................................43 1.18. SOBRECARGA DE LOS NOMBRES DE LOS MÉTODOS .........................................................................44 1.19. CLASES DE ALMACENAMIENTO ......................................................................................................45 RESUMEN .....................................................................................................................................................45 BIBLIOGRAFÍA RECOMENDADA ....................................................................................................................46 NEXO............................................................................................................................................................46 ACTIVIDAD...................................................................................................................................................46 AUTO EVALUACIÓN FORMATIVA ..................................................................................................................48

UNIDAD ACADEMICA 2.............................................................................................................................51

OBJETOS Y CLASES ...................................................................................................................................51

2.1. ¿QUÉ ES LA PROGRAMACIÓN ORIENTADA A OBJETOS? ...................................................................51 2.2. UN EJEMPLO SENCILLO...................................................................................................................53 2.3. MÉTODOS BÁSICOS ........................................................................................................................55

2.3.1. Constructores ...........................................................................................................................55

ii ESTRUCTURA DE DATOS EN JAVA

2.3.2. Métodos modificadores y de acceso.........................................................................................56 2.3.3. Salida y toString.......................................................................................................................57 2.3.4. Equals.......................................................................................................................................57 2.3.5. Métodos static ..........................................................................................................................59 2.3.6. Método main.............................................................................................................................59

RESUMEN .....................................................................................................................................................59 BIBLIOGRAFÍA RECOMENDADA....................................................................................................................60 NEXO ...........................................................................................................................................................60 ACTIVIDAD ..................................................................................................................................................60 AUTO EVALUACIÓN FORMATIVA ..................................................................................................................60

UNIDAD ACADEMICA 3 ............................................................................................................................63

ARREGLOS UNIDIMENSIONALES: VECTORES.................................................................................63

3.1. OPERACIONES BÁSICAS CON UN ARREGLO UNIDIMENSIONAL.........................................................64 3.2. IMPLEMENTACIÓN DE LAS OPERACIONES DE UN ARREGLO UNIDIMENSIONAL ................................64 3.3. OPERACIONES BÁSICAS CON UN ARREGLO UNIDIMENSIONAL ORDENADO ......................................66 3.4. IMPLEMENTACIÓN DE LAS OPERACIONES DE UN ARREGLO UNIDIMENSIONAL ORDENADO..............66 RESUMEN .....................................................................................................................................................69 BIBLIOGRAFÍA RECOMENDADA....................................................................................................................69 NEXO ...........................................................................................................................................................69 ACTIVIDAD ..................................................................................................................................................69 AUTO EVALUACIÓN FORMATIVA ..................................................................................................................70

UNIDAD ACADEMICA 4 ............................................................................................................................73

ARREGLOS BIDIMENSIONALES: TABLAS/ MATRICES...................................................................73

4.1. OPERACIONES BÁSICAS CON UN ARREGLO BIDIMENSIONAL ...........................................................74 4.2. IMPLEMENTACIÓN DE LAS OPERACIONES DE UN ARREGLO BIDIMENSIONAL ...................................74 RESUMEN .....................................................................................................................................................77 BIBLIOGRAFÍA RECOMENDADA....................................................................................................................78 NEXO ...........................................................................................................................................................78 ACTIVIDAD ..................................................................................................................................................78 AUTO EVALUACIÓN FORMATIVA ..................................................................................................................78

UNIDAD ACADEMICA 5 ............................................................................................................................81

TIPOS DE DATOS ABSTRACTOS (TDA) ................................................................................................81

5.1. TIPO DE DATOS ..............................................................................................................................81 5.2. TIPOS DE DATOS ABSTRACTOS (TDA)............................................................................................81 5.3. IMPLEMENTACIÓN DE TIPOS DE DATOS ABSTRACTOS .....................................................................82 RESUMEN .....................................................................................................................................................89 BIBLIOGRAFÍA RECOMENDADA....................................................................................................................89 NEXO ...........................................................................................................................................................89 ACTIVIDAD ..................................................................................................................................................89 AUTO EVALUACIÓN FORMATIVA ..................................................................................................................89

UNIDAD ACADEMICA 6 ............................................................................................................................93

RECURSION..................................................................................................................................................93

6.1. ALGORITMOS RECURSIVOS ............................................................................................................93 RESUMEN .....................................................................................................................................................97 BIBLIOGRAFÍA RECOMENDADA....................................................................................................................97 NEXO ...........................................................................................................................................................98 ACTIVIDAD ..................................................................................................................................................98 AUTO EVALUACIÓN FORMATIVA ..................................................................................................................98

Mg. Abraham Gamarra Moreno iii

UNIDAD ACADEMICA 7...........................................................................................................................101

ORDENAMIENTO ......................................................................................................................................101

7.1. ORDENAMIENTO...........................................................................................................................101 7.2. CLASES DE ORDENAMIENTO .........................................................................................................101 7.3. MÉTODOS DIRECTOS DE ORDENAMIENTO .....................................................................................102

7.3.1. Ordenamiento por intercambio directo. Método de la burbuja..............................................102 7.4. MÉTODOS AVANZADOS DE ORDENAMIENTO:................................................................................105

7.4.1. Ordemamiento con el método de shell....................................................................................105 7.4.2. Ordenamiento rápido (quick sort) ..........................................................................................107

7.5. PROGRAMA CON LOS ALGORITMOS DE ORDENAMIENTO ...............................................................109 RESUMEN ...................................................................................................................................................111 BIBLIOGRAFÍA RECOMENDADA ..................................................................................................................111 NEXO..........................................................................................................................................................112 ACTIVIDAD.................................................................................................................................................112 AUTO EVALUACIÓN FORMATIVA ................................................................................................................112

UNIDAD ACADEMICA 8...........................................................................................................................113

BÚSQUEDA..................................................................................................................................................113

8.1. BÚSQUEDA ...................................................................................................................................113 8.1.1. Definiciones ............................................................................................................................113 8.1.2. Clases de búsqueda ................................................................................................................114

8.2. BÚSQUEDA SECUENCIAL ..............................................................................................................114 8.3. BÚSQUEDA BINARIA .....................................................................................................................115 8.4. PROGRAMA CON LOS ALGORITMOS DE BÚSQUEDA .......................................................................116 8.5. EFICIENCIA DE LOS ALGORITMOS DE ORDENAMIENTO Y BÚSQUEDA.............................................117 RESUMEN ...................................................................................................................................................118 BIBLIOGRAFÍA RECOMENDADA ..................................................................................................................118 ACTIVIDAD.................................................................................................................................................119 AUTO EVALUACIÓN FORMATIVA ................................................................................................................119

4 ESTRUCTURA DE DATOS EN JAVA

UNIDAD ACADEMICA 1

INTRODUCCIÓN A LA PROGRAMACIÓN ORIENTADA A OBJETOS CON JAVA

1.1. EL ENTORNO GENERAL JAVA

¿Cómo se escriben, se compilan y ejecutan los programas Java? La respuesta, por supuesto, depende de la plataforma particular sobre la que se encuentra instalado el compilador de Java.

El código fuente de Java se guarda en ficheros con nombres acabados en el sufijo .Java. El compilador local, javac, compila el programa y genera ficheros .class, que contienen código-j. El código-j es un lenguaje portable intermedio que es interpretado por el intérprete de Java.java.

Para los programas de Java, la entrada puede provenir de muchas fuentes:

• El teclado, cuya entrada se denomina entrada estándar.

• Parámetros adicionales al invocar el programa ejecutable: argumentos de la línea de comandos.

Mg. Abraham Gamarra Moreno 5

• Una componente GUI.

• Un fichero.

Muchos sistemas operativos proporcionan una forma alternativa conocida como redireccionamiento de fichero, mediante la cual, el sistema operativo toma la entrada de (o envía la salida a) un fichero, de forma transparente al programa en ejecución. En Unix, por ejemplo, el comando:

java Programa < ficheroentrada > ficherosalida

dispone automáticamente las cosas para que cualquier lectura del teclado sea redirigida para obtenerla de ficheroentrada y cualquier escritura en la pantalla sea redirigida sobre ficherosalida.

1.2. EL EDITOR JCREATOR

JCreator Pro Release V2.00 build 004 (32 bit) for Win 95/98/NT/2000.

Jcreator es un poderoso Entorno de Desarrollo Integrado (Integrated Development Environment: IDE), para Java, que proporciona al usuario un amplio rango de funcionalidades tales como: Administración de proyectos, plantillas, navegador para clases, elaboración de código, interfaz de depuración, resaltado de sintaxis, asistente y una interfaz de usuario configurable.

JCreator esta escrito enteramente en C++, el cual lo hace a este rápido y eficiente comparado con los IDEs basados en Java.

1.2.1. REQUERIMIENTOS DEL SISTEMA

Windows 95/98/NT4/2000 or higher.

Internet Explorer 4 o superior (opcional)

1.2.2. INSTALACION DE JCREATOR

Descomprimir el fichero de instalación JCREATORPRO2\JCREATORSETUP.EXE en un

6 ESTRUCTURA DE DATOS EN JAVA

directorio temporal y correr el ejecutable. El asistente de instalación realizará el resto.

1.3. ESTRUCTURA DE UN PROGRAMA EN JAVA

Un programa es un conjunto de instrucciones, escritas en un lenguaje de programación, que sirven para resolver un tipo determinado de problema o para cumplir metas bien definidas. Un programa de Java contiene una o más clases. Éstas describen objetos, entidades de software que interactúan al momento de la ejecución para realizar tareas específicas. Los objetos se utilizan para modelar entidades reales o lógicas en el dominio del problema. Un aspecto importante de la POO es identificar estas entidades y sus interacciones en el proceso de solución. Por lo general una clase contiene miembros que pueden ser campos y métodos. Los primeros son variables que almacenan datos y objetos. Los segundos son funciones que codifican operaciones. Es así que ellos reciben argumentos, realizan cálculos predefinidos y devuelven resultados.

En Java, las clases contienen a todos los métodos, no se les permite no estar anexados y eso también sucede con las funciones. Un mensaje enviado a un objeto activa (o invoca) un método de ese objeto, le pasa argumentos y obtiene el valor que devuelve. Los objetos interactúan al enviar y recibir mensajes.

Una clase proporciona el nombre bajo el que se reúnen los miembros para formar una unidad de cálculo que puede operar con independencia de otras partes del programa. Con objetos, puede construirse un programa grande con muchas unidades pequeñas, independientes y que interactúan entre si. La orientación a objetos puede reducir significativamente la complejidad del programa, aumentar su flexibilidad y mejorar las posibilidades de volver a usarlo. Un programa de Java puede definir sus propias clases, utilizarlas ya integradas y emplear las que han sido creadas por otros.

Mg. Abraham Gamarra Moreno 7

Las clases pueden estar organizadas en paquetes con un nombre. Cada paquete puede contener uno o más archivos de código fuente.

La estructura de un programa se puede representar de la siguiente manera:

Class . . . { < campos o atributos > . . < métodos > }

Se debe tener un método main para que se pueda ejecutar la aplicación

1.4. COMO CREAR UN PROGRAMA

Un programa puede ser una aplicación o un applet. Crear con algún editor de textos (Block de notas o el Edit) el programa.

1.4.1. CREACIÓN DE UNA APLICACIÓN EN EL JCREATOR

Para mostrar un ejemplo, utilizaremos el IDE JCreator para crear nuestras aplicaciones.

Escriba el siguiente código en el JCreator:

class programa1 { /* * Punto de entrada a la aplicación. * * args: matriz de parámetros pasados a la * aplicación mediante la línea de órdenes. * Puede estar vacía. */ public static void main (String[] args) { System.out.println("Mi primer programa!!!"); } }

Para crear el programa elija File (Menú principal), New, elija la ficha Files, Java File, ingrese el nombre del archivo en Filename, elija la carpeta donde se alojará el archivo en Location y presione el clic en Aceptar, tal como se muestra en la figura 1.1.

8 ESTRUCTURA DE DATOS EN JAVA

Figura 1.1

El código en el IDE JCreator queda como se muestra en la figura 1.2.

Figura 1.2

Para compilar el programa presione clic

sobre el icono , luego presione

para ejecutar el programa.

Mg. Abraham Gamarra Moreno 9

Usted ahora tiene el siguiente resultado de la figura 1.3.

Figura 1.3

El programa anterior muestra en pantalla el mensaje Mi primer programa!!!, el cual se imprime debido al uso de la clase System. Nótese que el nombre de la clase debe ser igual al del archivo con la

extensión .java.

1.5. COMENTARIOS

En Java hay tres tipos de comentarios:

// Comentarios de una sola línea

/*

Comentarios de una o más líneas

*/

/** Comentario de documentación, que pueden ser de una o más líneas y pueden contener palabras claves que comienzan con @ para destacar cierta información, por ejemplo: @version 1.0 (06/11/2000) @author Gustavo A. Scrigna @author Lisandro A. Palermo */

Los dos primeros tipos de comentarios son los más conocidos, ya que son los heredados del lenguaje C y C++, y se utilizan del mismo modo. Los comentarios de documentación indican que ese

10 ESTRUCTURA DE DATOS EN JAVA

comentario ha de ser colocado en la documentación que se genera automáticamente cuando se utiliza la herramienta del JDK, javadoc. Dichos comentarios sirven como descripción del elemento declarado permitiendo generar una documentación de las clases que se van construyendo al mismo tiempo que se genera el código de la aplicación. En este tipo de comentario para documentación, se permite la introducción de algunas palabras claves, que harán que la información aparezca destacada, permitiendo la incorporación de información útil, que luego se podrá ver en formato HTML sobre cualquier navegador. Aunque posteriormente se verán en detalle algunas de las palabras claves que soporta javadoc, hay que tener en cuenta a la hora de utilizar este tipo de comentarios, que javadoc solamente procesarán la documentación para miembros public y protected, los comentarios para miembros private y package serán ignorados.

Algunas de las palabras claves más utilizadas son:

• @author: Información del autor

• @param: Parámetro y descripción

• @exception: Nombre de la clase y descripción

• @version: Información de la versión

• @see: Referencia a otra clase

• @return: Significado del valor de retorno

• @deprecated: Aviso de clase obsoleta

1.6. MÉTODO main

Un programs Java está formado por una colección de clases que interactán entre sí, las cuales contienen metodos. El equivalente en Java a una función o procedimiento es el metodo estático. Cuando se ejecuta un program se llama al metodo estatico especial main. Se puede llamar al metódo estatico main con argumentos en la línea de comandos. Es obligatorio que los tipos de los parámetros de main y el tipo del resultado (void) sean:

Mg. Abraham Gamarra Moreno 11

public static void main (String[] args)

Salida por pantalla

El programa inicial tiene una única instrucción, println es el principal mecanismo de salida en Java. En dicha linea se coloca una cadena en la salida estdándar system.out aplicando un método println. Se usa la misma sintaxis para producir la salida de cualquier entidad, ya sea un entero, un número en coma flotante, una cadena o un valor de cualquier otro tipo.

1.7. IDENTIFICADORES

Los identificadores se utilizan como nombres de clase, método y variable. Un identificador puede ser cualquier sentencia descriptiva de letras en mayúscula o minúscula, números y los caracteres subrayado (_) y signo de dólar (^). No se deban comenzar por número. Java diferencia entre mayúsculas/minúsculas, lo que significa que VALOR es un identificador diferente de Valor.

1.8. VARIABLES

Una variable es un ítem de datos nombrado por un identificador. Debemos explícitamente suministrar un nombre y un tipo para cada variable que quisiéramos usar en nuestro programa. El nombre de la variable debe ser un identificador válido --una serie de caracteres Unicode que comienzan con una letra. Utilizamos el nombre de la variable para referirnos al dato que la variable contiene. El tipo de la variable determina el conjunto de valores que se pueden almacenar en esa variable y el tipo de operaciones que se pueden realizar con ella. Para dar a una variable un tipo y un nombre, escribimos una declaración de variable, que en general se verá de la siguiente forma:

tipo nombre;

o también:

tipo nombre1 [ = valor][,nombre2 [= valor] ...];

12 ESTRUCTURA DE DATOS EN JAVA

en este último caso mostramos como podemos inicializar una variable en el momento de su declaración. Además del nombre y tipo que explícitamente le damos a la variable, una variable tiene un alcance (scope). La sección de código donde puede ser utilizado el nombre de la variable es el alcance de la variable. El alcance de la variable es determinado implícitamente por la ubicación de la declaración de la variable, es decir, donde aparece la declaración en relación a otros elementos del código.

1.9. TIPOS DE DATOS

Cada variable debe tener un tipo de datos. El lenguaje de programación Java tiene dos categorías de tipos de datos: primitivo y referencia.

1.9.1. TIPOS DE DATOS PRIMITIVOS

Una variable de tipo primitivo contiene un único valor de tamaño y formato apropiados para su tipo: un número, un carácter, un valor booleano. Por ejemplo, el valor de un entero (int) es de 32 bits de datos en un formato conocido como complemento a 2, el valor de un carácter (char) es de 16 bits de datos formateados como un carácter Unicode, etc.

En esta tabla listamos todos los tipos de datos primitivos soportados por Java, junto con sus tamaños y formatos, y una breve descripción de cada uno de ellos.

Tipo

Descripcion

boolean Tiene dos valores true o false.

char

Caracteres Unicode de 16 bits. Los caracteres alfa-numéricos son los mismos que los ASCII con el bit alto puesto a 0. El intervalo de valores va desde 0 hasta 65535 (valores de 16-bits sin signo).

Mg. Abraham Gamarra Moreno 13

byte Tamaño 8 bits. El intervalo de valores va desde -27 hasta 27 -1 (-128 a 127)

short Tamaño 16 bits. El intervalo de valores va desde -215 hasta 215-1 (-32768 a 32767)

int Tamaño 32 bits. El intervalo de valores va desde -231 hasta 231-1 (-2147483648 a 2147483647)

long Tamaño 64 bits. El intervalo de valores va desde -263 hasta 263-1 (-9223372036854775808 a 9223372036854775807)

float Tamaño 32 bits. Números en coma flotante de simple precisión. Estándar IEEE 754-1985 (de 1.40239846e–45f a 3.40282347e+38f)

double Tamaño 64 bits. Números en coma flotante de doble precisión. Estándar IEEE 754-1985. (de 4.94065645841246544e–324d a 1.7976931348623157e+308d.)

Los tipos básicos que utilizaremos en la mayor parte de los programas serán boolean, int y double.

1.9.2. TIPOS DE DATOS REFERENCIA

Los arreglos, las clases y las interfaces son tipos referencia. El valor de una variable de tipo referencia, en contraste con la de tipo primitivo, es una referencia a (la dirección de) el valor o conjunto de valores representados por la variable.

Una referencia es denominada un puntero, o una dirección de memoria en otros lenguajes. El lenguaje de programación Java no soporta el uso explícito de direcciones como en otros lenguajes. Utilizamos en cambio el nombre de la variable:

1.10. LITERALES

Un valor constante en Java se crea utilizando una representación literal de él. Java utiliza cinco tipos de elementos: enteros, reales en coma flotante, booleanos, caracteres y cadenas, que se

Nombre del objeto

Referencia Un objeto o un array

14 ESTRUCTURA DE DATOS EN JAVA

pueden poner en cualquier lugar del código fuente de Java. Cada uno de estos literales tiene un tipo correspondiente asociado con él.

A continuación se tiene el ejemplo de valores literales y sus tipos de datos:

Literal Tipo de Datos

178 Int

8864L Long

37.266 Double

37.266D double

87.363F float

26.77e3 double

'c' char

true boolean

false boolean

"Hola" String

Ejemplo Uno

Veamos como se declaran e inicializan variables de tipos de datos primitivos.

public class TiposPrimitivos { public static void main(String[] args) { /* Tipos de datos enteros */ byte b; b = 127; short s; s = 32767; int i = 2147483647; // 'L' para especificarlo como long long l = 9223372036854775807L; /* Tipos de datos de punto flotante */ // 'F' para especificarlo como float float f = 3.40282347e+38F; double d=1.797693134862310e+308; /* Otros tipos de datos */ char c = 'c'; boolean bo = true; // Salida por pantalla de los tipos de // datos primitivos System.out.println("Tipos de datos enteros (limites superiores):");

Mg. Abraham Gamarra Moreno 15

System.out.println("byte = " + b); System.out.println("short = " + s); System.out.println("int = " + i); System.out.println("long = " + l); System.out.println("\nTipos de datos de punto flotante (limites superiores):"); System.out.println("float = " + f); System.out.println("double = " + d); System.out.println("\nOtros Tipos de datos:"); System.out.println("char = " + c); System.out.println("boolean = " + bo); } }

Ejemplo Dos

Veamos como se declaran e inicializan variables de tipos de datos referencia.

import java.util.*; public class TiposReferencia { public static void main(String[] args) { // Declaración de una variable 'str' // de tipo Referencia a un objeto de la clase // String String str; // Creación del objeto String y asignación de //su referencia a la variable 'str' str = new String("Curso de Java"); // otra forma de crear un objeto String por // medio de un String literal String strLiteral = "Cadena Literal !"; // Declaración de la variable 'hoy' de tipo // referencia a un objeto de la clase Date Date hoy; // Creación del objeto Date hoy = new Date(); // Arreglos, son tipos Referencia ! // Declaración de un arreglo de int int[] ai; // Creación de un arreglo de 5 int ai = new int[5]; // Asignación de valores a los elementos // del arreglo ai[0] = 1; ai[1] = 2; ai[2] = 3; ai[3] = 4; ai[4] = 5; // Muestro los datos a pantalla System.out.println("str = " + str); System.out.println("strLiteral = " + strLiteral); System.out.println("hoy = " + hoy); System.out.print("ai[] = [" + ai[0] + ", " + ai[1] + ", " + ai[2] + ", " + ai[3] + ", " + ai[4] + "]"); } }

16 ESTRUCTURA DE DATOS EN JAVA

1.11. OPERADORES

Un operador realiza una función en uno, dos o tres operandos. Un operador que requiere un solo operando se denomina operador unario. Por ejemplo, ++ es un operador unario que incrementa el valor de su operando en 1. Un operador que requiere de dos operandos es un operador binario. Por ejemplo, = es un operador binario que asigna el valor del operando de la derecha al operando de la izquierda. Y, finalmente, el operador ternario el que requiere tres operandos. El lenguaje de programación Java tiene un operador ternario, ?:, que es un atajo de la sentencia if-else.

Los operadores unarios soportan tanto la notación prefija como postfija. La notación prefija significa que el operador aparece antes que el operando: operador op //notación prefija

La notación postfija significa que el operador aparece después que el operando:

op operador //notación postfija

Todos los operadores binarios utilizan notación infija, que significa que el operador aparece entre sus operandos:

op1 operador op2 //notación infija

El operador ternario es también infijo; cada componente del operador aparece entre operandos:

op1 ? op2 : op3 //notación infija

Además de realizar la operación, el operador devuelve un valor. El valor de retorno y su tipo depende del operador y del tipo de sus operandos. Por ejemplo, el operador aritmético, que realiza operaciones aritméticas básicas como suma y resta, devuelve números (el resultado de la operación aritmética). El tipo de dato devuelto por un operador aritmético depende del tipo de sus operandos: Si sumamos dos enteros, obtenemos un entero. Una operación se dice que se evalúa a su resultado.

1.11.1. OPERADORES ARITMÉTICOS

Operador Uso Descripción

Mg. Abraham Gamarra Moreno 17

+ op1 + op2 Suma op1 y op2

- op1 - op2 Resta op2 de op1

* op1 * op2 Multiplica op1 por op2

/ op1 / op2 Divide op1 por op2

% op1 % op2

Calcula el resto de la división de op1 por op2

++ op++ Incrementa op en 1; se evalúa el valor de op antes de ser incrementado

++ ++op Incrementa op en 1; se evalúa el valor de op después de ser incrementado

-- op-- Decrementa op en 1; se evalúa el valor de op antes de ser decrementado

-- --op Decrementa op en 1; se evalúa el valor de op después de ser decrementado

1.11.2. OPERADORES RELACIONALES

Operador Uso Devuelve true si > op1 > op2 op1 es mayor que op2

>= op1 >= Op2 op1 es mayor o igual que op2

< op1 < op2 op1 es menor que op2

<= op1 <= op2 op1 es menor o igual que op2

== op1 == op2 op1 y op2 son iguales

!= op1 != op2 op1 y op2 son distintos

1.11.3. OPERADORES CONDICIONALES

Operador Uso Devuelve true si && op1 &&

op2 op1 y op2 son ambos true, evalúa condicionalmente op2

|| op1 || op2 Cualquiera de op1 u op2 es true, evalúa condicionalmente op2

! ! op op es false

& op1 & op2 op1 y op2 son ambos true, siempre evalúa op1 y op2

| op1 | op2 Cualquiera de op1 u op2 es true, siempre evalúa op1 y op2

^ op1 ^ op2 Si op1 y op2 son diferentes. Esto es si uno u otro de los operandos es true, pero no ambos.

1.11.4. OPERADORES LÓGICOS Y DE CORRIMIENTO (SHIFT)

Operador Uso Operación & op1 & op2 "AND" de Bits

| op1 | op2 "OR" de Bits

^ op1 ^ op2 "XOR" de Bits

~ ~op2 Complemento Binario

>> op1 >> op2 Corrimiento de bits de op1 hacia la derecha por la distancia de op2

<< op1 << op2 Corrimiento de bits de op1 hacia la izquierda por la distancia de op2

>>> op1 >>> op2

Corrimiento de bits de op1 hacia la derecha por la distancia de op2 (sin signo)

18 ESTRUCTURA DE DATOS EN JAVA

1.11.5. OPERADORES DE ASIGNACIÓN

Operador Uso Equivalente a += op1 += op2 op1 = op1 + op2

-= op1 -= op2 op1 = op1 - op2

*= op1 *= op2 op1 = op1 * op2

/= op1 /= op2 op1 = op1 / op2

%= op1 %= op2 op1 = op1 % op2

&= op1 &= op2 op1 = op1 & op2

|= op1 |= op2 op1 = op1 | op2

^= op1 ^= op2 op1 = op1 ^ op2

<<= op1 <<= op2 op1 = op1 << op2

>>= op1 >>= op2 op1 = op1 >> op2

>>>= op1 >>>= op2 op1 = op1 >>> op2

1.11.6. OTROS OPERADORES

Operador Uso Descripción ? op1 ? op2 : op3 Si op1 es verdadero, devuelve op2. De lo contrario, devuelve op3.

tipo [] Declara un array de tamaño desconocido, que contiene elementos

tipo.

tipo[ op1 ] Crea un array de op1 elementos. Debe ser declarado con el

operador new. []

op1[ op2 ] Accede al elemento de la posición op2 dentro del array op1. El

índice comienza en 0 y se extiende hasta la longitud del array menos uno.

. op1.op2 Es una referencia al miembro op2 de op1.

() op1(parámetros) Declara o llama al método denominado op1 con los parámetros

especificados. La lista de parámetros puede ser una lista vacía. La lista esta separada por comas.

(tipo) (tipo) op1 Convierte (cast) op1 a tipo. Una excepción será lanzada si el tipo

de op1 es incompatible con tipo.

New new op1 Crea un nuevo objeto o array. op1 puede ser una llamada a un

constructor o la especificación de un array.

instanceof op1 instanceof

op2 Devuelve verdadero si op1 es una instancia de op2

Ejemplo Tres

Como se utilizan los operadores unarios, en su forma pre y postfija.

public class Operadores1 { public static void main(String[] args) { int a=2,b,c,d; b=2; c=d=2; // Prueba de operadores ++ y -- en sus formas // post y prefija System.out.println("a = " + (a++));

Mg. Abraham Gamarra Moreno 19

System.out.println("a = " + a); System.out.println("b = " + ++b); System.out.println("b = " + b); System.out.println("c = " + c--); System.out.println("c = " + c); System.out.println("d = " + (--d)); System.out.println("d = " + d); } }

Ejemplo Cuatro

Como se utilizan los operadores de asignación.

public class Operadores2 { public static void main(String[] args) { // Operadores de asignación double e, f, g, h; e = f = g = h = 100; e += 20; // e = e + 20 f *= e; // f = f * e g -= f; // g = g - f h /= 15; // h = h / 15 System.out.println("e = " + e); System.out.println("f = " + f); System.out.println("g = " + g); System.out.println("h = " + h); } }

Ejemplo Cinco

Como se utilizan los operadores relacionales.

public class Operadores3 { public static void main(String[] args) { // Operadores Relacionales boolean a,b; a = true; b = !a; System.out.println("a = " + a); System.out.println("b = " + b); System.out.println("a AND a = " + (a && a)); System.out.println("a AND b = " + (a && b)); System.out.println("b AND a = " + (b && a)); System.out.println("b AND b = " + (b && b)); System.out.println("a OR a = " + (a || a)); System.out.println("a OR b = " + (a || b)); System.out.println("b OR a = " + (b || a)); System.out.println("b OR b = " + (b || b)); } }

Ejemplo Seis

20 ESTRUCTURA DE DATOS EN JAVA

Como funciona el operador ternario.

public class Operadores4 { public static void main(String[] args) { // Otros Operadores int a,b; a = 4; b = 5; System.out.println("a = " + a); System.out.println("b = " + b); System.out.println("El mayor entre a y b es = " + (a > b ? a : b)); System.out.println("El menor entre a y b es = " + (a < b ? a : b)); } }

1.12. ENTRADA ESTANDAR

Para resumir la entrada estandar se va a construir la clase leer que nos permitira leer datos desde el teclado.

import java.io.*; public class Leer{ public static String dato(){ String sdato = ""; try{ // Definir un flujo de caracteres de entrada: flujoE InputStreamReader isr = new InputStreamReader(System.in); BufferedReader flujoE= new BufferedReader(isr); // Leer. La entrada finaliza al pulsar la tecla Entrar sdato = flujoE.readLine(); } catch(IOException e){ System.err.println("Error: " + e.getMessage()); } return sdato; // devolver el dato tecleado } public static short datoShort(){ try{ return Short.parseShort(dato()); } catch(NumberFormatException e){ // valor más pequeño return Short.MIN_VALUE; } } public static int datoInt(){ try{ return Integer.parseInt(dato()); } catch(NumberFormatException e){ // valor más pequeño return Integer.MIN_VALUE; } } public static long datoLong(){ try{ return Long.parseLong(dato()); }

Mg. Abraham Gamarra Moreno 21

catch(NumberFormatException e){ // valor más pequeño return Long.MIN_VALUE; } } public static float datoFloat(){ try{ Float f = new Float(dato()); return f.floatValue(); } catch(NumberFormatException e){ // No es un Número; valor float. return Float.NaN; } } public static double datoDouble(){ try{ Double d = new Double(dato()); return d.doubleValue(); } catch(NumberFormatException e){ // No es un Número; valor double. return Double.NaN; } } public static String datoString(){ return dato(); } public static char datoChar(){ int c=0; try{ InputStreamReader isr = new InputStreamReader(System.in); BufferedReader flujoE= new BufferedReader(isr); c=flujoE.read(); char car; car=(char) c; return car; } catch(IOException e){ return '\0'; } } }

Para tener acceso a la clase Leer.class copielo a una carpeta como indica la figura 1.4.

22 ESTRUCTURA DE DATOS EN JAVA

Figura 1.4

Para realizar modificaciones de CLASSPATH en el JCreator, que nos permita definir la ubicación de nuestra clase, debemos hacerlo utilizando Configure, Options, JDK Profiles, Edit, Add; tal como se muestra en la figura 1.5.

Mg. Abraham Gamarra Moreno 23

Figura 1.5.

Adicione el path como se muestra en la figura 1.6.

24 ESTRUCTURA DE DATOS EN JAVA

Figura 1.6

El siguiente programa nos permite probar la clase leer:

// Utiliza la clase Leer que debe de estar almacenada // en la misma carpeta public class LeerDatos{ public static void main(String[] args){ short dato_short = 0; int dato_int = 0; long dato_long = 0; float dato_float = 0; double dato_double = 0; String cadena=""; char car; System.out.print("Dato short: "); dato_short = Leer.datoShort(); System.out.print("Dato int: "); dato_int = Leer.datoInt(); System.out.print("Dato long: "); dato_long = Leer.datoLong(); System.out.print("Dato float: "); dato_float = Leer.datoFloat(); System.out.print("Dato double: "); dato_double = Leer.datoDouble(); System.out.print("Cadena :"); cadena=Leer.datoString(); System.out.print("Caracter :"); car=Leer.datoChar(); System.out.println(dato_short);

Mg. Abraham Gamarra Moreno 25

System.out.println(dato_int); System.out.println(dato_long); System.out.println(dato_float); System.out.println(dato_double); System.out.println(cadena); System.out.println(car); } }

1.13. EXPRESIONES, SENTENCIAS Y BLOQUES

Los programas en Java, al igual que en C y C++, se componen de sentencias, que a su vez están compuestas en base a expresiones. Una expresión esta formada por una combinación de operadores y operandos que se evalúan para obtener un resultado particular. Los operandos pueden ser variables, constantes o llamadas a métodos. Una llamada a un método evalúa el valor devuelto por el método y el tipo de una llamada a un método es el tipo devuelto por ese método.

Una expresión es una serie de variables, operadores y llamadas a métodos (construidas de acuerdo a la sintaxis del lenguaje) que se evalúan a un único valor. Podemos escribir expresiones compuestas combinando expresiones simples. Cuando escribimos expresiones compuestas, debemos ser explícitos e indicar con paréntesis que operadores se deben evaluar primero. Si elegimos no utilizar paréntesis, luego la plataforma Java evaluará la expresión compuesta en el orden dictado por la precedencia de los operadores.

Una sentencia forma una unidad completa de ejecución y es terminada con un punto y coma (;). Hay tres tipos de sentencias: sentencias de expresión, sentencias de declaración, y sentencias de control de flujo. Podemos agrupar cero o más sentencias juntas en un bloque con llaves ( { y } ). Aunque no se requiere, recomendamos utilizar bloques con las sentencias de control de flujo, aún cuando haya una sola sentencia en el bloque.

1.14. SENTENCIAS DE CONTROL DE FLUJO

Las sentencias de control de flujo se usan para condicionar la ejecución del código, para hacer loops sobre un conjunto de líneas de código o para saltar de una parte del programa a otra. A

26 ESTRUCTURA DE DATOS EN JAVA

continuación veremos como controlar el flujo del programa con estas sentencias.

A estas sentencias las podríamos agrupar en 4 grupos, loop, toma de decisiones, manejo de

excepción y bifurcación, los cuales veremos en más detalle a continuación:

1.14.1. LOOP

while

Sirve para ejecutar continuamente un bloque de código, mientras que una condición permanezca en true.

Veamos la sintaxis general:

while (expresión booleana) { sentencia 1; sentencia 2; ... sentencia 3; }

o bien:

while (expresión booleana) sentencia;

while no ejecutará el código (ni siquiera una vez) a menos que la expresión evalúe true.

Ejemplo while

Programa que determina si un número natural es primo. Un numero primo si sólo es divisible por la unidad y por si mismo.

// Utiliza la clase Leer que debe de estar almacenada // en la misma carpeta public class DemoWhile{ public static void main(String[] args){ int n,d; System.out.print("Numero natural : "); n=Leer.datoInt(); d=2; while(d*d<n && n%d!=0) d++; if (d*d>n) System.out.println("Es primo"); else System.out.println("No es primo"); }

Mg. Abraham Gamarra Moreno 27

}

do-while

La sintaxis es la siguiente:

do { sentencia 1; sentencia 2; sentencia 3; ... sentencia n; } while (expresión booleana);

o bien:

do sentencia 1; while (expresión booleana);

La diferencia con while es que en do-while se asegura la ejecución de las sentencias al menos 1 vez, ya que primero se ejecuta y luego se evalúa.

Ejemplo do-while

Programa que calcula el Máximo Común Divisor (MCD) de dos números naturales utilizando el algoritmo de Euclides.

El algoritmo consiste: los números a dividir se ubican en la parte central, el cociente se ubica en la parte superior y el residuo en la parte inferior. Se dividen los dos números si el residuo es diferente de cero, el divisor pasa a ser el dividendo y el residuo viene a ser el divisor, se continúa con este proceso hasta que el residuo sea cero. El máximo común divisor es igual al último divisor, por ejemplo:

MCD(70,12)=2 MCD(60,36)=12 5 1 5 1 1 2 70 12 10 60 36 24 12 0 10 2 0 14 12 0

// Utiliza la clase Leer que debe de estar almacenada // en la misma carpeta public class DemoDoWhile{ public static void main(String[] args){ int n1,n2,t,mcd,res; System.out.print("Primer número : "); n1=Leer.datoInt();

28 ESTRUCTURA DE DATOS EN JAVA

System.out.print("Segundo número : "); n2=Leer.datoInt(); do{ res=n1%n2; n1=n2; n2=res; }while(n2!=0); mcd=n1; System.out.println("El MCD es : "+mcd); } }

for

El for en Java, al igual que en C++, es muy potente. Sirve para iterar a través de un rango de valores. Veamos su sintaxis:

for (inicialización; expresión booleana; incremento) { sentencia 1; sentencia 2; sentencia 3; ... sentencia n; }

o bien:

for (inicialización; expresión booleana; incremento) sentencia;

Cualquiera de las expresiones inicialización, expresión booleana o incremento puede estar vacía. Antes de cada iteración se evalúa la expresión booleana. Hasta que la expresión booleana evalúe false se van a ejecutar las sentencias, cuando esto ocurra, es decir se evalúe false, el flujo de ejecución del programa pasará a la primer línea posterior al for. Un caso particular podría ser el siguiente:

for (;;);

el cual es perfectamente válido, y no es ni más ni menos que un loop infinito.

Ejemplo for

Programa que calcula la suma de los n términos de:

...4

1

3

1

2

11 +−+−=s

// Utiliza la clase Leer que debe de estar almacenada

Mg. Abraham Gamarra Moreno 29

// en la misma carpeta public class DemoFor{ public static void main(String[] args){ int n,i; double s,t; System.out.print("Cantidad de términos: "); n=Leer.datoInt(); s=0; t=-1.0; for(i=1;i<=n;i++){ t=-t; s=s+t/i; } System.out.println("Suma ="+s); } }

1.14.2. TOMA DE DECISIONES

if

Nos permite ejecutar una parte u otra del código dependiendo de la evaluación.

No vamos a explicar como funciona if, ya que a esta altura todos debemos conocerlo. Pero si vamos a resaltar algunas cosas específicas del if de Java.

La sintaxis es la siguiente:

if (expresión booleana) { // bloque por true sentencia 1; sentencia 2; ... sentencia n; } else { // bloque por false sentencia 1; sentencia 2; ... sentencia n; }

expresión es una evaluación lógica, es decir, debe evaluar true o false. Por true se ejecuta el primer bloque de sentencias y por false el segundo.

Una forma abreviada es cuando tenemos una sola sentencia, caso en el cual no hace falta poner las llaves.

if (expresión booleana) sentencia_para_true; else sentencia_para_false;

30 ESTRUCTURA DE DATOS EN JAVA

Ejemplo if

La comisión sobre las ventas totales de un empleado es como sigue:

• Si ventas < 50.00 unidades monetarias (u.m.) entonces no hay comisión.

• Si esta entre 50.00 u.m. y 500.00 u.m. incluidos, entonces la comisión es 10% de las ventas.

• Si las Ventas > 500.00, entonces la comisión es 50.00 u.m. mas 8% de las ventas superiores a 500.00.

El programa calcula la comisión cuando se ingresa las ventas.

// Utiliza la clase Leer que debe de estar almacenada // en la misma carpeta public class DemoIf{ public static void main(String[] args){ double ventas,comision=0; System.out.print("Ventas totales : "); ventas=Leer.datoDouble(); if(ventas<50) comision=0; else if(ventas>=50&&ventas<=500) comision=ventas*0.10; else if(ventas>500) comision=50+(ventas-500)*0.08; System.out.println("Comisión: "+comision); } }

switch

Veamos el funcionamiento con un ejemplo:

switch (mes) { case 1: System.out.println("Enero"); break; case 2: System.out.println("Febrero"); break; case 3: System.out.println("Marzo"); break; case 4: System.out.println("Abril"); break; case 5: System.out.println("Mayo"); break; case 6: System.out.println("Junio"); break; case 7: System.out.println("Julio"); break; case 8: System.out.println("Agosto"); break; case 9: System.out.println("Septiembre"); break; case 10: System.out.println("Octubre"); break; case 11: System.out.println("Noviembre"); break; case 12: System.out.println("Diciembre"); break; default: System.out.println("Error en el mes") break; }

Lo que hace es evaluar mes y en función de su valor ejecuta las sentencias correspondiente. Cabe destacar la

Mg. Abraham Gamarra Moreno 31

presencia de break, la cual es una palabra clave que interrumpe el flujo de ejecución enviándolo a la primer línea a continuación del cierre del switch. Podemos observar también la palabra clave default en último lugar, la cual se ejecutará si mes no ha coincidido con ningún valor explicitado. default no es obligatorio y por lo tanto puede no estar.

Ejemplo switch

Programa que calcula el monto a pagar por el consumo de energía eléctrica, si durante su ejecución se ingresa el consumo y el tipo de tarifa. Las tarifas son:

TIPO DE TARIFA

COSTO (U.M./Kw-h)

1 2.30 2 8.25 3 6.42 4 5.80 5 9.65

// Utiliza la clase Leer que debe de estar almacenada // en la misma carpeta public class DemoSwitch{ public static void main(String[] args){ double consumo,tarifa,monto; int tipo; System.out.print("Consumo: "); consumo=Leer.datoDouble(); System.out.print("Tipo de tarifa(1 al 5): "); tipo=Leer.datoInt(); switch(tipo){ case 1:tarifa=2.30;break; case 2:tarifa=8.25;break; case 3:tarifa=6.42;break; case 4:tarifa=5.80;break; case 5:tarifa=9.65;break; default:tarifa=0; } if(tarifa!=0){ monto=consumo*tarifa; System.out.println("\nMonto a pagar: "+monto); } else System.out.println("\nTarifa incorrecta"); } }

1.15. MANEJO DE EXCEPCIONES

Las excepciones son elementos que almacenan información y transmiten fuera de la secuencia

32 ESTRUCTURA DE DATOS EN JAVA

normal de retorno de datos. Las excepciones se propagan hacia atrás a través de la secuencia habitual de llamada, hasta que sean recogidas por alguna rutina. Se emplean para detectar hechos excepcionales, como por ejemplo errores.

El lenguaje de programación Java provee un mecanismo conocido como excepciones para manejar errores. Cuando ocurre un error, el programa lanza una excepción. Esto significa que el flujo normal del programa es interrumpido y el runtime busca un manejador de excepciones, es decir, trata de encontrar un bloque de código que pueda manejar ese tipo particular de error. El manejador de excepciones puede intentar recuperar el error, o bien puede producir una salida elegante del programa.

Hay 3 sentencias que juegan un papel preponderante en el manejo de excepciones: try, catch y finally.

try

Identifica un bloque de código dentro del cual puede lanzarse una excepción.

catch

Se debe asociar con la sentencia try e identifica un bloque de código que maneja un tipo particular de excepción. Estas sentencias se ejecutan si ocurre un tipo particular de excepción dentro del código try.

finally

También se debe asociar con la sentencia try e identifica un bloque de código que se ejecuta independientemente si ocurre o no una excepción.

La sintaxis es la siguiente:

try { sentencia 1; sentencia 2; ... sentencia n;

Mg. Abraham Gamarra Moreno 33

} catch (tipoDeExcepcion nombre) { sentencia 1; sentencia 2; ... sentencia n; } finally { sentencia 1; sentencia 2; ... sentencia n; }

1.15.1. PROCESAMIENTO DE EXCEPCIONES

El siguiente programa muestra el empleo de excepciones.

import java.io.*; public class DividePorDos{ public static void main(String []args){ BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); int x; String unaLinea; System.out.println("Introduce un entero: "); try{ unaLinea=in.readLine(); x=Integer.parseInt(unaLinea); System.out.println("La mitad de x es "+(x/2)); } catch(Exception e){ System.out.println(e); } } }

El código que eventualmente puede generar una excepción se encierra en el bloque try. El bloque try se extiende

try{ unaLinea=in.readLine(); x=Integer.parseInt(unaLinea); System.out.println("La mitad de x es "+(x/2)); }

Inmediatamente después del bloque try se encuentran los manejadores de excepciones. Está parte del código se ejecuta solo si se produce una excepción. En el momento en el que ésta se lanza, el bloque try del que procede se considera finalizado. Cada bloque catch se prueba en orden hasta encontrar un manejador de excepciones adecuado. Como Exception incluye los tipos de todas las excepciones de nuestro interés, recoge cualquier excepción generada por el bloque try. Más concretamente, estas excepciones son del

34 ESTRUCTURA DE DATOS EN JAVA

tipo IOException, generadas por readLine si se produce algún error inesperado de lectura, y del tipo NumberFormatException, generadas por parseInt, si unaLinea no es convertible a entero.

Una vez capturada la excepción correspondiente se ejecuta el código del bloque match, en nuestro caso

catch(Exception e){ System.out.println(e); }

Entonces este bloque y el que contiene la combinación try/catch se consideran terminados. En el ejemplo se imprime un mensaje significativo para el objeto e de tipo Exception. Como alternativa, podría realizarse un procesamiento adicional o bien darse mensajes de error mas detallados.

1.15.2. LA CLÁUSULA FINALLY

Algunos objetos construidos en el bloque try deberán ser eliminados antes de concluir la ejecución del mismo. Por ejemplo, los ficheros que se abren en el bloque try necesitan cerrarse antes de abandonar dicho bloque. Uno de los problemas que aparece es que si se lanza una excepción dentro de un bloque try, la eliminación podría no producirse al causar la excepción la salida inmediata del bloque try. Aunque la eliminación de los objetos puede realizarse justo después del último bloque catch, esto sólo es efectivo si la excepción es recogida por alguna cláusula match, y esto es difícil de garantizar con seguridad.

La cláusula finally que sigue al ultimo bloque catch (o al bloque try si no hav ningún bloque catch) se emplea en estas situaciones. La cláusula finally consiste en la palabra clave finally seguida del bloque finally. Existen tres situaciones básicas:

Mg. Abraham Gamarra Moreno 35

Si el bloque try se ejecuta sin generarse excepciones, el control pasa al bloque finally. Esto es así aún cuando el bloque try termine antes de alcanzar su última instrucción, mediante un return, break o continue.

Si se produce una excepción dentro del bloque try que no es recogida, el control pasa al bloque finally. Tras ejecutar éste la excepción se propaga.

Si se produce una excepción dentro del bloque try que es recogida en un catch posterior, el control pasa al bloque catch correspondiente. Tras ejecutarse, se procesa el bloque finally.

1.15.3. EXCEPCIONES MÁS COMUNES

En Java existen muchos tipos de excepciones estándar. Las excepciones run-time (o en tiempo de ejecución) incluyen eventos como la división-por-cero de enteros y los accesos i1egales a vectores. Como estos eventos pueden producirse casi en cualquier punto, sería agotador incorporar constantemente manejadores de excepciones para ellos. En cualquier caso, si se especifica para ellos un bloque match, estas excepciones se comportan como cualquier otra. Pero si no se especifica ninguno, se lanza una excepción estándar que se propaga de la forma usual, pudiendo sobrepasar main. En este caso el programa termina de forma anómala, presentando un mensaje de error. En la Tabla 1.1 se muestran algunas de las excepciones run-time mas usuales.

Excepciones Run-time Significado ArithmeticException Desbordamiento o división entera por cero.

NumberFormatException Conversión ilegal de un String a un tipo

numérico.

IndexOutofBoundsException Acceso a un elemento inexistente de un

vector o de un string.

NegativeArraySizeException Intento de creación de un vector de longitud

negativa.

NullPointerException Intento de uso de una referencia nula. SecurityException Violación de la seguridad en tiempo de

36 ESTRUCTURA DE DATOS EN JAVA

ejecución.

Tabla 1.1. Excepciones run-time más comunes.

La mayoría de las excepciones son del tipo standard checked. Si un método puede lanzar una de estas excepciones directa o indirectamente, el programador debe definir el bloque catch adecuado para ella o indicar de forma explícita que la excepción va a propagarse, incluyendo para esto ultimo la cláusula throws en la declaración del método. Observe que antes o después deben definirse manejadores para ellas, ya que el método main no debería tener cláusula throws. En la Tabla 1.2 se recogen algunas de las excepciones más usuales de este tipo.

Excepciones Checked Significado

java.io.EOFException Final de fichero antes de lo

esperado.

java.io.FileNotFoundException Fichero inexistente.

java.io.IOException Incluye muchas excepciones de

E/S.

InterruptedException Lanzada por el método

Thread.sleep.

Tabla 1.2. Excepciones standard checked-time más comunes.

Los errores son excepciones, pero no se ajustan al tipo Exception. Típicamente son irrecuperables. El error mas común es OutOfMemoryError. Para capturar cualquier excepción posible debe recogerse un objeto Throwable.

1.15.4. LAS CLÁUSULAS THROW Y THROWS

El programador puede lanzar una excepci6n empleando la cláusula throw. Por ejemplo, podemos lanzar una excepci6n de tipo Exception mediante

throw new Exception( "Malas Noticias" );

Mg. Abraham Gamarra Moreno 37

Normalmente, no se lanzan excepciones del tipo exception, sino que se lanzan excepciones definidas por el usuario.

Las excepciones del tipo standard checked deben ser recogidas o propagadas explícitamente hacia la rutina que ha realizado la llamada, pero en algunas ocasiones, y como último recurso, deben procesarse en main. Para hacer esto último, el método que no desea capturar la excepción debe indicar, a través de la cláusula throws, que excepciones se van a propagar. La cláusula throws se escribe al final de la cabecera del método. El siguiente programa muestra un método que propaga las excepciones del tipo IOException que encuentra, éstas deben ser recogidas en main (ya que no incluiremos una cláusula throws en main).

import java.io.*; public class DemoThrow{ public static void procesaFichero(String Fichero) throws IOException { // Esta implementación omitida propaga cualquier // IOException hacia la rutina invocadora } public static void main(String []args){ for(int i=0;i<args.length;i++){ try{ procesaFichero(args[i]); } catch(IOException e){ System.out.println(e); } } } }

Ejemplo 1

class Exc0{ public static void main(String args[]) { int d = 0; int a = 42 / d; } }

Al ejecutar esta rutina, el intérprete desplegará el siguiente error:

java.lang.ArithmeticException: / by zero at Exc0.main(Exc0.java:4)

38 ESTRUCTURA DE DATOS EN JAVA

Note que se indica el nombre de la clase, el nombre del método, el nombre del archivo y el número de línea donde ocurrió la excepción

Ejemplo 2

Una modificación del ejemplo anterior sería la siguiente:

class Exc1{ static void rutina() { int d = 0; int a = 10 / d; } public static void main(String args[]) { Exc1.rutina(); } }

El resultado sería el siguiente:

Exception in thread "main" java.lang.ArithmeticException: / by zero at Exc1.rutina(Exc1.java:4) at Exc1.main(Exc1.java:7)

El intérprete de Java muestra el trazado de la pila, desde la rutina donde ocurrió la excepción hasta el último objeto en la jerarquía de llamadas.

Ejemplo 3

Por supuesto es mejor manejar uno mismo las excepciones, y no dejárselas al intérprete de Java. Para proteger un bloque de código frente a todas las posibles excepciones, se usa la instrucción try. A continuación del bloque try se incluye una cláusula catch, que especifica el tipo de excepción que se desea capturar. Ejemplo:

class Exc2 { public static void main(String args[]) { try { int d = 0; int a = 42 / d; } catch (ArithmeticException e) { System.out.println("Division por cero"); } } }

Ejemplo 4

Mg. Abraham Gamarra Moreno 39

La instrucción throw (lanzar) se usa para enviar explícitamente una excepción a la clase que llamó a la rutina. El siguiente ejemplo demuestra el lanzamiento de una excepción creada en la rutina. Esta excepción es capturada en la rutina que la crea, y además es pasada al gestor de excepciones más externo (al siguiente en la jerarquía).

class ThrowDemo { static void demoproc() { try { throw new NullPointerException("demo"); } catch(NullPointerException e) { System.out.println("Capturada dentro de demoproc"); throw e; } } public static void main(String args[]){ try { demoproc(); } catch (NullPointerException e) { System.out.println("Capturada en el main: " + e); } } }

Al ejecutar la rutina se obtiene el siguiente resultado:

Capturada dentro de demoproc Capturada en el main: java.lang.NullPointerException: demo

Ejemplo 5

La cláusula finally se ejecuta justo antes del final del método, aunque no se ejecute ningún catch. Ejemplo:

class FinallyDemo { static void procA() { try { System.out.println("Dentro de procA"); throw new RuntimeException("demo"); } finally { System.out.println("finally de procA"); } } static void procB() { try { System.out.println("Dentro de procB"); return; } finally { System.out.println("finally de procB"); } }

40 ESTRUCTURA DE DATOS EN JAVA

public static void main(String args[]) { try { procA(); } catch (Exception e) { procB(); } } }

El ejemplo anterior produce el siguiente resultado:

Dentro de procA finally de procA Dentro de procB finally de procB

1.15.5. BIFURCACIÓN

El lenguaje de programación Java provee 3 sentencias de bifurcación: break, continue y return.

break

La sentencia break tiene 2 formas: sin etiqueta y etiquetado.

Hemos visto la versión sin etiquetar usada en switch. Como pudimos ver en ese momento, break interrumpe el flujo normal y transfiere el control a la primer línea después del comando switch. La sentencia break también se puede usar para salir de un for, while o do-while, transfiriendo siempre el control a la primer línea posterior a cada uno de los bucles.

La versión etiquetada es similar a la anterior, con la diferencia que se usa para salir de un bucle que tiene una etiqueta. Veamos un ejemplo:

Ejemplo: break etiquetado - Código parcial

... busqueda: for (; i < maximo; i++) { for (; j < maximo; j++) { ... ... break busqueda; } }

Mg. Abraham Gamarra Moreno 41

En el ejemplo, cuando se llegue al punto de la ejecución de

break busqueda;

se saldrá del for externo, donde figura la etiqueta busqueda:.

Ejemplo break

Programa que lee un número de punto flotante y lo imprime redondeado a dos decimales. El usuario decide si quiere continuar.

// Utiliza la clase Leer que debe de estar almacenada // en la misma carpeta public class DemoBreak{ public static void main(String[] args){ double num; char resp; while(true){ System.out.print("Numero : "); num=Leer.datoDouble(); num=((int)(num*100+0.5))/100.0; System.out.println("Numero Redondeado: "+num); System.out.print("\nContinuar (S/N)?\n"); resp=Leer.datoChar(); if ((resp=='N') || (resp=='n')) break; } } }

continue

La sentencia continue se usa para saltar la iteración actual de un for, while o do-while. Al igual que break tiene 2 formas: sin etiquetar y etiquetada; y el funcionamiento es análogo al de break.

Ejemplo continue

Programa que imprime los números pares comprendidos de 1 a 20.

public class DemoContinue{ public static void main(String[] args){ int i; for( i=1 ; i <=20 ; i++ ){ if (i % 2==1) continue;

42 ESTRUCTURA DE DATOS EN JAVA

System.out.print(i+"\t"); } } }

return

La última sentencia de bifurcación en Java es return. return se usa para salir del método actual. El flujo de ejecución retorna a la sentencia que sigue a la llamada original del método. La sentencia return también tiene 2 formas: una devuelve un valor y la otra no devuelve nada. Para devolver un valor, simplemente se coloca el valor de retorno (o una expresión que calcule el valor) a continuación de return. El tipo de dato del valor de retorno debe coincidir con el tipo de dato en la declaración del método.

Veamos como sería el código:

return valor;

o simplemente,

return;

1.16. EL OPERADOR CONDICIONAL

El operador condicional ? : se usa como abreviatura de una instrucción if-else simple. La forma general es:

exprTest ? exprSi : exprNo

Primero se evalúa exprTest, seguida por exprSi o exprNo, produciendo asi el resultado de la expresión completa. Si exprTest se evalúa a true entonces se evalúa exprsi: en caso contrario, se evalúa exprNo. La precedencia del operador condicional se encuentra justo por encima de la de los operadores de asignación. Esto nos evita tener que usar parentesis cuando asignamos a una variable el resultado de un operador condicional. Como ejemplo, para asignar el mínimo entre x e y a la variable valmin hariamos to siguiente:

valmin = x <= y ? x : y;

Mg. Abraham Gamarra Moreno 43

1.17. MÉTODOS

Lo que en otros lenguajes se conoce como función, o procedimiento, en Java se llama merodo.Algunos conceptos basicos para escribir funciones del estilo de C, como main, de forma que podamos escribir algunos programas simples.

La cabecera de un método consiste en un nombre, una lista (posiblemente vacía) de parámetros y el tipo del resultado. El código que realmente implementa el metodo, a veces llamado el cuerpo del metodo, es formalmente un bloque. La declaración de un método esta formada por una cabecera y un cuerpo. En el programa siguiente se muestra un ejemplo de un metodo y una rutina mainque lo invoca.

Colocando delante de un metodo las palabras public static, podemos imitar una función global del estilo de C. Aunque en algunos ejemplos es una tecnica útil, no debe sobreutilizarse.

El nombre del método es un identificador. La lista de parámetros consiste en cero o más parámetros formales, cada uno de ellos con un tipo. Cuando se llama a un metodo, los argumentos reales se pasan a los parametros formales usando asignación normal. Esto significa que los tipos primitivos se pasan siempre usando paso de parametros por valor. Los argumentos reales no pueden ser modificados por la funcion. Como en la mayoría de los lenguajes de programación modernos, las declaraciones de los métodos pueden aparecer en cualquier orden.

public class MinTest{ public static void main (String []Args){ int a=3; int b=7; System.out.println(min(a,b)); } //Definición de la función public static int min(int x,int y){ return x<y?x:y; } }

La instrucción return se usa para devolver un valor al punto de llamada. Si el tipo del resultado es void, entonces no se devuelve ningún valor, escribiendose return ; en tal caso.

44 ESTRUCTURA DE DATOS EN JAVA

1.18. SOBRECARGA DE LOS NOMBRES DE LOS MÉTODOS

Supongamos que necesitamos escribir una rutina que devuelva el máximo de tres valores de tipo int. Una cabecera razonable para el metodo seria

int max(int a, int b, int c )

En algunos lenguajes, esto puede ser inaceptable si max se ha declarado previamente. Por ejemplo podriamos tener también

int max(int a, int b)

Java permite la sobrecarga de nombres de los metodos. Esto significa que varios métodos pueden tener el mismo nombre y declararse en el mismo ambito de la clase mientras sus signaturas (es decir, los tipos de la lista de parámetros) sean diferentes. Cuando se produce una llamada a max, el compilador puede deducir a cual es el metodo que se pretende aplicar en base a la lista de argumentos reales. Dos signaturas pueden tener el mismo número de parámetros, siempre que el tipo de algunos de ellos sea distinto.

Observe que el tipo del resultado no esta incluido en la signatura. Esto significa que no esta permitido tener dos metodos dentro del mismo ambito de clase cuya unica diferencia sea el tipo del resultado. Metodos que se encuentren en ambitos de clase distimos pueden tener el mismo nombre, signatura e incluso tipo del resultado.

public class Mintest1{ public static void main (String []Args){ int a=3; int b=7; int c=10; System.out.println("El menor de "+a+","+b+" es: "); System.out.println(min(a,b)); System.out.println("El menor de "+a+","+b+","+c+" es: "); System.out.println(min(a,b,c)); } //Definición de la función public static int min(int x,int y){ return x<y?x:y; } public static int min(int x,int y,int z){

Mg. Abraham Gamarra Moreno 45

int menor; menor=x<y?x:y; menor=menor>z?z:menor; return menor; } }

1.19. CLASES DE ALMACENAMIENTO

Las entidades declaradas dentro del cuerpo de un metodo son variables locales y solamente se puede acceder a ellas a traves de su nombre, dentro del cuerpo del método. Dichas entidades se crean cuando se ejecuta el cuerpo del metodo y desaparecen cuando el cuerpo del metodo termina.

Una variable declarada fuera del cuerpo de un metodo es global a la clase. Es similar a las variables globales en otros lenguajes, si se usa la palabra static (lo cual es bastante probable si se desea permitir el acceso a la entidad por parte de métodos estáticos). Si se usan las palabras static y final, se trata de constantes simbólicas globales. Por ejemplo,

static final double PI =3.141592653589?932;

Observe la convención habitual de usar nombres en mayúsculas para los nombres de constantes simbólicas. Si el nombre esta formado por varias palabras se separa mediante el carácter de subrayado, como en MAX_INT_VALUE.

Resumen

Los programas en el Lenguaje de Programación Java utilizan class para su implementación y el método principal es el main.

La lectura de datos desde el teclado se realiza con el método readLine() y la impresión en pantalla lo realizamos con el método print() y println().

Para evitar la caida de los programas en tiempo de ejecución se implementa el manejo de las excepciones.

El flujo de control en Java utiliza las sentencias if…else, switch, while, do…while, for, break.

46 ESTRUCTURA DE DATOS EN JAVA

Bibliografía Recomendada

• Allen Weiss, Mark (2000). “Estructuras de Datos en Java, compatible con Java 2”. Editorial Addison Wesley. España.

• Ceballos Sierra, Javier (2000). “JAVA 2 Curso de Programación”. Editorial Alfaomega-Rama. México.

• Deitel y Deitel (1998). “Como programar en Java”. Editorial Prentice Hall. México.

• December, John (1996). “Introducción a Java”. Editorial Prentice Hall. México.

• Decker, Rick y Hirshfield, Stuart (2001). “Introducción a la Programación en Java”. Segunda edición. México.

• Froufe Quintas, Agustín (2000). “JAVA 2 Manual de usuario y tutorial”. Editorial Alfaomega-Rama. México.

• J. Koosis, Donald y S. Koosis, David (1996). “Java Programming For Dummies”. Editorial IDG Books. USA.

• S. Wang, Paul (2000). “Java con programación orientada a objetos y aplicaciones en la World Wide Web”. Editorial Thomson. México.

Nexo

La siguiente unidad académica amplia las nociones del uso de clases y objetos.

Actividad

Pruebe los programas de los ejemplos siguientes, realice un análisis de su implementación y modifiquelo teniendo en cuenta las siguientes recomendaciones:

• Cambie la implementación que utiliza la sentencia if por la sentencia switch y viceversa.

• Cambie la implementación que utiliza la sentencia while por la sentencia for o por la sentencia do..while.

Ejemplo 1

Programa que permite calcular el factorial de un número natural. El número es leído de la línea de órdenes.

Mg. Abraham Gamarra Moreno 47

class Factorial{ public static int Factorial(int n){ int ans=1; while(n>1){ ans*=n; n--; } return ans; } public static void main(String[] args){ if(args.length!=1) System.err.println("Use factorial1 n"); //Convierte la cadena a int int n=Integer.valueOf(args[0]).intValue(); if (n>=10 && n<13) System.out.println("Factorial("+n+")="+ Factorial(n)); else System.err.println("Factorial("+n+")?"); } }

Ejemplo 2

Programa que determina el promedio de 11 y 20.

class Average{ public static void main(String[] args){ int i=11,j=20; double a=(i+j)/2; System.out.println("i es "+i+" y j es "+j); System.out.println("El Promedio es: "+a); } }

Ejemplo 3

Programa que permite calcular el factorial del de 0 al 12.

class Factorial{ public static int Factorial(int n){ int ans=1; while(n>1){ ans*=n; n--; } return ans; } public static void main(String[] args){ int n=0; while (n<13){ System.out.print(n+"! = "); System.out.println(Factorial(n)); n++; } } }

Ejemplo 3

48 ESTRUCTURA DE DATOS EN JAVA

Programa que resuelve una ecuación de segundo grado de la forma:

02=++ cbxax

La discriminante es:

acbd 42−=

Si la discriminante es mayor o igual que cero (d>=0) tiene raíces reales, caso contrario tiene raíces complejas. Las raíces se obtienen con:

a

acbbx

2

42−±−

=

// La clase Leer debe estar en alguna carpeta de las especificadas // por la variable de entorno CLASSPATH. public class CEcuacion{ public static void main(String[] args){ double a, b, c, d, x1, x2; System.out.print("Coeficiente a: "); a = Leer.datoDouble(); System.out.print("Coeficiente b: "); b = Leer.datoDouble(); System.out.print("Coeficiente c: "); c = Leer.datoDouble(); d = b * b - 4 * a * c; if (d < 0){ // Si d es menor que 0 System.out.println("Las raíces son complejas."); return; // salir } // Si d es mayor o igual que 0 System.out.println("Las raíces reales son:"); d = Math.sqrt(d); x1 = (-b + d) / (2 * a); x2 = (-b - d) / (2 * a); System.out.println("x1 = " + x1 + ", x2 = " + x2); } }

Auto evaluación formativa

Escriba programas que encuentren la solución a los siguientes problemas:

PROBLEMA UNO

Escriba un método void octalDisplay(n) que despliegue el entero n en notación octal.

PROBLEMA DOS

Escriba un metodo que dado un número entero, muestre su representación en números romanos. En particular, si el dato es 1998, la salida seria MCMLXLVIII.

Mg. Abraham Gamarra Moreno 49

PROBLEMA TRES

Realizar un programa que determine los divisores de un número.

PROBLEMA CUATRO

Escribir un programa que permita leer un número en base “m” y lo convierta a otro número en base “n”. El programa debe imprimir el número en base “n”. Los valores de m y n son menores que 10.

Mg. Abraham Gamarra Moreno 51

UNIDAD ACADEMICA 2

OBJETOS Y CLASES

2.1. ¿QUÉ ES LA PROGRAMACIÓN ORIENTADA A OBJETOS?

El corazón de la programación orientada a objetos es el objeto. Un objeto es un tipo de datos con estructura y estado. Cada objeto tiene definida. Operaciones que pueden acceder a ese estado o manipularlo. En Java los objetos se distinguen de los valores de los tipos primitivos, pero ésta es más bien una característica de Java que de la programación orientada a objetos. Además de ejecutar acciones generales, podemos hacer lo siguiente:

• Crear nuevos objetos, posiblemente con un valor inicial.

• Copiar o comprobar la igualdad.

• Realizar E/S sobre esos objetos.

También vimos el objeto como una unidad atómica que el usuario no debería pretender diseccionar. La mayoría de nosotros ni siquiera pensaría en jugar

52 ESTRUCTURA DE DATOS EN JAVA

con los bits que representan a un número en coma flotante, y consideraríamos completamente ridículo el intentar incrementar nosotros mismos un número en coma flotante alterando su representación interna.

El principio de atomicidad se conoce como ocultamiento de la información. El usuario no tiene acceso directo a las partes del objeto o a su implementación; solamente se puede acceder a ellas de forma indirecta a través de métodos proporcionados junto con el objeto. Podemos pensar que cada objeto viene con el aviso “No abrir partes no utilizables por el usuario”. En la vida real, la mayoría de la gente que intenta arreglar las cosas a pesar de tales avisos, termina produciendo más perjuicio que beneficio. En este sentido, la programación imita al mundo real. El agrupamiento de datos y las operaciones que se aplican sobre ellos, forman un agregado, mientras que el ocultamiento de los detalles del agregado, se conoce como encapsulación.

Un objetivo importante de la programación orientada a objetos es soportar la reutilización de código. Al igual que los ingenieros usan las misma componentes repetidamente en sus diseños los programadores deberían ser capaces de reutilizar objetos en lugar de implementarlos repetidamente. Cuando tenemos una implementación del objeto exacto que necesitamos usar, la reutilización es simple. El problema está en utilizar un objeto disponible cuando no es exactamente el que se necesita sino solamente uno muy parecido.

Los lenguajes orientados a objetos proporcionan varios, mecanismos para satisfacer este objetivo. Uno es el uso del código genérico. Si la implementación es idéntica independientemente del tipo de los objetos sobre los que se aplica, no hay necesidad de rescribir completamente el código: en lugar de ello, se escribe el código genéricamente, de forma que funcione para cualquier tipo. Por ejemplo, la lógica usada para ordenar un vector de objetos es independiente del tipo de los objetos que se están ordenando, de modo que se podría usar un algoritmo genérico.

Mg. Abraham Gamarra Moreno 53

El mecanismo de herencia nos permite extender la funcionalidad de un objeto. En otras palabras, podemos crear tipos nuevos con las propiedades de los tipos originales restringidos (o extendidos). La herencia nos permite avanzar un largo trecho hacia el objetivo deseado de reutilización de código.

Otro principio importante de la programación orientada a objetos es el polimorfismo. Un tipo referencia polimórfico puede referenciar objetos de varios tipos diferentes. Cuando se aplican métodos al tipo polimórfico, se selecciona automáticamente la operación apropiada para el objeto referenciado en ese momento. En Java, esto se implementa como parte de la herencia. El polimorfismo nos permite implementar clases que comparten una lógica común. El uso de la herencia para crear estas jerarquías distingue la programación orientada a objetos de la más simple programación basada en objetos. En Java, los algoritmos genéricos se implementan como parte de la herencia.

Un objeto en Java es una instancia de una clase. Una clase es similar a una estructura en C o un registro en Pascal o Ada. Excepto por el hecho de que hay dos mejoras importantes. En primer lugar, las componentes pueden ser funciones o datos, las cuales se conocen respectivamente por métodos y atributos. En segundo lugar, se puede restringir la visibilidad de dichas componentes. Puesto que los métodos que manipulan el estado del objeto son componentes de la clase, se accede a ellos mediante el operador punto, al igual que a los atributos. En la terminología de la programación orientada a objetos, cuando hacemos una llamada a un método, estamos pasando un mensaje al objeto.

2.2. UN EJEMPLO SENCILLO

Recuerde que cuando está diseñando una clase, es importante ser capaz de ocultar los detalles internos al usuario de la clase. Esto se consigue de dos formas. En primer lugar, la clase puede definir su funcionalidad mediante componentes de la clase, llamadas métodos. Algunos de estos métodos describen cómo se crea e inicializa una instancia de la estructura, otros cómo se realiza las

54 ESTRUCTURA DE DATOS EN JAVA

comprobaciones de igualdad o cómo se lleva a cabo la salida. Otras funciones serían específicas a la estructura particular. La idea es que los atributos internos que representan el estado del objeto no deberían ser manipulados directamente por el usuario de la clase, sino solamente a través de los métodos. Esta idea se puede reforzar ocultando componentes al usuario. Para hacer esto podemos especificar que se almacenen en una sección privada. El compilador hará cumplir la regla que convierte a las componentes de la sección privada en inaccesibles para el usuario del objeto. En general todas las componentes de datos deberían ser privadas.

En la siguiente programa se muestra una declaración de clase para un objeto celdaEntero. La declaración consta de dos partes: una pública y otra privada. La sección pública representa la porción visible al usuario del objeto. Puesto que esperamos ocultar los datos, en general solamente deberían aparecer métodos y constantes en la sección pública. En nuestro ejemplo, tenemos métodos que leen y escriben en el objeto celdaEntero. La sección privada contiene los datos: ésta es invisible para el usuario del objeto. Se debe acceder al atributo valorAlmacenado a través de las rutinas públicas leer y escribir; main no puede acceder directamente a ella.

public class IntCell{ /** * Retorna el valor almacenado * @return valor almacenado */ public int read( ){ return storedValue; } /** * Valor a almacenar * @param x numero a almacenar */ public void write( int x ){ storedValue = x; } private int storedValue; }

La clase TestCeldaEntero muestra cómo se usan los objetos de la clase celdaEntero.

public class TestIntCell{ public static void main( String [] args ){ IntCell m = new IntCell( );

Mg. Abraham Gamarra Moreno 55

m.write( 5 ); System.out.println("Contenido de la celda: " + m.read( ) ); } }

Puesto que leer y escribir son componentes de la clase celdaEntero, se puede acceder a ellas usando el operador punto. También se podría acceder al atributo valorAlmacenado usando el operador punto, pero debido a que es privada, el acceso sería ilegal.

A continuación resumimos la terminología. La clase define componentes, que pueden ser atributos (datos) o métodos (funciones). Los métodos pueden actuar sobre los atributos y pueden llamar a otros métodos. El modificador de visibilidad public significa que la componente es accesible para cualquiera a través del operador punto. El modificador de visibilidad private significa que la componente solamente es accesible a través de otros métodos de esa clase. Si no hay modificador de visibilidad, tenemos acceso amistoso. Hay un cuarto modificador conocido como protected.

2.3. MÉTODOS BÁSICOS

Algunos métodos son comunes a todas las clases. En esta sección se estudia los métodos modificadores y de acceso, y tres métodos especiales: los constructores, toString y equals. También se habla de los métodos estáticos, uno de los cuales es main.

2.3.1. CONSTRUCTORES

Como se ha mencionado anteriormente, una propiedad básica de los objetos es que se pueden definir, posiblemente con un valor inicial. En Java, los métodos que controlan cómo se crea e inicializa un objeto reciben el nombre de constructores. Gracias a la sobrecarga, en una clase se puede definir diversos constructores.

Si no se proporciona ningún constructor, como en el caso de la clase CeldaEntero, se genera un constructor por defecto que

56 ESTRUCTURA DE DATOS EN JAVA

inicializa cada atributo usando los correspondientes valores por defecto. Esto significa que los atributos de tipo primitivo se inicializan a cero y los tipos referencia se inicializan a la referencia null. Por tanto, en el caso de celdaEntero, la componente valorAlmacenado es 0.

Para escribir un constructor, proporcionamos un método con el mismo nombre que la clase y sin resultado. En la clase Date (incluido mas adelante) hay dos constructores:

// Constructor con cero parámetros public Date(){ month = 1; day = 1; year = 1998; } // Constructor con tres parámeteros public Date(int theMonth, int theDay, int theYear){ month = theMonth; day = theDay; year = theYear; }

Usando estos constructores, podemos con-struir objetos Date de las dos formas siguientes:

Date f1=new Date(); Date f2=new Date(15,4,1998);

Una vez que se escribe un constructor, ya no se utiliza un constructor por defecto sin parámetros. Si desea volver a contar con él, tiene que escribirlo explícitamente. Así, el primer constructor es obligatorio para poder construir el objeto que referencia f1.

2.3.2. MÉTODOS MODIFICADORES Y DE ACCESO

Los atributos de una clase se declaran normalmente como privados. En consecuencia, las rutinas que no pertenecen a la clase no pueden acceder directamente ellos. Sin embargo, algunas veces nos gustaría examinar el valor de un

Mg. Abraham Gamarra Moreno 57

atributo, e incluso podríamos querer cambiarlo directamente.

Una alternativa para hacer esto es declarar los atributos como públicos. Ésta es, sin embargo, una elección pobre, pues viola el principio de ocultamiento de información. En su lugar podemos proporcionar métodos para examinar y cambiar cada atributo. Un método que examina pero no cambia el estado de un objeto es un método de acceso. Un método que cambia el estado es un modificador (porque modifica el estado del objeto).

Casos particulares de métodos de acceso y modificadores trabajan solamente sobre un atributo. Estos métodos de acceso usualmente tendrán nombres que empiezan por obtener, como obtenerMes, mientras que los modificadores tendrán nombres que comienzan por cambiar, como cambiarMes.

La ventaja de usar un modificador es que de esta forma podemos asegurar que los cambios realizados en el estado del objeto son consistentes. Así, un modificador que cambie el atributo day en un objeto Date nos garantizará que solamente se generan fechas legales.

2.3.3. SALIDA Y TOSTRING

Normalmente queremos mostrar el estado de un objeto usando print. Esto se consigue definiendo un método toString en la clase. Dicho método devuelve un valor de tipo String apto para producir una salida. La clase Date muestra una implementación básica del método toString para dicha clase.

2.3.4. EQUALS

El método equals se usa para comprobar si dos referencias describen el mismo valor. La signatura es siempre la siguiente:

58 ESTRUCTURA DE DATOS EN JAVA

public boolean equals( object lder)

Observe que el parámetro es del tipo object, en lugar del tipo de la clase. El método equals sobre una clase Nombreclase se implementará de modo que devuelva true sólo cuando lder es una instancia de NombreClase y, si tras la conversión a NombreClase, todos los atributos primitivos son iguales (usando ==) y todos los atributos referencia son iguales (usando una aplicación componente a componente de equals).

La clase Date proporciona un ejemplo de cómo se implementas equals.

public class Date{ // Atributos private int month; private int day; private int year; // Constructor con cero parámetros public Date(){ month = 1; day = 1; year = 1998; } // Constructor con tres parámeteros public Date(int theMonth, int theDay, int theYear){ month = theMonth; day = theDay; year = theYear; } // Retorna true si los dos valores son iguales public boolean equals(Object rhs){ if(!(rhs instanceof Date)) return false; Date rhDate = (Date) rhs; return rhDate.month == month && rhDate.day == day && rhDate.year == year; } // Conversión a String public String toString(){ return month + "/" + day + "/" + year; } } _________________________________________________________ public class DateApp{ // Ejempo main public static void main(String [] args){ Date d1 = new Date(); Date d2 = new Date(1,1,1998); Date d3 = new Date(1,1,1999); System.out.println("Date 1: "+d1);

Mg. Abraham Gamarra Moreno 59

System.out.println("Date 2: "+d2); System.out.println("Date 3: "+d3); System.out.println("Date1==Date2?: "+d1.equals(d2)); System.out.println("Date1==Date3?: "+d1.equals(d3)); } }

2.3.5. MÉTODOS STATIC

Un método estático es un método que no necesita un objeto que lo controle. El método estático más común es main. En las clases String, Integer y Math se puede encontrar otros métodos estáticos. Algunos ejemplos son String.valueOf, Integer.parseInt, Math.sin y Math.max. El acceso a los métodos estáticos utiliza las mismas reglas de visibilidad que los atributos estáticos.

Recuerde que algunos atributos de la clase usan el modificador static. Usándolo, en conjunción con la palabra final, obtenemos las constantes. Sin la palabra final, tenemos atributos estáticos, que tienen otro significado distinto, estudiado mas adelante.

2.3.6. MÉTODO main

Cuando se usa el comando java para ejecutar el intérprete, se llama al método main de la clase del fichero referenciado por el comando. Por tanto, cada clase puede tener su propia función main sin ningún problema. Sin embargo, aunque así se puede probar la funcionalidad, colocar main en una clase proporciona a esta función más visibilidad que la que estaría permitida en general. Por tanto, llamadas de main a métodos no públicos tendrán éxito en la prueba, aunque serán ilegales en un entorno más general.

Resumen

60 ESTRUCTURA DE DATOS EN JAVA

Las clases y los objetos son la estructura basica del Lenguaje Java; estos permiten crear estructuras que el usuario necesita en sus aplicaciones.

Los datos se guardan en los atributos de una clase y la manipulación de estos, se realiza con los métodos.

Bibliografía Recomendada

• Allen Weiss, Mark (2000). “Estructuras de Datos en Java, compatible con Java 2”. Editorial Addison Wesley. España.

• Ceballos Sierra, Javier (2000). “JAVA 2 Curso de Programación”. Editorial Alfaomega-Rama. México.

• Deitel y Deitel (1998). “Como programar en Java”. Editorial Prentice Hall. México.

Nexo

La siguiente unidad académica revisa la manipulación de los arreglos unidimensionales.

Actividad

• Pruebe los programas de los ejemplos anteriores y realice un análisis de su implementación.

Auto evaluación formativa

Escriba programas que encuentren la solución a los siguientes problemas:

PROBLEMA UNO

Realice un programa que permita implementar la clase empleado. La clase almacenará los atributos: nombre del empleado, cargo que ocupa y sueldo que percibe. Los métodos a implementar permitiran almacenar valores en los atributos, mostrar los valores almacenados y el tercer método debe permitir aumentar el sueldo del empleado.

Mg. Abraham Gamarra Moreno 61

PROBLEMA DOS

Realice un programa que implemente la clase Cuenta con atributos que almacenen el nombre del cliente y su saldo. Los métodos a implementar deben permitir asignar valores a los atributos, mostrar estos valores, además se debe desarrollar métodos que nos permitan recibir depósitos y realizar retiros de la cuenta.

Mg. Abraham Gamarra Moreno 63

UNIDAD ACADEMICA 3

ARREGLOS UNIDIMENSIONALES: VECTORES

Un arreglo unidimensional, o simplemente un arreglo, de N variables de algún tipo de dato se declara en la forma:

Tipo_de_dato []identificador=new Tipo_de_dato[Longitud];

Donde:

Tipo_de_dato : Es el tipo de dato usado en el arreglo.

Identificador : Es el nombre del arreglo.

Longitud : Es el tamaño del arreglo o la cantidad de elementos(variables) que se utilizará en el arreglo.

Ejemplo:

int [ ]A=new int[100];

El arreglo A consiste de la colección de variables A[0], A[1], …A[99] de tipo int, que son referidas por el nombre del arreglo y el correspondiente subíndice entre corchetes. 100 es la dimensión del arreglo –cantidad de elementos- y debe ser un entero positivo constante

64 ESTRUCTURA DE DATOS EN JAVA

3.1. OPERACIONES BÁSICAS CON UN ARREGLO UNIDIMENSIONAL

Suponemos que A es un arreglo unidimensional y a continuación se dan algunas operaciones sobre ella:

A.INGRESO() Este método lee n elementos y los inserta al arreglo.

A.REPORTE() Este método imprime los elementos almacenados en el arreglo.

A.LOCALIZAR(x) Método que retorna la índice del primer elemento de A que es igual a x o devuelve -1 si tal elemento no existe.

A.SUPRIMIR(pos) Método que elimina del arreglo A el elemento cuya índice es pos.

A.INSERTAR(x,pos) Método que inserta x en el Arreglo A en la posición pos.

Nota: Para los siguientes programas se utiliza la clase Leer que se cita en la unidad académica 1.

3.2. IMPLEMENTACIÓN DE LAS OPERACIONES DE UN ARREGLO UNIDIMENSIONAL

Para implementar se utiliza la clase ArregloUni:

public class ArregloUni{ static int MAX=20; private int n; private int []a=new int[MAX]; //Define métodos ……….. }

La clase efectiva es:

// Utiliza la clase Leer que debe de estar almacenada // en la misma carpeta public class ArregloUni{ static int MAX=20; int n; int []a=new int[MAX]; public int cantidad(){ return n; } public void ingreso(){ int i,cant; do{ System.out.print("Cuantos elementos : "); cant=Leer.datoInt(); } while(cant<1 || cant>MAX); for(i=0;cant>i;i++){ System.out.print("elemento "+i+":"); a[i]=Leer.datoInt(); } n=cant; }

Mg. Abraham Gamarra Moreno 65

public void reporte(){ int i; if(n>0){ for(i=0;n>i;i++) System.out.print(a[i]+"\t"); System.out.println("\n"); } else System.out.println("Esta Vacio"); } public int localizar(int x){ int i=0; if(n>0){ while (i<n-1 && x!=a[i]) i++; if (x==a[i]) return i; // Esta en posición i else return -1; // No se encuentra } else return -2; // Esta vacia } public void insertar(int x, int pos){ int i; if ((n>0) && (n)!=MAX){ for(i=n-1;pos<=i;i--) a[i+1]=a[i]; a[pos]=x; n=n+1; } else if (n>0) System.out.println("Desbordamiento"); else System.out.println("Esta vacio"); } public void suprimir(int pos){ int i; if(n>0){ for(i=pos;n-1>i;i++) a[i]=a[i+1]; n=n-1; } else System.out.println("Esta vacio"); } }

Para probar la clase utilice la siguiente clase:

public class DemoArregloUni{ public static void main(String []args){ ArregloUni vector=new ArregloUni(); int x=0,pos=0,sw,opcion; sw=1; do{ System.out.println("\n\n\n\n”+ ”Procesamiento de una arreglo Unidimensional\n"); System.out.println("0. Salir"); System.out.println("1. Ingreso"); System.out.println("2. Reporte"); System.out.println("3. Localiza elemento"); System.out.println("4. Inserta elemento"); System.out.println("5. Suprime elemento"); System.out.print("Opcion ==> "); opcion=Leer.datoInt(); switch(opcion){ case 0:sw=0;break; case 1:vector.ingreso(); break; case 2:vector.reporte(); break;

66 ESTRUCTURA DE DATOS EN JAVA

case 3: if(vector.cantidad()>0){ System.out.print("Valor a localizar: "); x=Leer.datoInt(); pos=vector.localizar(x); if(pos==-1) System.out.println("No se encuentra"); else System.out.println("Esta en el indice: "+pos); } else System.out.println("Esta vacio"); break; case 4: System.out.print("Valor a insertar: "); x=Leer.datoInt(); System.out.print("Indice : "); pos=Leer.datoInt(); vector.insertar(x,pos); break; case 5: System.out.print("Indice del valor a suprimir: "); pos=Leer.datoInt(); vector.suprimir(pos); break; } }while(sw==1); } }

3.3. OPERACIONES BÁSICAS CON UN ARREGLO UNIDIMENSIONAL ORDENADO

Suponemos que A es un arreglo unidimensional (donde el índice 0 no se utiliza), que va a mantener los elementos del arreglo ordenado ascendentemente, algunas operaciones sobre ella son:

A.INGRESO() Este método lee n elementos y los inserta ordenadamente en el arreglo.

A.REPORTE() Este método imprime los elementos almacenados en el arreglo.

A.LOCALIZAR(x)

Método que retorna el índice del elemento de A que es igual a x o devuelve -índice si el elemento no existe. El valor absoluto de –índice indica la posición donde debería estar ubicado el elemento si se insertaría x.

A.SUPRIMIR(x) Método que elimina del arreglo A el elemento cuyo valor es igual a x, después de la eliminación de x el arreglo se mantiene ordenado.

A.INSERTAR(x)

Método que inserta x en el Arreglo A. Después de insertar x el arreglo se mantiene ordenado. Este arreglo no permite valores repetidos y retorna verdadero (true) si la inserción se realizo con éxito, caso contrario retorna falso (false).

3.4. IMPLEMENTACIÓN DE LAS OPERACIONES DE UN ARREGLO UNIDIMENSIONAL ORDENADO

Para implementar se utiliza la clase ArregloUniOrd:

Mg. Abraham Gamarra Moreno 67

public class ArregloUniOrd{ static int MAX=20; private int n; private int []a=new int[MAX+1]; //Define métodos ……….. }

La clase efectiva es:

// Utiliza la clase Leer que debe de estar almacenada // en la misma carpeta public class ArregloUniOrd{ static int MAX=20; int n; int []a=new int[MAX+1]; public int cantidad(){ return n; } public void ingreso(){ int i,cant,x; do{ System.out.print("Cuantos elementos : "); cant=Leer.datoInt(); } while(cant<1 || cant>MAX); i=1; while(i<=cant){ System.out.print("Elemento "+i+":"); x=Leer.datoInt(); if (insertar(x)) i++; } n=cant; } public void reporte(){ int i; if(n>0){ for(i=1;i<=n;i++) System.out.print(a[i]+"\t"); System.out.println("\n"); } else System.out.println("Esta Vacio"); } public int localizar(int x){ int i=1,pos; while (i<=n && a[i]<x) i++; if (i>n) pos=-i; // Debe estar en la posición else if (a[i]>x) pos=-i; // Debe estar en la posición else pos=i; // Se encuentra en la posición return pos; } public boolean insertar(int x){ int i,pos; boolean ok; if (n<MAX){ pos=localizar(x); if(pos>0){ System.out.println("Ya existe el elemento"); ok=false; }

68 ESTRUCTURA DE DATOS EN JAVA

else{ n=n+1; pos=-pos; for(i=n;i>=pos+1;i--) a[i]=a[i-1]; a[pos]=x; ok=true; } } else{ System.out.println("No hay espacio en el arreglo"); ok=false; } return ok; } public void suprimir(int x){ int i,pos; if(n>0){ pos=localizar(x); if(pos<0) System.out.println("No existe el elemento"); else{ n=n-1; for(i=pos;i<=n;i++) a[i]=a[i+1]; } } else System.out.println("Esta vacio"); } }

Para probar la clase:

public class DemoArregloUniOrd{ public static void main(String []args){ ArregloUniOrd vector=new ArregloUniOrd(); int x=0,pos=0,sw,opcion; sw=1; do{ System.out.println("\n\n\n\nProcesamiento de una arreglo"); System.out.println("unidimensional ordenado\n"); System.out.println("0. Salir"); System.out.println("1. Ingreso"); System.out.println("2. Reporte"); System.out.println("3. Localiza elemento"); System.out.println("4. Inserta elemento"); System.out.println("5. Suprime elemento"); System.out.print("Opcion ==> "); opcion=Leer.datoInt(); switch(opcion){ case 0:sw=0;break; case 1:vector.ingreso(); break; case 2:vector.reporte(); break; case 3: if(vector.cantidad()>0){ System.out.print("Valor a localizar: "); x=Leer.datoInt(); pos=vector.localizar(x); if(pos>0) System.out.println("Esta en el indice: "+pos); else System.out.println("No se encuentra"); } else System.out.println("Esta vacio");

Mg. Abraham Gamarra Moreno 69

break; case 4: System.out.print("Valor a insertar: "); x=Leer.datoInt(); vector.insertar(x); break; case 5: System.out.print("Valor a suprimir: "); x=Leer.datoInt(); vector.suprimir(x); break; } }while(sw==1); } }

Resumen

Los arreglos permiten almacenar un conjunto de variables con un solo nombre. Cada variable se accesa a traves de sus indices; estas variables tienen un indice para los arreglos unidimensionales.

Bibliografía Recomendada

• Allen Weiss, Mark (2000). “Estructuras de Datos en Java, compatible con Java 2”. Editorial Addison Wesley. España.

• Ceballos Sierra, Javier (2000). “JAVA 2 Curso de Programación”. Editorial Alfaomega-Rama. México.

• Deitel y Deitel (1998). “Como programar en Java”. Editorial Prentice Hall. México.

• December, John (1996). “Introducción a Java”. Editorial Prentice Hall. México.

• Decker, Rick y Hirshfield, Stuart (2001). “Introducción a la Programación en Java”. Segunda edición. México.

Nexo

La siguiente unidad académica revisa las nociones de los arreglos bidimensionales.

Actividad

• Pruebe los programas de los ejemplos anteriores y realice un análisis de su implementación.

70 ESTRUCTURA DE DATOS EN JAVA

Auto evaluación formativa

Escriba programas que encuentren la solución a los siguientes problemas:

PROBLEMA UNO

En un arreglo se ha almacenado el número total de toneladas de cereales cosechadas durante cada mes del año anterior. Se desea la siguiente información:

a) El promedio anual de toneladas cosechadas.

b) ¿Cuántos meses tuvieron una cosecha superior al promedio anual?

c) ¿Cuántos meses tuvieron una cosecha inferior al promedio anual?

Escriba un programa que proporcione estos datos.

PROBLEMA DOS

En un arreglo se almacenan las calificaciones finales de N alumnos. Escriba un programa que calcule a imprima:

a) El promedio general del grupo.

b) Número de alumnos aprobados y número de alumnos reprobados.

c) Porcentaje de alumnos aprobados y porcentaje de alumnos reprobados.

d) Número de alumnos cuya calificación fue mayor o igual a 8.

PROBLEMA TRES

Dada una cadena de caracteres como dato, se desea saber el número de veces que aparecen las letras 'a', 'b', …… ,'z' y 'A', 'B', …… , 'Z' en dicha cadena.

a) Escriba un programa que resuelva el problema.

Mg. Abraham Gamarra Moreno 71

b) Si usó arreglos, ¿cuántos necesitó? ¿Por qué?

c) ¿Existe otra forma de resolverlo?

PROBLEMA CUATRO

Una inmobiliaria tiene información sobre departamentos en renta almacenada en dos arreglos:

EXTENSION

E1 E2 E3 … En

El arreglo EXTENSIÓN almacena la superficie, en metros cuadrados, de cada uno de los N departamentos.

PRECIO

P1 P2 P3 … Pn

El arreglo PRECIO almacena los precios de alquiler de los N departamentos. Este arreglo está ordenado de manera creciente. Considere que no existen departamentos con igual superficie y distintos precios. Escriba un programa que pueda llevar a cabo las siguientes operaciones:

a) Llega un cliente a la inmobiliaria solicitando rentar un departamento. Si existe algún departamento con la superficie y el precio buscados, se dará de baja al departamento seleccionado.

b) Se vence un contrato y el cliente no desea renovarlo. Se deben actualizar los arreglos.

Mg. Abraham Gamarra Moreno 73

UNIDAD ACADEMICA 4

ARREGLOS BIDIMENSIONALES: TABLAS/ MATRICES

Es un conjunto de elementos, todos del mismo tipo, y se necesita especificar dos subíndices para poder identificar a cada elemento del arreglo. La representación de un arreglo bidimensional utiliza filas y columnas como se ilustra en la siguiente figura:

Representamos el arreglo bidimensional M que tiene 4 filas y 5 columnas.

Columna 0 →

Columna 1 →

Columna 2 →

Columna 3 →

Columna 4 →

Fila 0 → M[0][0] M[0][1] M[0][2] M[0][3] M[0][4]

Fila 1 → M[1][0] M[1][1] M[1][2] M[1][3] M[1][4]

Fila 2 → M[2][0] M[2][1] M[2][2] M[2][3] M[2][4]

Fila 3 → M[3][0] M[3][1] M[3][2] M[3][3] M[3][4]

En las celdas del arreglo se muestra el uso de los subíndices, donde el primer subíndice representa a la fila y el segundo subíndice representa a la columna y M es el nombre del arreglo.

74 ESTRUCTURA DE DATOS EN JAVA

Para acceder a un elemento del arreglo utilizar el siguiente formato:

Tipo_dato []identificador=new Tipo_de_dato[Número_filAs][Número_columnas];

4.1. OPERACIONES BÁSICAS CON UN ARREGLO BIDIMENSIONAL

Suponemos que A es un arreglo bidimensional y a continuación se dan algunas operaciones sobre ella.

A.INGRESO() Este método lee los elementos de las n filas y m columnas y los inserta al arreglo bidimensional (recorrido por fila mayor).

A.REPORTE() Este método imprime los elementos de cada fila almacenados en el arreglo bidimensional (recorrido por fila mayor).

A.LOCALIZAR(x)

Método que retorna la índice de la fila y columna del primer elemento de A que es igual a x o devuelve -1 si tal elemento no existe. El recorrido es por fila mayor

A.SUPRIMIR(pos_fila, pos_col) Método que elimina la fila y columna del arreglo A, pos_fila es el índice de la fila y pos_col el índice de la columna.

A.INSERTAR(pos_fila, pos_col)

Método que inserta una fila y una columna con valores cero en el Arreglo A, pos_fila es el índice de la fila a insertar y pos_col el índice de la columna a insertar

4.2. IMPLEMENTACIÓN DE LAS OPERACIONES DE UN ARREGLO BIDIMENSIONAL

Para implementar se utiliza la clase ArregloBi:

public class ArregloBi{ static int MAX=20; private int filas; private int columnas; private int [][]a=new int[MAX][MAX]; // Define métodos ……….. }

La clase Dimension almacena la fila y la columna de un elemento del arreglo bidimensional.

class Dimension{ int fila; int columna; Dimension(){ fila=0; columna=0; }

Mg. Abraham Gamarra Moreno 75

public String toString(){ return "Fila="+fila+" "+"Columna="+columna; } }

La clase efectiva es:

// Utiliza la clase Leer que debe de estar almacenada // en la misma carpeta public class ArregloBi{ static int MAX=20; private int filas; private int columnas; private int [][]a=new int[MAX][MAX]; public Dimension cantidad(){ Dimension x=new Dimension(); x.fila=filas; x.columna=columnas; return x; } public void ingreso(){ int i,j,cant_fil,cant_col; do{ System.out.print("Numero de filas : "); cant_fil=Leer.datoInt(); } while(cant_fil<1 || cant_fil>MAX); do{ System.out.print("Numero de columnas : "); cant_col=Leer.datoInt(); } while(cant_col<1 || cant_col>MAX); for(i=0;i<cant_fil;i++) for(j=0;j<cant_col;j++){ System.out.print("Elemento("+i+","+j+"):"); a[i][j]=Leer.datoInt(); } filas=cant_fil; columnas=cant_col; } public void reporte(){ int i,j; if(filas>0 && columnas>0){ for(i=0;i<filas;i++){ for(j=0;j<columnas;j++) System.out.print(a[i][j]+"\t"); System.out.println(""); } } else System.out.println("Esta Vacio"); } public Dimension localizar(int x){ int i=0,j=0,sw; Dimension d=new Dimension(); if(filas>0 && columnas>0){ sw=0; for(i=0;i<filas && sw==0;i++) for(j=0;j<columnas && sw==0;j++) if(x==a[i][j]) sw=1; if (sw==1){ d.fila=i-1; d.columna=j-1;

76 ESTRUCTURA DE DATOS EN JAVA

return d; // Esta en posición i } else{ // No se encuentra d.fila=-1; d.columna=-1; return d; } } else{ // Esta vacia d.fila=-2; d.columna=-2; return d; } } public void insertar(int pos_fil, int pos_col){ int i,j; if (filas<MAX && columnas<MAX){ // Inserta fila for (j=0;j<columnas;j++){ for(i=filas-1;pos_fil<=i;i--) a[i+1][j]=a[i][j]; a[pos_fil][j]=0; } filas++; // Inserta columna for (i=0;i<filas;i++){ for(j=columnas-1;pos_col<=j;j--) a[i][j+1]=a[i][j]; a[i][pos_col]=0; } columnas++; } else System.out.println("Desbordamiento"); } public void suprimir(int pos_fil, int pos_col){ int i,j; if(filas>0 && columnas>0){ //Elimina fila for(j=0;j<columnas;j++) for(i=pos_fil;i<filas-1;i++) a[i][j]=a[i+1][j]; filas--; //Elimina columna for(i=0;i<filas;i++) for(j=pos_col;j<columnas-1;j++) a[i][j]=a[i][j+1]; columnas--; } else System.out.println("Esta vacio"); } }

Para probar la clase utilice:

public class DemoArregloBi{ public static void main(String []args){ ArregloBi vector=new ArregloBi(); int x=0,sw,opcion,pos_fil,pos_col; Dimension pos=new Dimension(); sw=1; do{ System.out.println("\n\n\n\nProcesamiento de una arreglo bidimensional\n"); System.out.println("0. Salir"); System.out.println("1. Ingreso");

Mg. Abraham Gamarra Moreno 77

System.out.println("2. Reporte"); System.out.println("3. Localiza elemento"); System.out.println("4. Inserta elemento"); System.out.println("5. Suprime elemento"); System.out.print("Opcion ==> "); opcion=Leer.datoInt(); switch(opcion){ case 0:sw=0;break; case 1:vector.ingreso(); break; case 2:vector.reporte(); break; case 3: pos=vector.cantidad(); if(pos.columna>0 && pos.fila>0){ System.out.print("Valor a localizar: "); x=Leer.datoInt(); pos=vector.localizar(x); if(pos.columna==-1 && pos.fila==-1) System.out.println("No se encuentra"); else System.out.println("Esta en el indice: "+pos); } else System.out.println("Esta vacio"); break; case 4: pos=vector.cantidad(); do{ System.out.print("Fila a insertar: "); pos_fil=Leer.datoInt(); }while(pos_fil<0 || pos_fil>pos.fila); do{ System.out.print("Columna a insertar: "); pos_col=Leer.datoInt(); }while(pos_col<0 || pos_fil>pos.columna); vector.insertar(pos_fil,pos_col); break; case 5: pos=vector.cantidad(); do{ System.out.print("Fila a eliminar: "); pos_fil=Leer.datoInt(); }while(pos_fil<0 || pos_fil>pos.fila); do{ System.out.print("Columna a eliminar: "); pos_col=Leer.datoInt(); }while(pos_col<0 || pos_fil>pos.columna); vector.suprimir(pos_fil,pos_col); break; } }while(sw==1); } }

Resumen

Recordamos que los arreglos permiten almacenar un conjunto de variables con un solo nombre. Cada variable se accesa a traves de sus indices; estas variables dos indices para los arreglos bidimensionales.

78 ESTRUCTURA DE DATOS EN JAVA

La utilización de arreglos bidimensionales permite implementar el manejo de tablas y matrices.

Bibliografía Recomendada

• Allen Weiss, Mark (2000). “Estructuras de Datos en Java, compatible con Java 2”. Editorial Addison Wesley. España.

• Ceballos Sierra, Javier (2000). “JAVA 2 Curso de Programación”. Editorial Alfaomega-Rama. México.

• Deitel y Deitel (1998). “Como programar en Java”. Editorial Prentice Hall. México.

• December, John (1996). “Introducción a Java”. Editorial Prentice Hall. México.

• Decker, Rick y Hirshfield, Stuart (2001). “Introducción a la Programación en Java”. Segunda edición. México.

Nexo

La siguiente unidad académica amplia las nociones del Tipo de Dato Abstracto.

Actividad

• Pruebe los programas de los ejemplos anteriores y realice un análisis de su implementación.

Auto evaluación formativa

Escriba programas que encuentren la solución a los siguientes problemas:

PROBLEMA UNO

Escriba un programa que llene de ceros una matriz A(N x N) excepto en la diagonal principal donde debe asignar 1. Si N = 4, la matriz debe quedar:

1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1

Mg. Abraham Gamarra Moreno 79

PROBLEMA DOS

Escriba un programa que intercambie los elementos de las filas de un arreglo bidimensional. Los elementos de la fila 0 deben intercambiarse con los de la fila N-1, los de la fila 1 con los del N -2, y así sucesivamente. Por ejemplo, si A es:

1 4 8 -5 0 87 1 0 2 4 10 3 9 5 7 5

El resultado de la operación debe ser:

9 5 7 5 2 4 10 3 0 87 1 0 1 4 8 -5

PROBLEMA TRES

Se tienen registradas las calificaciones de 50 alumnos obtenidas en un examen. Los datos son cal[0], cal[1], ... , cal[49], donde cal es un arreglos de números enteros comprendido entre los valores 0 y 10 (0 <= cal[i] <= 10).

Escriba un programa que calcule a imprima la frecuencia de cada uno de los posibles valores.

La salida del programa debe ser como la que se muestra a continuación:

Calificación Frecuencia 0 1 ALUMNOS 1 4 ALÜMNOS 2 2 ALUMNOS …… …… 10 3 ALUMNOS

PROBLEMA CUATRO

Escriba un programa que intercambie los elementos de las filas de un arreglo bidimensional. Los elementos de la fila 0 deben intercambiarse con los de la fila N-1, los de la fila 1 con los del N -2, y así sucesivamente. Por ejemplo, si A es:

80 ESTRUCTURA DE DATOS EN JAVA

1 4 8 -5 0 87 1 0 2 4 10 3 9 5 7 5

El resultado de la operación debe ser:

9 5 7 5 2 4 10 3 0 87 1 0 1 4 8 -5

PROBLEMA CINCO

Se tiene una tabla con las calificaciones obtenidas por treinta alumnos en seis exámenes diferentes:

0 1 … 5 1

29

Escriba un programa para calcular:

a) El promedio general de calificaciones de los 30 alumnos (considerando los 6 exámenes).

b) El alumno que obtuvo la mayor calificación en el tercer examen.

c) El alumno (si lo hubiera) que obtuvo la mayor calificación en el primero y en el sexto examen.

d) Dado el número que identifica a un alumno, informar en qué examen logró la menor calificación.

e) ¿En cuál examen fue más alto el promedio de los 30 alumnos?

Mg. Abraham Gamarra Moreno 81

UNIDAD ACADEMICA 5

TIPOS DE DATOS ABSTRACTOS (TDA)

5.1. TIPO DE DATOS

Llamaremos Tipo de Datos de una variable al conjunto de valores que dicha variable puede asumir.

El tipo de una variable en un programa para un lenguaje de alto nivel requiere de una declaración de tipo la cual tiene 2 objetivos:

� Separar el espacio de memoria que los valores de la variable requieren. Por ejemplo 1 byte para un carácter, 2 bytes para un entero, 4 bytes para un real, etc.

� Interpretar correctamente el contenido de la memoria a la variable que accede.

5.2. TIPOS DE DATOS ABSTRACTOS (TDA)

Un tipo de datos abstracto (TDA) consiste en:

� Un modelo matemático y

� Un conjunto de operaciones definidas en el modelo

82 ESTRUCTURA DE DATOS EN JAVA

5.3. IMPLEMENTACIÓN DE TIPOS DE DATOS ABSTRACTOS

Una implementación de un TDA es la representación (usando estructuras de datos) y la traducción en sentencias de un lenguaje de programación de:

� La declaración de que una o más variables son de aquel tipo y

� Una función para cada una de las operaciones del TDA.

Ejemplo del TDA PILA

Tres representaciones clásicas de pilas son las siguientes:

Las operaciones del TDA PILA son las siguientes: put (o push), remove (o pop), item (o top), empty y make (o new). La operación put pone un elemento en el tope de la pila, remove borra el último elemento

Mg. Abraham Gamarra Moreno 83

que se introdujo, item retorna el elemento en el tope de la pila, empty dice si la pila está vacía o no, y make crea una nueva pila.

Estas son todas las operaciones necesarias. Cualquier otra operación que se defina (por ejemplo isFull) hace que se especifique más de lo necesario.

EJEMPLO UNO

Ningún computador puede almacenar exactamente al número racional 1/3, por ejemplo. Sin embargo puede ser necesario operar sólo en aritmética racional.

Es posible hacer esto, para lo cual primero definimos el TDA RACIONAL:

El concepto matemático es el de par ordenado de números enteros:

0,),( ≠qq

pparaqp

Operaciones:

Igualdad de números racionales

(p,q) = (p’, q’) ⇔ p q’ = p’ q

Adición en los racionales

(p , q) + (p’ , q’) = (p q’ + p’q , q q’)

Multiplicación de racionales

(p , q) . (p’ , q’) = (p p’ , q q’)

IMPLEMENTACIÓN USANDO ARREGLOS

// La clase Leer debe estar en alguna carpeta de // las especificadas por la variable de // entorno CLASSPATH. public class CRacional{ static int max=2; int[] rational=new int[max]; CRacional(){ rational[0]=0; rational[1]=0;

84 ESTRUCTURA DE DATOS EN JAVA

} public void leer(){ int i; for (i=0;i<max;i++){ System.out.print("ingrese elemento "+(i+1)+":"); rational[i]=Leer.datoInt(); } } public String toString(){ if (rational[0]==rational[1]) return ""+rational[0]/rational[1]; else if (rational[1]==1) return ""+rational[0]; else return rational[0]+"/"+rational[1]; } public CRacional sumar(CRacional y){ CRacional su=new CRacional(); su.rational[0]=rational[0]*y.rational[1]+rational[1]*y.rational[0]; su.rational[1]=rational[1]*y.rational[1]; su.simplificar(); return su; } public CRacional multiplicar(CRacional y){ CRacional mu=new CRacional(); mu.rational[0]=rational[0]*y.rational[0]; mu.rational[1]=rational[1]*y.rational[1]; mu.simplificar(); return mu; } public void simplificar(){ int a,b,res; a=rational[0]; b=rational[1]; while(b!=0){ res=a % b; a=b; b=res; } rational[0]/=a; rational[1]/=a; } }

// La clase Leer debe estar en alguna carpeta de las especificadas // por la variable de entorno CLASSPATH. public class CRacionalApp{ public static void main(String[] args){ CRacional a=new CRacional(); CRacional b=new CRacional(); CRacional s=new CRacional(); CRacional m=new CRacional(); System.out.println("ingrese primer racional"); a.leer(); System.out.println("ingrese segundo racional"); b.leer(); s=a.sumar(b); m=a.multiplicar(b);

Mg. Abraham Gamarra Moreno 85

System.out.println("contenido del 1er racional "+a); System.out.println("contenido del 2do racional "+b); System.out.println("contenido de la suma es "+s); System.out.println("contenido de la multiplicacion es "+m); } }

IMPLEMENTACIÓN USANDO ATRIBUTOS

// La clase Leer debe estar en alguna carpeta de las especificadas // por la variable de entorno CLASSPATH. public class CRacional{ int num,den; CRacional(){ num=0; den=0; } public void leer(){ System.out.print("Numerador : "); num=Leer.datoInt(); System.out.print("Denominador : "); den=Leer.datoInt(); } public String toString(){ if (num==den) return ""+num/den; else if (den==1) return ""+num; else return num+"/"+den; } public CRacional sumar(CRacional y){ CRacional su=new CRacional(); su.num=num*y.den+den*y.num; su.den=den*y.den; su.simplificar(); return su; } public CRacional multiplicar(CRacional y){ CRacional mu=new CRacional(); mu.num=num*y.num; mu.den=den*y.den; mu.simplificar(); return mu; } public void simplificar(){ int a,b,res; a=num; b=den; while(b!=0){ res=a % b; a=b; b=res; } num/=a; den/=a; }

86 ESTRUCTURA DE DATOS EN JAVA

}

// La clase Leer debe estar en alguna carpeta de las especificadas // por la variable de entorno CLASSPATH. public class CRacionalApp{ public static void main(String[] args){ CRacional a=new CRacional(); CRacional b=new CRacional(); CRacional s=new CRacional(); CRacional m=new CRacional(); System.out.println("ingrese primer racional"); a.leer(); System.out.println("ingrese segundo racional"); b.leer(); s=a.sumar(b); m=a.multiplicar(b); System.out.println("contenido del 1er racional "+a); System.out.println("contenido del 2do racional "+b); System.out.println("contenido de la suma es "+s); System.out.println("contenido de la multiplicacion es "+m); } }

EJEMPLO DOS

Se tiene un TDA enterazo que guarda un numero entero, cada cifra es un elemento de un arreglo de enteros. Se pide desarrollar un programa para las operaciones suma y resta.

// La clase Leer debe estar en alguna carpeta de las especificadas // por la variable de entorno CLASSPATH. public class CEnterazo{ static int max=4; int[] enterazo=new int[max]; CEnterazo(){ for(int i=0;i<max;i++) enterazo[i]=0; } public void leer_numero(){ int i; System.out.println("Ingrese cifra por cifra del numero ("+(max-1)+" digitos) :"); for(i=1;i<max;i++) enterazo[i]=Leer.datoInt(); } public String toString(){ String x; int i; x=""; for(i=0;i<max;i++) x=x+enterazo[i]; return x; } //halla la resta de dos enteros si el primero //es mayor que el segundo public CEnterazo resta(CEnterazo y){ int i;

Mg. Abraham Gamarra Moreno 87

CEnterazo re=new CEnterazo(); for(i=max-1;i>=0;i--) if (enterazo[i]>=y.enterazo[i]) re.enterazo[i]=enterazo[i]-y.enterazo[i]; else{ re.enterazo[i]=(enterazo[i]+10)-y.enterazo[i]; y.enterazo[i-1]=y.enterazo[i-1]+1; }//fin de else (x[i]>y[i]) return re; } public CEnterazo suma(CEnterazo y){ int i,a=0; CEnterazo su=new CEnterazo(); for(i=max-1;i>=0;i--){ su.enterazo[i]=enterazo[i]+y.enterazo[i]+a; if (su.enterazo[i]>=10){ a=su.enterazo[i]/10;//calcula acarreo su.enterazo[i]=su.enterazo[i]%10;//halla lo que se queda } else a=0; } return su; } }

// La clase Leer debe estar en alguna carpeta de las especificadas // por la variable de entorno CLASSPATH. public class CEnterazoApp{ public static void main(String[] args){ CEnterazo n1=new CEnterazo(); CEnterazo n2=new CEnterazo(); CEnterazo r=new CEnterazo(); n1.leer_numero(); System.out.println("El primer numero es :"+n1); n2.leer_numero(); System.out.println("El segundo numero es :"+n2); r=n1.suma(n2); System.out.println("La suma es :"+r); r=n1.resta(n2); System.out.println("La resta es :"+r); } }

EJEMPLO TRES

Implementación de la operación diferencia de un TDA conjunto de 5 elementos enteros cada conjunto. El conjunto se representa por un arreglo de enteros, el conjunto diferencia si tiene menos de 5 elementos es completada con ceros.

// La clase Leer debe estar en alguna carpeta de las especificadas // por la variable de entorno CLASSPATH. public class CConjunto{ static int N=5;

88 ESTRUCTURA DE DATOS EN JAVA

int[] Conjunto=new int[N]; CConjunto(){ for(int i=0;i<N;i++) Conjunto[i]=0; } CConjunto(int a,int b,int c,int d,int e){ Conjunto[0]=a; Conjunto[1]=b; Conjunto[2]=c; Conjunto[3]=d; Conjunto[4]=e; } public CConjunto diferencia(CConjunto b){ int i, j=0;//j indice de d int v;//elemento a buscar CConjunto d=new CConjunto(); for(i=0;i<N;i++){ v=Conjunto[i];//toma elemento de a para buscar en b if(b.busca(v)==-1)//no existe elemento en b { d.Conjunto[j]=Conjunto[i]; j++; } } //agrega los ceros a d for(i=j;i<N;i++) d.Conjunto[i]=0; return d; } public int busca(int v){ int i=0; while(i<N-1 && Conjunto[i]!=v) i++; if(Conjunto[i]==v) return i; //si encuentra retorna el índice else return -1; //si no encuentra retorna -1 } public String toString(){ String x; int i; x=""; for(i=0;i<N;i++) if (Conjunto[i]!=0) x=x+Conjunto[i]+" "; return x; } }

// La clase Leer debe estar en alguna carpeta de las especificadas // por la variable de entorno CLASSPATH. public class CConjuntoApp{ public static void main(String[] args){ CConjunto a=new CConjunto(6,7,5,4,2); CConjunto b=new CConjunto(8,3,4,9,6); CConjunto d=new CConjunto(); System.out.println("Primer conjunto : "+a); System.out.println("Segundo conjunto: "+b); d=a.diferencia(b);

Mg. Abraham Gamarra Moreno 89

System.out.println("Diferencia : "+d); } }

Resumen

Los Tipos de Datos Abstractos nos permite crear nuestros propios tipos de Datos; basados en los tipos de datos básicos, de un Lenguaje de Programación.

Bibliografía Recomendada

• Allen Weiss, Mark (2000). “Estructuras de Datos en Java, compatible con Java 2”. Editorial Addison Wesley. España.

• Ceballos Sierra, Javier (2000). “JAVA 2 Curso de Programación”. Editorial Alfaomega-Rama. México.

• Deitel y Deitel (1998). “Como programar en Java”. Editorial Prentice Hall. México.

• December, John (1996). “Introducción a Java”. Editorial Prentice Hall. México.

• Decker, Rick y Hirshfield, Stuart (2001). “Introducción a la Programación en Java”. Segunda edición. México.

Nexo

La siguiente unidad académica trata el uso de los algoritmos recursivos.

Actividad

• Pruebe los programas de los ejemplos anteriores y realice un análisis de su implementación.

Auto evaluación formativa

Escriba programas que encuentren la solución a los siguientes problemas:

PROBLEMA UNO

Escriba un programa que permita operar con números complejos a+bi, en donde:

90 ESTRUCTURA DE DATOS EN JAVA

abs(a + bi) � sqrt(a2 + b2)

(a+bi) + (c+di) � (a + c) + (b + d)i

(a+bi) * (c+di) � (a*c – b*d) + (a*d + b*c)i

-(a + bi) � (-a) + (-b)i

PROBLEMA DOS

Escriba un programa que permita operar con números complejos definido en su forma polar, en donde:

)(cos θθ isenrbia +=+ 22bar +=

=

a

barctanθ

Operaciones

Suma:

( ) ( )

( ) ( )22112211

222111

sensencoscos

sencossencos

θθθθ

θθθθ

rrirr

irir

+++

=+++

Producto:

( ) ( )

( ) ( ))sen()cos(**

sencos*sencos

12121

222111

θθθθ

θθθθ

+++

=++

irr

irir

División:

( )

( )( ))sen()cos(

sencos

sencos121

2

1

222

111 θθθθθθ

θθ−+−=

+

+i

r

r

ir

ir

Potencia:

( ) ))sen()(cos()sen(cos θθθθ ninrirnn

+=+

Mg. Abraham Gamarra Moreno 91

Raíz (tiene n raíces):

1416.3

1,...,2,1,0

))2

sen()2

(cos()sen(cos

=

−=

++

+=+

π

πθπθθθ

nk

n

ki

n

krir nn

Mg. Abraham Gamarra Moreno 93

UNIDAD ACADEMICA 6

RECURSION

6.1. ALGORITMOS RECURSIVOS

La recursión es un concepto fundamental en Matemáticas y en la Ciencia de la Computación, en este último caso particularmente cuando se manipulan ciertas estructuras de datos de naturaleza recursiva o como paso previo para obtener una solución no recursiva.

Un objeto es llamado recursivo si parcialmente consiste o está definido en términos de sí mismo.

Las características esenciales en la recursión son:

� La condición de terminación. Sin ella, se tendría un número infinito de llamadas recursivas.

� Un parámetro que varía en cada llamada recursiva y que después de un número finito de valores debe conducir a la condición de terminación.

94 ESTRUCTURA DE DATOS EN JAVA

PROGRAMA EJEMPLO UNO

Factorial de un número natural

El factorial de un número natural n es otro número natural denotado por n! y definido como sigue:

a) n! = n (n-1)! , si n > 0

b) 0! = 1

De acuerdo con está definición, el cálculo de factorial de 4! es como sigue:

4! = 4 * (3!) por (b) 4! = 4 * 3* (2!) por (b) 4! = 4 * 3* 2 * (1!) por (b) 4! = 4 * 3* 2 * 1* (0!) por (b) 4! = 4 * 3* 2 * 1* 1 por (b) 4! = 120

La implementación de una función factorial recursiva en el Lenguaje C++ es:

public class factorial{ public static long factorial(long n){ if (n==0) return(1); else return(n*factorial(n-1)); } public static void main(String []args){ long n; System.out.print("Ingrese un número: "); n=Leer.datoLong(); System.out.println("El factorial es "+factorial(n)); } }

PROGRAMA EJEMPLO TWO

Multiplicación de números naturales.

El producto a*b en donde a y b son enteros positivos, se define como a sumado a sí mismo b veces (definición iterativa).

Una definición recursiva equivalente es:

a) a*b = a, si b=1

b) a*b = a * (b-1) + a si b>1

De acuerdo con esta definición, si se desea evaluar 6 * 2 se tiene:

Mg. Abraham Gamarra Moreno 95

6 *3 = 6 * 2 + 6 = 6 * 1+ 6 + 6 = 6 + 6 + 6

public class producto{ public static int producto(int a, int b){ if (b==1) return(a); else return(producto(a,b-1)+a); } public static void main(String []args){ int a,b,p; System.out.print("Ingrese 1er número: "); a=Leer.datoInt(); System.out.print("Ingrese 2do número: "); b=Leer.datoInt(); p=producto(a,b); System.out.println("El producto es "+p); } }

PROGRAMA EJEMPLO TRES

Suma de los n numeros consecutivos: 1+2+3+…+n

public class sumaConsecutivos{ public static int suma(int n){ if (n==0) return(0); else return(suma(n-1)+n); } public static void main(String []args){ int n,s; System.out.print("Ingrese un número: "); n=Leer.datoInt(); s=suma(n); System.out.println("La suma es "+s); } }

PROGRAMA EJEMPLO CUATRO

Determina el mayor valor almacenado en un arreglo unidimensional.

// Utiliza la clase Leer que debe de estar almacenada // en la misma carpeta public class ArregloUni{ static int MAX=20; int n; int []a=new int[MAX]; public int cantidad(){ return n; } public void ingreso(){ int i,cant; do{ System.out.print("Cuantos elementos : "); cant=Leer.datoInt(); } while(cant<1 || cant>MAX); for(i=0;cant>i;i++){ System.out.print("elemento "+i+":");

96 ESTRUCTURA DE DATOS EN JAVA

a[i]=Leer.datoInt(); } n=cant; } public void reporte(){ int i; if(n>0){ for(i=0;n>i;i++) System.out.print(a[i]+"\t"); System.out.println("\n"); } else System.out.println("Esta Vacio"); } public int localizar(int x){ int i=0; if(n>0){ while (i<n-1 && x!=a[i]) i++; if (x==a[i]) return i; // Esta en posición i else return -1; // No se encuentra } else return -2; // Esta vacia } public void insertar(int x, int pos){ int i; if ((n>0) && (n)!=MAX){ for(i=n-1;pos<=i;i--) a[i+1]=a[i]; a[pos]=x; n=n+1; } else if (n>0) System.out.println("Desbordamiento"); else System.out.println("Esta vacio"); } public void suprimir(int pos){ int i; if(n>0){ for(i=pos;n-1>i;i++) a[i]=a[i+1]; n=n-1; } else System.out.println("Esta vacio"); } int mayor(int i){ if (i==n-1) return a[n-1]; else if (a[i]>mayor(i+1)) return a[i]; else return mayor(i+1); } }

public class vectorMayor{ public static void main(String []args){ ArregloUni b; b=new ArregloUni(); b.ingreso(); b.reporte(); System.out.println("El mayor es "+b.mayor(0)); } }

Mg. Abraham Gamarra Moreno 97

PROGRAMA EJEMPLO CINCO

Calcula el máximo común divisor

public class mcd1{ public static int mcd(int a,int b){ if (b>a) return mcd(b,a); if (b==0) return a; else return mcd(b,a%b); } public static void main(String []args){ int n1,n2; char resp; do{ System.out.print("Primer número : "); n1=Leer.datoInt(); System.out.print("Segundo número: "); n2=Leer.datoInt(); System.out.println("MCD de "+n1+" y "+n2+" es " +mcd(n1,n2)); System.out.println(); System.out.print("Continuar (s/n)? "); resp=Leer.datoChar(); }while(resp!='n'&& resp!='N'); } }

Resumen

Un objeto es llamado recursivo si parcialmente consiste o está definido en términos de sí mismo. Las características esenciales en la recursión son: la condición de terminación y un parámetro que varía en cada llamada recursiva.

La recursividad permite eliminar el uso de instrucciones repetitivas.

Bibliografía Recomendada

• Allen Weiss, Mark (2000). “Estructuras de Datos en Java, compatible con Java 2”. Editorial Addison Wesley. España.

• Ceballos Sierra, Javier (2000). “JAVA 2 Curso de Programación”. Editorial Alfaomega-Rama. México.

• Deitel y Deitel (1998). “Como programar en Java”. Editorial Prentice Hall. México.

• December, John (1996). “Introducción a Java”. Editorial Prentice Hall. México.

• Decker, Rick y Hirshfield, Stuart (2001). “Introducción a la Programación en Java”. Segunda edición. México.

98 ESTRUCTURA DE DATOS EN JAVA

Nexo

La siguiente unidad académica trata el uso de los algoritmos para ordenamiento.

Actividad

• Pruebe los programas de los ejemplos anteriores y realice un análisis de su implementación.

Auto evaluación formativa

Escriba programas que encuentren la solución a los siguientes problemas:

PROBLEMA UNO

Desarrollar un procedimiento o función recursiva para hallar las combinaciones de n números combinados en grupos de r elementos. Recomendación: Utilice las siguientes propiedades:

10 =n

C

n

r

n

r Cr

rnC 1*

1−

+−=

PROBLEMA DOS

Escribir un programa que utilizando una función recursiva imprima los “n” numeros consecutivos.

PROBLEMA TRES

Diseñar un método recursivo para que recorra e imprima los elementos de un arreglo unidimensional.

PROBLEMA CUATRO

Considere un arreglo (matriz) unidimensional de enteros. Escriba algoritmos recursivos para calcular:

a) La suma de los elementos del arreglo.

Mg. Abraham Gamarra Moreno 99

b) El producto de los elementos del arreglo.

c) El promedio de los elementos del arreglo.

PROBLEMA CINCO

La función de Ackerman se define en forma recursiva para enteros no negativos de la siguiente manera:

a(m,n)=n+1 � si m=0

a(m,n)=a(m-1,n) � si m≠0, n=0

a(m,n)=a(m-1,a(m,n-1) � si m≠0,n ≠0

Escriba un algoritmo recursivo para la función de Ackerman.

Mg. Abraham Gamarra Moreno 101

UNIDAD ACADEMICA 7

ORDENAMIENTO

7.1. ORDENAMIENTO

Consiste en organizar los datos en algún orden dado, tal como ascendente o descendente; los datos a ordenar tienen que ser del mismo tipo como: numéricos, alfabéticos, alfanuméricos, fechas.

Si la siguiente lista de "N" elementos esta ordenada ascendentemente:

A1, A2, A3, A4, ... , AN

entonces:

A1<=A2<=A3<=A4<= ... <=AN

7.2. CLASES DE ORDENAMIENTO

Se consideran dos:

1. Ordenamiento interno: Tiene lugar con todos los datos en la memoria RAM del computador. Claramente, es aplicado sólo para un número razonable de datos. Los métodos de este tipo se agrupan en dos subclases.

1.1. Métodos directos

102 ESTRUCTURA DE DATOS EN JAVA

1.2. Métodos avanzados

2. Ordenamiento externo: Tiene lugar con una parte de los datos en la memoria RAM del computador y la otra en un almacenamiento secundario. Claramente, es aplicado a enormes volúmenes de datos (Todos los métodos son avanzados).

7.3. MÉTODOS DIRECTOS DE ORDENAMIENTO

Las características principales de estos métodos son las siguientes:

1. Se realizan IN SITU; es decir, con los datos almacenados en un arreglo durante todo el proceso de ordenamiento.

2. Los algoritmos que los describen son muy simples.

3. Se aplican a pequeños números de datos o a un moderado número de datos si el ordenamiento se realiza pocas veces.

7.3.1. ORDENAMIENTO POR INTERCAMBIO DIRECTO. MÉTODO DE LA BURBUJA.

Consiste en comparar dos elementos consecutivos e intercambiarlos cuando estén desubicados. La comparaciones pueden hacerse de del primer elemento al último elemento o viceversa.

Después de realizar el primer recorrido, comparar los elementos consecutivos del primer elemento al último se tiene que el último elemento esta en posición correcta. En el segundo recorrido se compara los elementos consecutivos del primer elemento al penúltimo elemento, no se considera el último por que ya esta ordenado, al terminar el recorrido los dos últimos elementos están ordenados. En el tercer recorrido se compara los elementos consecutivos del primer elemento al antepenúltimo elemento, no se considera el

Mg. Abraham Gamarra Moreno 103

último ni el antepenúltimo por que ya están ordenados, al terminar este recorrido los tres últimos elementos están ordenados. Las comparaciones continúan hasta ordenar el primero con el segundo elemento.

Burbuja de izquierda a derecha

Esta versión va colocando en cada pasada el mayor elemento de los tratados en la última posición, quedando en su posición correcta y por lo tanto excluida de los elementos a tratar en el siguiente recorrido. A0 A1 A2 A3 A4 Secuencia inicial 3 2 4 1 2 1er recorrido 2 3 1 2 4 2do Recorrido 2 1 2 3 4 3er Recorrido 1 2 2 3 4 4to Recorrido 1 2 2 3 4

SEUDOCODIGO

Para i= n-2 hasta 0 incremento -1 hacer Para j= 0 hasta i hacer Si datos[j]>datos[j+1] entonces cambio(datos[j],datos[j+1]) Finsi Finpara Finpara

Donde: Si se llama al función cambio de la siguiente manera: cambio(A,B); y los valores de sus parámetros son: A=1 y B=5. Al terminar la función los valores de las variables serán intercambiadas a: A=5 y B=1.

Burbuja de derecha a izquierda

Es una versión simetrica de la anterior desplazando los elementos menores hacia la izquierda. A0 A1 A2 A3 A4 Secuencia inicial 3 2 4 1 2 1er recorrido 1 3 2 4 2 2do Recorrido 1 2 3 2 4 3er Recorrido 1 2 2 3 4

104 ESTRUCTURA DE DATOS EN JAVA

4to Recorrido 1 2 2 3 4

SEUDOCODIGO

Para i= 1 hasta n-1 hacer Para j=n-1 hasta i incremento -1 hacer Si datos[j-1]>datos[j] entonces cambio(datos[j-1],datos[j]) Finsi Finpara Finpara

Ordenamiento por inserción directa

Este método también es conocido como el método de la baraja. Consiste en repetir el siguiente proceso desde el segundo elemento hasta el último elemento: se toma dicho elemento y se inserta en el lugar que le corresponda entre los elementos situados a la izquierda (que ya están ordenados). Los elementos superiores a la tratada se desplazaran un lugar a la derecha.

A0 A1 A2 A3 A4 Secuencia inicial 3 2 4 1 2 Se ubica A1 2 3 4 1 2 Se ubica A2 2 3 4 1 2 Se ubica A3 1 2 3 4 2 Se ubica A4 1 2 2 3 4

SEUDOCODIGO

Para i=1 hasta n-1 hacer aux=datos[i] j=i-1 Mientras datos[j]>aux y j>0 hacer datos[j+1]=datos[j] j=j-1 FinMientras Si datos[j]>aux entonces datos[j+1]=datos[j] datos[j]=aux sino datos[j+1]=aux FinSi FinPara

Ordenamiento por selección directa

Consiste en repetir el siguiente proceso desde el primer elemento hasta el penúltimo. Se selecciona la componente de menor valor de todas las situadas a la

Mg. Abraham Gamarra Moreno 105

derecha de la tratada (si que existe) y se intercambian con esta.

A0 A1 A2 A3 A4

Secuencia inicial 3 2 4 1 2

Se intercambia A0 y A3 1 2 4 3 2

No se intercambia A1 1 2 4 3 2

Se intercambia A2 y A4 1 2 2 3 4

No se intercambia A3 1 2 3 3 4

SEUDOCODIGO

Para i=0 hasta n-2 hacer k=i aux=datos[i] Para j=i+1 hasta n-1 hacer Si datos[j]<aux entonces k=j aux=datos[j] FinSi FinPara datos[k]=datos[i] datos[i]=aux FinPara

7.4. MÉTODOS AVANZADOS DE ORDENAMIENTO:

Las características principales de estos métodos son las siguientes:

1. Se aplican para un número grande de datos ya que para pocos elementos son ineficientes.

2. Los intercambios de datos se realizan a grandes distancias.

3. Los algoritmos que los describen son complicados.

7.4.1. ORDEMAMIENTO CON EL MÉTODO DE SHELL

Consiste en comparar los elementos separados en una misma distancia, si los elementos no se encuentran ordenados se intercambian sus valores. La distancia inicial es la mitad de la longitud del vector. La distancia de comparación se reduce a la mitad cuando ya no existen

106 ESTRUCTURA DE DATOS EN JAVA

intercambios a esa distancia. El proceso se repite hasta que la distancia sea 1.

DISTANCIA DE COMPARACIÓN:

D=parte_entera(9/2)=4

A0 A1 A2 A3 A4 A5 A6 A7 A8

Secuencia inicial 3 2 4 6 7 3 5 1 1

1era Comparación 3 2 4 1 1 3 5 6 7

2da Comparación 1 2 4 1 3 3 5 6 7

DISTANCIA DE COMPARACIÓN:

D=parte_entera(4/2)=2

A0 A1 A2 A3 A4 A5 A6 A7 A8

Secuencia inicial 1 2 4 1 3 3 5 6 7

1era Comparación 1 2 4 1 3 3 5 6 7

2da Comparación 1 1 3 2 4 3 5 6 7

DISTANCIA DE COMPARACIÓN:

D=parte_entera(2/2)=1

A0 A1 A2 A3 A4 A5 A6 A7 A8

Secuencia inicial 1 1 3 2 4 3 5 6 7

1era Comparación 1 1 2 3 3 4 5 6 7

SEUDOCODIGO

d=n Repetir d=Parte_entera(d/2) Repetir sw=0 i=0 Repetiir i=i+1 Si a[i]>a[i+d] entonces cambio(a[i],a[i+d]) sw=1 Finsi Hasta i+d=n Hasta sw=0 Hasta d=1

Donde: Si se llama a la función cambio de la siguiente manera: cambio(A,B); y los valores de sus parámetros son: A=1 y B=5. Al terminar la función los valores de las variables serán intercambiadas a: A=5 y B=1.

Mg. Abraham Gamarra Moreno 107

7.4.2. ORDENAMIENTO RÁPIDO (QUICK SORT)

Es un algoritmo que elige un valor llamado comparando y entonces divide a los elementos en dos partes: una parte todos los elementos mayores o iguales que el comparando y en la otra parte todos los menores. Este proceso se repite para cada trozo restante hasta que los elementos queden ordenados. Su implementación requiere del uso de la recursividad.

Medio A0 A1 A2 A3 A4 A5 A6 A7 A8 A9

1er Paso 55 86 3 10 23 12 67 59 47 31 24

2do Paso 35 24 3 10 23 12 31 47 59 67 86

<>

3er Paso 27 24 3 10 23 12 31 47 59 67 86

<> <>

4to Paso 18 24 3 10 23 12 31 47 59 67 86

<> <>

5to Paso 11 12 3 10 23 24 31 47 59 67 86

<> <>

6to Paso 6 10 3 12 23 24 31 47 59 67 86

<> <> <> <> <>

7to Paso 23 3 10 12 23 24 31 47 59 67 86

<> <> <> <> <> <> <>

8vo Paso 72 3 10 12 23 24 31 47 59 67 86

<> <> <> <> <> <> <> <>

9no Paso 63 3 10 12 23 24 31 47 59 67 86

<> <> <> <> <> <> <> <> <> <>

Orden final 3 10 12 23 24 31 47 59 67 86

Figura 7.1. Algoritmo de ordenamiento rápido.

Este algoritmo comienza estimando un valor medio, podría ser el promedio de los elementos extremos. El valor del punto medio no es crucial; el algoritmo trabajara con cualquier punto medio. No obstante, cuando más cerca esté el punto medio estimado del valor medio del arreglo, más rápida será la ordenación.

El procedimiento calcula un punto medio a partir de la media aritmética de los elementos primero y último de la porción del arreglo que se va a ordenar. Una vez que el procedimiento selecciona un punto medio, coloca en la parte inferior del

108 ESTRUCTURA DE DATOS EN JAVA

arreglo los elementos que están por debajo de dicho punto medio y los que están por encima en la parte superior, como se muestra en la figura 7.1.

En el paso 1, el punto medio es 55, la media entre 86 y 24. En el paso 2, el segmento a ordenar va desde 24 hasta 47, con el punto medio igual a 35. Observe que llos elementos del segmento raramente se distribuyen uniformemente con relación al punto medio. Esto no perjudica al procedimiento, pero disminuye su eficiencia.

En cada paso del proceso, la ordenación rápida ordena los elementos de un segmento del array alrededor del valor del punto medio. A medida que los segmentos se hacen más y más pequeños, el arreglo se aproxima a su forma totalmente ordenada.

SEUDOCODIGO

quicksort(data[],inf,sup) /* data es el arreglo a ordenar inf y sup son los indices izquierdo y derecho respectivamente que definen la porción del arreglo a ordenar */ INICIO left=inf; right=sup;

half=data[parte_entera((left+right)/2)]; Mientras left<right hacer Mientras data[left]<half y left<sup hacer left++; FinMientras Mientras half<data[right] y right>inf) right--; FinMientras Si left<right entonces cambio(data[left],data[right]) FinSi left=left+1 right=right-1 FinMientras Si inf<right entonces quicksort(data, inf, right) FinSi Si left<sup entonces quicksort(data, left, sup) FinSi FIN

Mg. Abraham Gamarra Moreno 109

Donde: Si se llama al función cambio de la siguiente manera: cambio(A,B); y los valores de sus parámetros son: A=1 y B=5. Al terminar la función los valores de las variables serán intercambiadas a: A=5 y B=1.

Para llamar a la función se utiliza:

quicksort(datos,0,n-1)

Se ordena los elementos desde el indice 0 al indice n-1, es decir, los n elementos del arreglo.

7.5. PROGRAMA CON LOS ALGORITMOS DE ORDENAMIENTO

Clase Ordenamiento

public class Ordenamiento extends ArregloUni{ public void burbuja_der_izq(){ int i,j; for (i=1;i<=n-1 ;i++) for (j=n-1;j>=i;j--) if (a[j-1]>a[j]) cambio(a,j-1,j); } public void burbuja_izq_der(){ int i,j; for (i=n-2;i<=0 ;i--) for (j=0;j<=i;j++) if (a[j]>a[j+1]) cambio(a,j,j+1); } public void baraja(){ int i,j,aux; for(i=1;i<=n-1;i++){ aux=a[i]; j=i-1; while (a[j]>aux && j>0){ a[j+1]=a[j]; j=j-1; } if(a[j]>aux){ a[j+1]=a[j]; a[j]=aux; } else a[j+1]=aux; }; } public void seleccion_directa(){

110 ESTRUCTURA DE DATOS EN JAVA

int i,j,k,aux; for(i=0;i<=n-2;i++){ k=i; aux=a[i]; for(j=i+1;j<=n-1;j++) if(a[j]<aux){ k=j; aux=a[j]; } a[k]=a[i]; a[i]=aux; } } public void shell(){ int d,i,sw; d=n; do{ d=d/2; do{ sw=0; i=-1; do{ i++; if(a[i]>a[i+d]){ cambio(a,i,i+d); sw=1; } } while(i+d!=n); } while(sw!=0); } while(d!=1); } public void quicksort(int data[],int inf,int sup){ int left,right; double half; left=inf; right=sup; half=data[(left+right)/2]; while (left<right){ while(data[left]<half && left<sup) left++; while(half<data[right] && right>inf) right--; if (left<right) cambio(data,left,right); left++; right--; } if (inf<right) quicksort(data, inf, right); if (left<sup) quicksort(data, left, sup); } public void cambio(int []a, int pos1, int pos2){ int t; t=a[pos1]; a[pos1]=a[pos2]; a[pos2]=t; } }

Clase DemoOrdenamiento

public class DemoOrdenamiento{ public static void main(String []args){ Ordenamiento vector=new Ordenamiento(); int sw,opcion;

Mg. Abraham Gamarra Moreno 111

vector.ingreso(); sw=1; do{ System.out.println( "\n\n\n\nSeleccione el algoritmo de ordenamiento\n"); System.out.println("0. Salir"); System.out.println("1. Burbuja de derecha a izquierda"); System.out.println("2. Burbuja de izquierda a derecha"); System.out.println("3. Inserción directa (Baraja)"); System.out.println("4. Seleccion directa"); System.out.println("5. Método de shell"); System.out.println("6. Ordenamiento rápido"); System.out.print("Opcion ==> "); opcion=Leer.datoInt(); if(opcion>0){ System.out.println("Arreglo antes de ordenar"); vector.reporte(); } switch(opcion){ case 0: sw=0;break; case 1: vector.burbuja_der_izq();break; case 2: vector.burbuja_izq_der();break; case 3: vector.baraja();break; case 4: vector.seleccion_directa();break; case 5: vector.shell();break; case 6: vector.quicksort(vector.a,0,vector.n-1);break; } if(opcion>0){ System.out.println("Arreglo despues de ordenar"); vector.reporte(); } }while(sw==1); } }

Resumen

El ordenamiento consiste en organizar los datos en algún orden dado, tal como ascendente o descendente.

Bibliografía Recomendada

• Allen Weiss, Mark (2000). “Estructuras de Datos en Java, compatible con Java 2”. Editorial Addison Wesley. España.

• Ceballos Sierra, Javier (2000). “JAVA 2 Curso de Programación”. Editorial Alfaomega-Rama. México.

• Deitel y Deitel (1998). “Como programar en Java”. Editorial Prentice Hall. México.

• December, John (1996). “Introducción a Java”. Editorial Prentice Hall. México.

• Decker, Rick y Hirshfield, Stuart (2001). “Introducción a la Programación en Java”. Segunda edición. México.

112 ESTRUCTURA DE DATOS EN JAVA

Nexo

La siguiente unidad académica trata el uso de los algoritmos para búsqueda.

Actividad

• Pruebe los programas de los ejemplos anteriores y realice un análisis de su implementación.

Auto evaluación formativa

Escriba programas que encuentren la solución a los siguientes problemas:

PROBLEMA UNO

Realice un programa que lea el nombre de “n” alumnos y su respectivo promedio. Estos datos deben de ordenarse y mostrar cuales son los alumnos que ocuparon el 1er, 2do y 3er lugar.

Implemente este programa utilizando todos los métodos de ordenamiento (un método por vez).

PROBLEMA DOS

Para el programa anterior muestre los tres alumnos con la nota más baja.

Implemente este programa utilizando todos los métodos de ordenamiento (un método por vez).

Mg. Abraham Gamarra Moreno 113

UNIDAD ACADEMICA 8

BÚSQUEDA

8.1. BÚSQUEDA

Se denomina búsqueda cuando queremos obtener la posición donde se encuentra el elemento o si se desea saber si esta almacenado en la estructura.

La búsqueda de uno o más elementos es una de las tareas más frecuentes en computación. Por tanto se requieren el conocimiento de métodos que hagan más eficiente el proceso.

8.1.1. DEFINICIONES

1. Un algoritmo de búsqueda es un algoritmo que acepta un argumento a y trata de encontrar un registro con llave a. Si lo encuentra, retorna dicho registro o un puntero al registro; en caso contrario retorna "un registro nulo".

2. Un algoritmo de búsqueda e inserción es un algoritmo de búsqueda tal que si no encuentra al registro con llave

114 ESTRUCTURA DE DATOS EN JAVA

dada a, lo inserta en el conjunto de datos.

8.1.2. CLASES DE BÚSQUEDA

Como en el ordenamiento hay dos clases de búsqueda:

1. Búsqueda interna: Tiene lugar con todos los datos en la memoria RAM del computador. Mencionaremos dos técnicas:

a. Búsqueda secuencial

b. Búsqueda binaria

2. Búsqueda externa: Tiene lugar con una parte de los datos en la memoria RAM del computador y la otra en un almacenamiento secundario (disco).

8.2. BÚSQUEDA SECUENCIAL

Es la más simple y es aplicable preferentemente, cuando los datos están desordenados pero almacenados en un arreglo o en una lista enlazada.

Consiste en recorrer el arreglo de izquierda a derecha hasta encontrar una componente cuyo valor coincida con el buscado o hasta a llegar al último elemento. Este algoritmo generalmente es usado cuando los datos no están ordenados y para buscar la primera ocurrencia. En los casos que existan elementos con valores repetidos iguales al valor buscado el algoritmo retorna el indice del primero que encuentra.

SEUDOCODIGO

El siguiente algoritmo retorna el indice en el arreglo donde es encontrado el “dato”, caso contrario retorna -1.

i=0; Mientras (dato<>vec[i]) y (i<n) hacer

Mg. Abraham Gamarra Moreno 115

i=i+1 FinMientras Si dato=vec[i] entonces posicion=i Sino posicion=-1 FinMientras

Donde: Dato es el valor a buscar en el arreglo unidimensional.

8.3. BÚSQUEDA BINARIA

Es la búsqueda que usamos en los diccionarios o las guías telefónicas, en los cuales las llaves (palabras o nombres, en estos casos) están ordenadas, permitiendo seleccionar una página, por ejemplo la de cerca de la mitad, comparar la llave dada con alguna palabra de dicha página y según el resultado de la comparación avanzar en el sentido apropiado.

Es un algoritmo que trabaja con arrays ordenados. Consiste en comparar el elemento que ocupa la posición central, si no es igual al valor buscado se reduce el intervalo de búsqueda a la mitad derecha o izquierda, según donde se pueda encontrase el valor a buscar. El algoritmo termina si se encuentra el valor buscado o si el término del intervalo de búsqueda queda anulado. En los casos que existan elementos con valores repetidos iguales al valor buscado este algoritmo obtendrá uno de ellos aleatoriamente según los lugares que ocupen las cuales necesariamente son consecutivos.

SEUDOCODIGO

El siguiente algoritmo retorna la posición del elemento que coincide con el buscado o -1 si no esta en el vector.

inf=0 sup=n-1 sw=0 Mientras (sup>inf) y (sw=0) hacer cen=Parte_entera((sup+inf)/2) Si dato>datos[cen] entonces inf=cen+1 Sino si dato<datos[cen] entonces sup=cen-1 Sino sw=1 Finsi FinSi

116 ESTRUCTURA DE DATOS EN JAVA

FinMientras Si sw=1 entonces posicion=cen Sino posicion=-1 Finsi

Donde: dato es el valor a buscar en el vector.

8.4. PROGRAMA CON LOS ALGORITMOS DE BÚSQUEDA

Clase Búsqueda

public class Busqueda extends ArregloUni{ public int busqueda_secuencial(int dato){ int i,posicion; i=0; while(dato!=a[i] && i<n) i++; if (dato==a[i]) posicion=i; else posicion=-1; return posicion; } public int busqueda_binaria(int dato){ int inf,sup,sw,cen=0,posicion; inf=0; sup=n-1; sw=0; while(sup>=inf && sw==0){ cen=(sup+inf)/2; if(dato>a[cen]) inf=cen+1; else if(dato<a[cen]) sup=cen-1; else sw=1; } if(sw==1) posicion=cen; else posicion=-1; return posicion; } public void quicksort(int data[],int inf,int sup){ int left,right; double half; left=inf; right=sup; half=data[(left+right)/2]; while (left<right){ while(data[left]<half && left<sup) left++; while(half<data[right] && right>inf) right--; if (left<right) cambio(data,left,right); left++; right--; } if (inf<right) quicksort(data, inf, right); if (left<sup) quicksort(data, left, sup); } public void cambio(int []a, int pos1, int pos2){ int t; t=a[pos1]; a[pos1]=a[pos2];

Mg. Abraham Gamarra Moreno 117

a[pos2]=t; } }

Clase DemoBusqueda

public class DemoBusqueda{ public static void main(String []args){ Busqueda vector=new Busqueda(); int sw,opcion,x=0,pos=0; vector.ingreso(); sw=1; do{ System.out.println("\n\n\n\nSeleccione el algoritmo de Busqueda\n"); System.out.println("0. Salir"); System.out.println("1. Busqueda secuencial"); System.out.println("2. Búsqueda binaria"); System.out.print("Opcion ==> "); opcion=Leer.datoInt(); if(opcion>0){ System.out.print("Elemento a buscar: "); x=Leer.datoInt(); } switch(opcion){ case 0: sw=0;break; case 1: System.out.println("Contenido del arreglo"); vector.reporte(); pos=vector.busqueda_secuencial(x); break; case 2: vector.quicksort(vector.a,0,vector.n-1); System.out.println("Contenido del arreglo (ordenado)"); vector.reporte(); pos=vector.busqueda_binaria(x); break; } if(opcion>0) if(pos!=-1) System.out.println("Esta en la posición: "+pos); else System.out.println("No se encuentra en el arreglo"); }while(sw==1); } }

8.5. EFICIENCIA DE LOS ALGORITMOS DE ORDENAMIENTO Y BÚSQUEDA

Seymour Lipschutz, en su libro Estructura de Datos, nos dice: "Analizar algoritmos es una de las tareas mas costosas en el diseño de estos. Para comparar dos algoritmos que solucionan el mismo problema es necesario aportar criterios que midan la eficiencia de ambos. Supongamos que "M" es el algoritmo y que "n" es el tamaño de los datos de entrada. El tiempo de ejecución y el espacio utilizado por "M", son los parámetros principales que miden la eficiencia de "M". El tiempo suele medirse contando el número de operaciones clave realizadas. Por ejemplo: En

118 ESTRUCTURA DE DATOS EN JAVA

una ordenación o búsqueda, el numero de comparaciones realizadas. Esto es debido a que suponemos que el tiempo empleado en aquellas otras operaciones que no consideramos clave es menor o a lo sumo proporcional al empleo por estas. El espacio es evaluado contando el máximo de memoria necesaria por el algoritmo".

De los algoritmos de ordenación o búsqueda expuestos líneas arriba, se puede deducir que todos utilizan aproximadamente la misma cantidad de memoria. Por esa razón concluimos:

ALGORITMO CASO PEOR CASO MEDIO

De la burbuja 2

1)-n(n

2

1)-n(n

Por inserción 2

1)-n(n

4

1)-n(n

Por selección 2

1)-n(n

2

1)-n(n

Ordenamiento rápido 2

1)-n(n n)*1,4(n

2log

Búsqueda secuencial n 2

1)+(n

Búsqueda binaria n2

log n2

log≈

La eficiencia se mide en base a las comparaciones necesarias realizadas para ordenar la lista, el numero de comparaciones tiene relación directa con la cantidad de elementos y el numero de comparaciones tiene relación directa con el tiempo, a más elementos se requiere más comparaciones y tiempo.

Resumen

Se denomina búsqueda cuando queremos obtener la posición donde se encuentra el elemento o si se desea saber si esta almacenado en la estructura.

Bibliografía Recomendada

Mg. Abraham Gamarra Moreno 119

• Allen Weiss, Mark (2000). “Estructuras de Datos en Java, compatible con Java 2”. Editorial Addison Wesley. España.

• Ceballos Sierra, Javier (2000). “JAVA 2 Curso de Programación”. Editorial Alfaomega-Rama. México.

• Deitel y Deitel (1998). “Como programar en Java”. Editorial Prentice Hall. México.

• December, John (1996). “Introducción a Java”. Editorial Prentice Hall. México.

• Decker, Rick y Hirshfield, Stuart (2001). “Introducción a la Programación en Java”. Segunda edición. México.

Actividad

• Pruebe los programas de los ejemplos anteriores y realice un análisis de su implementación.

Auto evaluación formativa

Escriba programas que encuentren la solución a los siguientes problemas:

PROBLEMA UNO

Realice un programa que almacene el nombre “n” cursos con su respectiva área (computación, matematicas, bases de datos). El programa lee el área y muestra los libros que pertenecen a esa área.

Implemente este programa utilizando todos los métodos de búsqueda (un método por vez).