Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
TEMA 1.
Introduccin a la programacin.
La figura anterior se corresponde con una de las dos filosofas4 en la que se basan los
traductores: la compilacin. Mediante ella se genera un cdigo denominado objeto, que,
una vez cargado (load) en la memoria del ordenador, se puede ejecutar. La compilacin
solo se realiza una vez (siempre que no se hagan cambios en el programa). El resultado
(programa ejecutable) puede guardarse en un dispositivo de almacenamiento externo
(disco, CD, etc.) y desde l cargarse en memoria y ejecutarse en futuras ocasiones.
El Java es un lenguaje mixto: primero se compila (por medio del compilador Javac,
produciendo ficheros con extensin .class), y a continuacin, ese cdigo se interpreta en el
1
Por el contrario, sera la tcnica ms eficiente (mayor velocidad de ejecucin y menor consumo de
memoria). No obstante, y como consecuencia de la incesante mejora y abaratamiento de la tecnologa, esta
alternativa no ha sido nunca tomada en consideracin.
2
Difcilmente se podr encontrar otra actividad ms viva que el desarrollo de lenguajes de programacin:
en tan solo cincuenta aos de existencia de los ordenadores y de la Informtica algunos autores llegan a
identificar en torno a medio millar de ellos. Se puede encontrar una referencia en:
http://www.lenguajesdeprogramacion.com/
3
Se trata de un modelo muy elemental. La realidad es algo ms compleja.
4
Existen otras soluciones intermedias.
ESTRUCTURAS DE DATOS INTRODUCCIN A LA PROGRAMACIN 3
1.1.1.2. Mtodos.
Dentro de una clase en la que se define una estructura de datos, se pueden definir
mtodos de objeto, que se aplican a una variable de la clase poniendo el nombre de la
variable y luego el nombre del mtodo, separados por un punto.
Adems de definir mtodos de objeto, dentro de la clase se pueden crear mtodos con
el modificador static: son mtodos de clase, que se pueden utilizar aunque no se haya
creado ningn objeto de la clase (al contrario de lo que ocurre con los mtodos de objeto: si
se intentan invocar sin haber creado previamente el objeto se produce un error). Los
mtodos static se invocan desde fuera de la clase poniendo el nombre de la clase y luego el
nombre del mtodo, separados por un punto.
1.1.1.3. Modificadores.
o protected: tienen acceso las clases del resto del paquete, as como desde
subclases definidas fuera del paquete.
o public: se puede acceder desde cualquier otra clase.
1.1.1.4. Excepciones.
Las excepciones son elementos que almacenan informacin para detectar hechos
excepcionales, como por ejemplo errores. En Java existen muchos tipos de excepciones
estndar y las ms habituales son del tipo IOException (errores de lectura), as como del
tipo NumberFormatException (que se genera cuando se espera leer un nmero y se recibe
algo diferente).
Cdigo Explicacin
//Primer programa en Java Lnea de comentario.
public class hola_EUI Se indica el nombre del programa.
{ Delimitador de inicio del programa.
public static void main (String [ ] args) Clase principal
{ Delimitador de inicio de la clase
Ejemplo de accin: sentencia println (escribir en el dispositivo
de salida system.out y avanzar al comienzo de la lnea
System.out.println ("Hola EUI");
siguiente) que acta sobre un sujeto (dato): la cadena de
caracteres Hola EUI.
} Delimitador de fin de clase.
} Delimitador de fin de programa.
Sintaxis Semntica
import <nombre>; Llamada a una (o varias) componente(s) de la biblioteca.
public class <nombre de la clase general> Nombre de la clase general (obligatorio)
{ Principio de la clase.
5
Este esquema se ampliar en el punto de Programacin modular (1.3)
6
Devuelve/n uno o ningn (void) valor/es. En Java no existe la posibilidad de devolver varios valores.
7
La otra alternativa (utilizada por lenguajes tales como COBOL o FORTRAN) se basa en considerar lneas
de cdigo de una longitud determinada estructuradas en campos, cada uno de los cuales tiene un significado
predeterminado.
6 INTRODUCCIN A LA PROGRAMACIN ESTRUCTURAS DE DATOS
Los nombres en Java son sensibles a las maysculas y las minsculas (por ejemplo,
cadena sera una variable distinta de Cadena). Habitualmente en Java se escribe con
minsculas, con las siguientes excepciones:
o Cuando un nombre consta de varias palabras, se escriben seguidas, comenzando
en minsculas, excepto la primera letra de cada palabra a partir de la segunda (por
ejemplo presuntoDivisor, datoMayor, etc.).
o Los nombres de las clases e interfaces empiezan con mayscula (por ejemplo
Pila, Lista, Arbol).
o Los nombres de objetos, variables y mtodos empiezan por minscula (por
ejemplo buscarMayor, maximaDiferencia, etc.).
o Los nombres de las constantes (o variables finales) se escriben en maysculas
(por ejemplo PI).
Como ya se ha indicado, los datos son los sujetos del tratamiento. Los datos, en un
programa se pueden presentar en tres modalidades:
o En forma literal. Es decir, indicando de forma explcita el propio dato. Por
ejemplo, la cadena de caracteres Hola EUI en el ejemplo anterior.
o Mediante un identificador de constante. Si se ha dado un nombre simblico al
valor de un dato (por ejemplo: PI = 3.14), el programa puede hacer referencia a l
mediante el identificador asociado.
o Mediante un identificador de variable. Se trata de un caso parecido al de
constantes, con la importante diferencia que el valor asociado al identificador de
la variable (en adelante, simplemente, variable) puede cambiar durante la
ejecucin del programa.
ESTRUCTURAS DE DATOS INTRODUCCIN A LA PROGRAMACIN 7
Numricos:
o Enteros (int). En el rango, aproximadamente, 2*109. Adems existen otros tipos
de datos enteros: byte, short y long.
o Racionales o fraccionarios (float). Aproximadamente en el rango 3.4*1038. La
parte real y la fraccionaria se separan mediante un punto (.). Tambin se pueden
utilizar nmeros reales con mayor precisin por medio del tipo double
(aproximadamente en el rango 1.8*10308).
Lgicos (boolean). Se refieren a los valores utilizados en el lgebra de Boole
(verdadero: true o falso: false).
Carcter (char). Se utiliza para representar todos los caracteres del estndar Unicode
(que incluye el ASCII).
Cadena de caracteres (String). Este tipo de datos consiste en una secuencia de
caracteres (por ejemplo El cielo est enladrillado).
1.2.3.2.1. Operaciones.
Una operacin es un proceso que acta sobre dos datos (operandos) y produce, en
consecuencia, un resultado. Se identifica mediante un smbolo (o palabra reservada)
denominado operador. Excepcionalmente se pueden presentar operaciones (unarias) que
implican un solo operando y/u operaciones con datos de diferentes tipos9. Normalmente
(pero no siempre) se utilizan dos operandos del mismo tipo que, adems, es el tipo del
resultado.
8
El concepto tipo de datos se asocia implcitamente al los datos elementales (simples). Ms adelante
(apartado 1.4) se contemplar la posibilidad de agrupar datos simples en unidades de orden superior para dar
lugar a diferentes estructuras de datos.
9
Las operaciones con ms de dos operandos las consideramos dentro del epgrafe de expresiones.
8 INTRODUCCIN A LA PROGRAMACIN ESTRUCTURAS DE DATOS
Ejemplo
Tipo Operacin Operador
Operacin Resultado
Entero (int) Suma + 3+5 8
Resta - 1-3 -2
Multiplicacin * 2 * (-5) -10
Cociente / 7/3 2
Resto % 7%3 1
Real (float) Suma + 1,23 + 8,77 10,0
Resta - 1,23 - 8,77 -7,54
Multiplicacin * -3,2 * 4,6 -14,72
Divisin / 3,2 / (-4,6) -0,6956
Lgico (boolean) Negacin ! ! true false
Unin (or) || true || false true
Interseccin (and) && true && false false
Carcter (char) No existen
10
Cadena (String) Concatenacin + Hola + Antonio Hola Antonio
10
Obsrvese que la cadena (String) Antonio incluye un espacio en blanco a su izquierda.
11
Excepto de tipo lgico (boolean) en donde no tiene sentido.
12
Los cdigos Unicode de las letras maysculas son ms bajos que los de las minsculas.
13
La diversidad de oferta de funciones integradas en el lenguaje es muy dispar, no solo entre diferentes
lenguajes sino, tambin, para un mismo lenguaje, entre diferentes desarrolladores de traductores. Para su
eficiente utilizacin se insta encarecidamente a utilizar el manual del fabricante. En este sentido su empleo
debe entenderse como manejo de catlogo, dado que la aportacin conceptual es escasa.
ESTRUCTURAS DE DATOS INTRODUCCIN A LA PROGRAMACIN 9
Algunas funciones estn disponibles como parte integrante del propio lenguaje en
tanto que otras no forman parte del lenguaje. En el caso de Java, las correspondientes
funciones (mtodos) estn declaradas y definidas en componentes (en Java, paquetes o
packages) que, en su conjunto, configuran una biblioteca, almacenadas en uno o varios
directorios14.
Ejemplos:
14
Adems de las componentes (clases) proporcionadas por el fabricante (en este caso Eclipse) el
programador puede incorporar otras de desarrollo propio (ver tema 2: Tipos Abstractos de Datos) o
adquiridas a terceros.
10 INTRODUCCIN A LA PROGRAMACIN ESTRUCTURAS DE DATOS
1.2.3.2.3. Expresiones.
Una expresin es una combinacin (coherente) de datos (literales, constantes y/o
variables), operaciones y funciones, enlazados entre s por medio de operadores.
1.2.4. Sentencias.
1.2.4.1. Asignacin.
Permite, como su propio nombre indica, asignar un valor a una variable (ver 1.2.2)
definida en la parte declarativa. Su sintaxis es:
16
<nombreVariable> = <expresin >;
Ejemplo (HolaEui2.Java):
15
Con excepcin de comentarios y Directivas de compilacin. Consultar el manual del compilador.
16
Ver epgrafe Expresiones.
17
Hacen referencia a los dispositivos configurados por defecto (el teclado y la pantalla).
ESTRUCTURAS DE DATOS INTRODUCCIN A LA PROGRAMACIN 11
cadena = linea.readLine();
.
En las dos primeras lneas, se declaran los objetos linea del tipo
BufferedReader y cadena de tipo String.
El usuario escribe los caracteres correspondientes y finaliza pulsando la tecla
Intro.
Se utiliza el mtodo readLine sobre el objeto linea, y se almacena en cadena.
Se contina con la ejecucin del programa.
Para leer otros datos que no sean de tipo String, habra que utilizar una sintaxis
similar a la siguiente:
n = Integer.parseInt (linea.readLine());
.
import java.io.*;
//Ejemplo de sentencias de entrada/salida.
public class HolaEui3 {
public static void main(String [] args) throws
NumberFormatException,IOException{
String cadena, cadena2;
int edad, ao = 2010;
BufferedReader linea=new BufferedReader (new InputStreamReader (System.in));
System.out.println ("Hola, como te llamas? ");
cadena = linea.readLine();
System.out.println ("Encantado de conocerte, " + cadena);
System.out.println ("Cuantos aos tienes? ");
edad = Integer.parseInt (linea.readLine());
edad = edad+3;
ao = ao+3;
cadena2 = cadena+", en algun momento de "+ao+" tendrs "+edad+" aos";
System.out.println (cadena2);
System.out.println (cadena);
}
}
Las dos estructuras restantes suponen una ejecucin no lineal del conjunto de
sentencias respecto al orden en que aparecen escritas en el programa. Son las estructuras
alternativa y repetitiva (o iteracin).
ESTRUCTURAS DE DATOS INTRODUCCIN A LA PROGRAMACIN 13
Ejemplo:
El siguiente programa informa al usuario de la paridad de un nmero entero
introducido por el teclado.
import java.io.*;
Operador condicional
El operador condicional ?: se puede usar como abreviatura de la sentencia if, cuya
sintaxis es:
expresionCondicional ? expresionSI : expresionNO;
minimo = x <= y ? x : y;
18
Se consideran los siguientes casos particulares:
<grupo de sentencias> puede ser una nica sentencia, y no haran falta las llaves ({ y }).
Se puede omitir else: el ordenador no realizara ninguna accin y ejecutara la siguiente sentencia.
14 INTRODUCCIN A LA PROGRAMACIN ESTRUCTURAS DE DATOS
switch (<variable>) {
case <valor1>:
<grupo de sentencias1;>
break;
.
case <valorN>:
<grupo de sentenciasN;>;
break;
default
<grupo de sentenciasD;>
break;
}
Ejemplo:
El programa siguiente espera recibir desde el teclado un dgito, entre 1 y 7,
correspondiente al ordinal del da de la semana (lunes a domingo) y mostrar por la
pantalla el literal del da asociado o un mensaje de error si el cdigo no es vlido.
import java.io.*;
//Ejemplo de alternativa multiple.
public class PruebaSwitch {
public static void main (String [ ] args) throws NumberFormatException,
IOException {
BufferedReader linea = new BufferedReader (new InputStreamReader
(System.in));
System.out.print ("Opcion: ");
int opc = Integer.parseInt (linea.readLine ());
switch (opc) {
case 1: System.out.println ("lunes");
break;
case 2: System.out.println ("martes");
break;
case 3: System.out.println ("miercoles");
break;
case 4: System.out.println ("jueves");
break;
case 5: System.out.println ("viernes");
break;
case 6: System.out.println ("sabado");
break;
case 7: System.out.println ("domingo");
break;
default: System.out.println ("opcion no valida");
break;
}
}
}
ESTRUCTURAS DE DATOS INTRODUCCIN A LA PROGRAMACIN 15
Ejemplo:
import java.io.*;
//Ejemplo de bucle for.
public class PruebaFor {
public static void main(String[] args) throws NumberFormatException,IOException{
int i, dato, cuadrado;
BufferedReader linea = new BufferedReader (new InputStreamReader (System.in));
for (i = 1; i <= 5; i ++) {
System.out.print ("Numero: ");
dato = Integer.parseInt (linea.readLine ());
cuadrado = dato * dato;
System.out.println ("El cuadrado de " + dato + " es: " + cuadrado);
}
}
}
19
En consecuencia, podra ser que el bloque de cdigo pudiera no ejecutarse ninguna vez.
16 INTRODUCCIN A LA PROGRAMACIN ESTRUCTURAS DE DATOS
Ejemplo:
El siguiente programa ejecuta reiteradamente el ejemplo de los das de la
semana, salvo que el usuario teclee 0 como opcin20.
import java.io.*;
//Ejemplo de bucle while.
public class PruebaWhile {
public static void main (String [] args) throws NumberFormatException,
IOException {
int opc;
BufferedReader linea = new BufferedReader (new InputStreamReader
(System.in));
System.out.print ("Opcin: ");
opc = Integer.parseInt (linea.readLine());
while (opc != 0) {
switch (opc) {
case 1: System.out.println ("lunes");
break;
case 2: System.out.println ("martes");
break;
case 3: System.out.println ("miercoles");
break;
case 4: System.out.println ("jueves");
break;
case 5: System.out.println ("viernes");
break;
case 6: System.out.println ("sabado");
break;
case 7: System.out.println ("domingo");
break;
default: System.out.println ("opcin no valida");
break;
}
System.out.print ("Opcin: ");
opc = Integer.parseInt (linea.readLine ());
}
}
}
20
Pruebe a ejecutarlo introduciendo la primera vez la opcin 0.
21
En consecuencia, la ejecucin del bloque tiene lugar, al menos, una vez.
ESTRUCTURAS DE DATOS INTRODUCCIN A LA PROGRAMACIN 17
Ejemplo:
El programa siguiente constituye una variante del ejemplo anterior en el que
el bloque de cdigo se ejecuta una vez y volver a repetirse reiteradamente, o
no, hasta que el usuario teclee 0 como opcin22.
import java.io.*;
//Ejemplo de bucle do ... while.
public class PruebaDoWhile {
public static void main (String [] args) throws NumberFormatException,
IOException {
int opc = 7;
BufferedReader linea=new BufferedReader (new InputStreamReader (System.in));
System.out.println("Empezamos en domingo");
do {
switch (opc) {
case 1: System.out.println ("lunes");
break;
case 2: System.out.println ("martes");
break;
case 3: System.out.println ("miercoles");
break;
case 4: System.out.println ("jueves");
break;
case 5: System.out.println ("viernes");
break;
case 6: System.out.println ("sabado");
break;
case 7: System.out.println ("domingo");
break;
default: System.out.println ("opcin no valida");
break;
};
System.out.print ("Opcin: ");
opc = Integer.parseInt (linea.readLine ());
} while (opc != 0);
}
}
22
Pruebe a ejecutarlo introduciendo la primera vez la opcin 0.
18 INTRODUCCIN A LA PROGRAMACIN ESTRUCTURAS DE DATOS
Cualquier producto de Ingeniera (desde un barco hasta una central nuclear, pasando
por una catedral) se concibe como un sistema complejo constituido por un conjunto de
subsistemas ms sencillos, y as sucesivamente hasta acabar en piezas indivisibles.
Cuando hemos hablado antes de programacin modular lo hemos hecho desde una
perspectiva de disciplina mental. Por supuesto que la tecnologa proporciona un
importante conjunto de facilidades para dar soporte a tales concepciones. Aunque su
explicacin pormenorizada queda fuera de los objetivos y alcance de este curso, citaremos,
simplemente, a grandes rasgos las principales variantes:
23
Internet es una fuente casi inagotable donde obtener este tipo de recursos.
ESTRUCTURAS DE DATOS INTRODUCCIN A LA PROGRAMACIN 19
Memoria libre
Subprograma (mdulo)
<retorno
Zona de datos > Zona de
algoritmo
-----------
-----------
<Llamada>
-----------
Programa principal
-----------
Figura 1.5. Gestin de la memoria en programas modulares-.
Este tipo de gestin de memoria se denomina esttica26 porque durante todo el tiempo
de ejecucin tanto el programa principal como la totalidad de mdulos estn cargados en
memoria, alojados en espacios independientes.
A su vez, cada uno de los espacios se subdivide en otros dos: zona de datos y zona de
algoritmo (la parte de cdigo -previamente traducido a lenguaje de mquina-).
La ejecucin del conjunto tiene lugar a partir de la primera instruccin del programa
principal. Cuando se llega a una <llamada> se suspende y se pasa al contexto del
24
La mayora de entornos de programacin modernos contemplan el concepto de proyecto en donde se indica
el conjunto de mdulos que configuran el sistema y sus ubicaciones. En el curso, dado su carcter bsico, no
utilizaremos esta posibilidad.
25
Se entiende por aplicacin principal a la parte de cdigo (generalmente poco extensa) que utiliza (llama o
invoca) los diferentes mdulos funcionales.
26
Las alternativas ms evolucionadas son de naturaleza dinmica: el bloque correspondiente al programa
principal est permanentemente en memoria mientras que los subprogramas se cargan cuando se necesitan y
al finalizar su ejecucin se libera la memoria ocupada. No obstante esta tcnica es la nica posible cuando se
utiliza el tratamiento recursivo (ver apartado 1.2.5.5)
20 INTRODUCCIN A LA PROGRAMACIN ESTRUCTURAS DE DATOS
Por valor. La variable del subprograma recibe inicialmente una copia del valor
almacenado, en el momento de producirse la llamada, en el mdulo principal.
Durante su ejecucin (del subprograma) podr modificarlo pero una vez que
finalice, el programa principal conserva intacto su valor. En Java todos los tipos
primitivos (nmeros enteros, reales, caracteres y booleanos) se pasan siempre por
valor.
Por referencia. En este caso no existe tal variable en el mbito del subprograma. El
mecanismo consiste en que el mdulo principal permite al subprograma actuar
sobre sus propias variables. En consecuencia, cualquier modificacin que se
realice en una variable pasada por referencia tendr efecto en el contexto del
programa (mdulo) principal. En Java todos los datos que no sean de un tipo
primitivo se pasan por valor, pero al ser referencias, los datos en s pueden cambiar
(pero no la posicin de memoria en la que estn guardados).
27
Lo que se explica en el apartado debe entenderse con carcter general. El lenguaje Java solo
admite el paso de argumentos por valor. Esta afirmacin es extensiva al caso de que el argumento sea un
objeto (por ejemplo, un vector) dado que lo que se pasa como argumento por valor es un puntero (referencia)
a dicho objeto que no puede ser modificado por el mdulo subordinado (aunque s el propio objeto).
28
No hay ningn inconveniente en que dos variables locales de mdulos diferentes tengan el mismo
nombre.
29
Una modificacin de una variable global realizada por un mdulo afectar al resto.
30
En este caso si habra ambigedad en caso de coincidencia de nombres de una variable local y otra
global. Esto no supone ningn error de compilacin y la ejecucin podra producir resultados no esperados (ni
deseados).
31
No tiene sentido pasar como argumentos variables globales. Ya estn accesibles desde todos los
mdulos.
ESTRUCTURAS DE DATOS INTRODUCCIN A LA PROGRAMACIN 21
Los nombres de los argumentos son formales. No tienen por qu coincidir con los
nombres reales de las variables utilizadas en la llamada al mtodo32. El compilador solo
verifica que las listas de argumentos empleadas en la llamada (reales) y en la cabecera
(formales) coinciden en nmero, tipo y orden.
Las sintaxis de las llamadas es similar a la de las cabeceras, si bien en este caso se
utiliza una versin reducida de la <lista de argumentos> en la que solo aparecen sus
nombres (reales), separados por comas.
El mtodo est delimitado por las llaves de inicio y fin de bloque ({ y }), y a
continuacin aparece la declaracin de variables locales del subprograma y el algoritmo.
Los mtodos que no sean de tipo void deben acabar con la siguiente sentencia:
return <variableDeTrabajo>;
32
El hacerlo as permite que los subprogramas sean reutilizables.
22 INTRODUCCIN A LA PROGRAMACIN ESTRUCTURAS DE DATOS
Dado que el lenguaje Java solo admite el paso de argumentos por valor no es posible
que el modulo subordinado modifique una variable del mdulo de llamada (salvo que se
trate del valor devuelto por el mtodo). En tales situaciones optamos por crear una clase
esttica que declare dicha variable como global de la clase (lo que no contraviene la
recomendacin general de no utilizar variables globales)33 por lo que carecera de sentido
pasarla como argumento.
Sintaxis Semntica
import <nombre> Llamada a una (o varias) componente(s) de la biblioteca.
public class <nombre de la clase general> Nombre de la clase general (obligatorio)
{ Principio de la clase.
......
public static void main (String [ ] args) Declaracin del programa principal
{ Inicio del programa principal
33
Algunos programadores optan por la alternativa de declarar dicha variable como vector (objeto) y pasar el
puntero (referencia) correspondiente como argumento (por valor).
ESTRUCTURAS DE DATOS INTRODUCCIN A LA PROGRAMACIN 23
1.3.4.1. Ejemplo.
El siguiente programa pide al usuario una serie de cinco nmeros enteros y muestra
por la pantalla dos de sus estadsticas: valor medio y rango.
import java.io.*;
public class PruebaMetodos {
static float media (int dato1, int dato2, int dato3, int dato4, int dato5) {
float resul;
resul = (dato1 + dato2 + dato3 + dato4 + dato5) / 5;
return resul;
}
static int max (int dato1, int dato2, int dato3, int dato4, int dato5) {
int resul;
resul=dato1;
if (dato2 > resul)
resul = dato2;
if (dato3 > resul)
resul = dato3;
if (dato4 > resul)
resul = dato4;
if (dato5 > resul)
resul = dato5;
return resul;
}
static int min (int dato1, int dato2, int dato3, int dato4, int dato5) {
int resul;
resul = dato1;
if (dato2 < resul)
resul = dato2;
if (dato3 < resul)
resul = dato3;
if (dato4 < resul)
resul = dato4;
if (dato5 < resul)
resul = dato5;
return resul;
}
public static void main(String[] args) throws NumberFormatException,IOException{
int d1, d2, d3, d4, d5, rango;
float media;
BufferedReader linea = new BufferedReader(new InputStreamReader(System.in));
System.out.println ("Introduce cinco nmeros enteros: ");
d1 = Integer.parseInt (linea.readLine ());
d2 = Integer.parseInt (linea.readLine ());
d3 = Integer.parseInt (linea.readLine ());
d4 = Integer.parseInt (linea.readLine ());
d5 = Integer.parseInt (linea.readLine ());
media = media (d1, d2, d3, d4, d5);
System.out.println("El valor medio es: " + media);
rango = max (d1, d2, d3, d4, d5) - min (d1, d2, d3, d4, d5);
System.out.println ("y el rango: " + rango);
}
}
24 INTRODUCCIN A LA PROGRAMACIN ESTRUCTURAS DE DATOS
1.3.5. Recursividad.
1.3.5.1. Concepto.
Se define objeto recursivo como: aquel que forma parte de s mismo o que forma
parte de su propia definicin.
34
Un ejemplo en este sentido sera el clsico algoritmo denominado Torres de Hanoi.
35
En caso de un nmero elevado de llamadas recursivas es posible quedarse sin espacio libre en memoria y se
produce un error en tiempo de ejecucin (StackOverflowError).
ESTRUCTURAS DE DATOS INTRODUCCIN A LA PROGRAMACIN 25
import java.io.*;
public class PruebaRecursividad {
static int factorial (int dato) {
int resul = 1;
if (dato > 0)
resul = dato * factorial (dato - 1);
return resul;
}
public static void main(String[] args) throws NumberFormatException,IOException{
int d, f;
BufferedReader linea = new BufferedReader (new InputStreamReader(System.in));
System.out.print("Introduzca el dato: ");
d = Integer.parseInt (linea.readLine ());
if (d >= 0) {
f = factorial(d);
System.out.println("El factorial de " + d + " es: " + f);
}
else System.out.println("No existe el factorial de un nmero negativo");
}
}
Explicacin:
El programa principal llama al subprograma factorial y le pasa como argumento la
variable d. Cuando ste termine de ejecutarse, el programa de llamada dispondr de
un resultado que podr mostrar por la pantalla.
El subprograma factorial es recursivo.
o Su condicin de terminacin es dato == 0. En la instancia en que se alcance36
(transicin) devolver el valor 1.
o Durante la fase de ida, la ejecucin de cada instancia consiste en multiplicar
el valor del argumento recibido desde la instancia anterior (salvo la primera,
que lo recibe directamente del programa principal) por el factorial del nmero
anterior (factorial(N-1)). La ejecucin de esa instancia queda suspendida hasta
que se le devuelva el valor solicitado.
o En la fase de vuelta cada instancia:
Multiplica el valor devuelto por la instancia siguiente por el que, en su
momento de la fase de ida, recibi como argumento,
36
Su nmero de orden ser uno ms que el dato cuyo factorial se quiere calcular.
26 INTRODUCCIN A LA PROGRAMACIN ESTRUCTURAS DE DATOS
37
En algunos casos la terminacin anticipada es necesaria para el correcto funcionamiento del programa
mientras que en otros, aunque el programa funcione se debe usar por consideraciones de eficiencia.
ESTRUCTURAS DE DATOS INTRODUCCIN A LA PROGRAMACIN 27
1.3.5.4. Ejemplos.
El diseador del programa principal no tiene por qu saber que se necesitan otros
argumentos adicionales al dato (d), sin embargo, el subprograma recursivo realmente
necesita otro argumento (presuntoDivisor, de tipo entero), para probar recursivamente
desde 2 hasta d/2 y controlar la terminacin (pesimista).
Ejemplo 2. (Terminacin anticipada).
El siguiente ejemplo consiste en una funcin booleana (esPrim) que indica si un
nmero (d) que se introduce desde el teclado es primo (true) o no (false).
import java.io.*;
public class Recursividad3 {
static boolean esPrim (int dato, int presuntoDivisor) {
boolean resul;
if ((presuntoDivisor*presuntoDivisor) <= dato)
if ((dato % presuntoDivisor) != 0)
resul = esPrim (dato, presuntoDivisor+1);
else resul = false;
else resul = true;
return resul;
}
public static class Suma {
static int numeroFactores = 0; //variable global de la clase Suma
static int sumaPrimos (int dato, int presuntoPrimo) {
int resul, orden;
if ((presuntoPrimo * 2) <= dato)
if ((dato % presuntoPrimo) == 0)
if (esPrim (presuntoPrimo, 2)) {
numeroFactores= numeroFactores + 1;
orden = numeroFactores;
resul = sumaPrimos(dato, presuntoPrimo + 1);
if ((numeroFactores% 2) == 0) {
if (orden <= (numeroFactores / 2))
resul = resul + presuntoPrimo;
}
else {
if (orden > ((numeroFactores / 2) + 1))
resul = resul + presuntoPrimo;
}
}
else resul = sumaPrimos (dato, presuntoPrimo + 1);
else resul = sumaPrimos (dato, presuntoPrimo + 1);
else resul = 0;
return resul;
}
static int sumaPrimosCondicionada (int dato) {
int resul;
resul = sumaPrimos (dato, 2);
return resul;
}
}
public static void main(String[] args) throws NumberFormatException,IOException{
int d, suma;
BufferedReader linea = new BufferedReader (new InputStreamReader(System.in));
do {
System.out.print("Introduzca un nmero mayor que cero: ");
d = Integer.parseInt (linea.readLine());
} while (d <= 0);
suma = Suma.sumaPrimosCondicionada (d);
System.out.println ("El resultado es: " + suma);
}
}
primos, por lo que no se sabe qu hay que sumar. La parte de proceso que se realiza
en ella consiste en:
o Identificar si un nmero (argumento presuntoPrimo, pasado por valor) es
primo y factor de d.
En caso negativo se realiza una nueva llamada recursiva con
presuntoPrimo+1.
En caso afirmativo:
Se contabiliza en la variable numeroFactores global dentro de la clase
Suma, inicializado a 0 (pues se utilizar su valor final en la fase de
vuelta).
Se toma nota del nmero de orden (orden) del factor primo
encontrado (variable local que recoge el valor actual de
numeroFactores)38.
38
En las instancias correspondientes a valores de presuntoPrimo que no son factores primos el valor de la
variable orden es aleatorio
39
Vamos marcha atrs.
ESTRUCTURAS DE DATOS INTRODUCCIN A LA PROGRAMACIN 31
import java.io.*;
Las estructuras de datos pueden ser homogneas (todos los datos son del mismo tipo)
o heterogneas (constituidas por datos de tipos diferentes).
Las estructuras de datos homogneas ms representativas son los vectores, las tablas
y, en general, las matrices n-dimensionales. El ejemplo ms representativo de estructuras
de datos heterogneas son los registros
Se dice que una estructura de datos es dinmica cuando inicialmente (en el momento
de la compilacin) no tiene espacio asignado para almacenar informacin. Durante la
ejecucin del programa el sistema (en tiempo de ejecucin, run time) asigna y libera
espacio en memoria, en funcin de las necesidades.
40
Este concepto toma su suporte fsico en el mecanismo de direccionamiento indirecto tal como se maneja en
los lenguajes de bajo nivel.
ESTRUCTURAS DE DATOS INTRODUCCIN A LA PROGRAMACIN 33
Variable de trabajo
(apuntada por puntero) Memoria
dinmica
Memoria
puntero
esttica
se declara una variable (puntVector) de tal forma que, al realizar la operacin new se
reserve el espacio necesario para almacenar un vector de 100 caracteres.
Aunque, como se ha indicado, una variable de tipo puntero apunta a una zona de
memoria (nodo) existe una situacin excepcional consistente en no apuntar a ninguno. En
Java se utiliza para esto la constante null.
Sobre las variables referencia, se realizan las operaciones propias del tipo de datos a
que pertenezcan.
41
Este tipo de operaciones deber hacerse con especial cuidado pues, si no se han tomado previamente las
precauciones oportunas, podra perderse la informacin almacenada en el nodo inicialmente apuntado por
<puntero1> (se perder si no tenemos otra referencia a esa informacin)
ESTRUCTURAS DE DATOS INTRODUCCIN A LA PROGRAMACIN 35
En las estructuras de datos homogneas todos los datos son del mismo tipo. Como
ejemplo veremos los vectores, las tablas y, en general, las matrices n-dimensionales.
Declara una variable llamada vector1 que es un vector de enteros inicialmente vaco.
Para indicar el tamao del vector, se puede hacer directamente en la propia lnea de
declaracin:
Int [] vector1 = new int [5]; //declara un vector de 5 elementos de tipo entero.
Acceso:
o Al conjunto. Por ejemplo asignar un vector a otro del mismo tipo:
vector2 = vector1.
En realidad esta instruccin no copia el contenido de vector1 en vector2, sino que
hace que vector2 apunte a la misma posicin de memoria en la que est el vector1.
o A un elemento del vector:
<variable_tipo_vector> [<ndice>];
42
En Java el ndice es numrico y siempre comienza en 0.
43
Se describen solamente las operaciones bsicas. El manejo de este tipo de estructuras admite una gran
flexibilidad. Consultar el manual del lenguaje para mayor informacin.
36 INTRODUCCIN A LA PROGRAMACIN ESTRUCTURAS DE DATOS
Con lo que se podr realizar cualquier operacin acorde con el tipo del elemento
correspondiente. Por ejemplo, si datos es un vector de nmeros enteros podramos hacer:
datos [3] = datos [3] * 2;
Ejemplo.
A continuacin se retoma el ejemplo expuesto en el apartado 1.3.4.1 (valores medio y
rango de un conjunto de 5 nmeros enteros) utilizando un vector.
import java.io.*;
public class PruebaVectores {
static float media (int [ ] dato) {
float resul = 0;
int i;
for (i = 0; i < 5; i ++)
resul = resul + dato [i];
resul = resul / i;
return resul;
}
static int max (int [] dato) {
int resul,i;
resul = dato[0];
for (i = 1; i<5; i++)
if (dato[i] > resul)
resul = dato[i];
return resul;
}
static int min (int [] dato) {
int resul,i;
resul = dato[0];
for (i = 1; i < 5; i ++)
if (dato [i] < resul)
resul = dato [i];
return resul;
}
public static void main(String [] args)throws NumberFormatException,IOException{
int [ ] d = new int [5];
int i, rango;
float media;
BufferedReader linea = new BufferedReader(new InputStreamReader(System.in));
System.out.println ("Introduce cinco nmeros enteros: ");
for (i = 0; i < 5; i ++)
d[i] = Integer.parseInt (linea.readLine ());
media = media (d);
System.out.println ("El valor medio es: " + media);
rango = max (d) - min (d);
System.out.println ("y el rango: " + rango);
}
}
ESTRUCTURAS DE DATOS INTRODUCCIN A LA PROGRAMACIN 37
import java.io.*;
public class PruebaMatrices {
static BufferedReader linea=new BufferedReader(new
InputStreamReader(System.in));
public static void leerMatriz (int [][] temperaturas) throws
NumberFormatException, IOException{
int i,j;
for (i = 0;i < 7; i ++)
for (j = 0; j < 2; j ++) {
System.out.println ("Valor dia: " + i + " extremo: " + j + ": ");
temperaturas [i] [j] = Integer.parseInt (linea.readLine ());
}
}
public static int min (int [][] temperaturas) {
int resul, i;
resul = temperaturas [0] [0];
for (i = 1; i < 7; i++)
if (temperaturas [i] [0] < resul)
resul = temperaturas [i] [0];
return resul;
}
public static int maxDif (int [] [] temperaturas) {
int resul, i, dif;
resul = 0;
dif = temperaturas [0][1]- temperaturas [0][0];
for (i = 1; i < 7; i++) {
if (temperaturas [i][1] - temperaturas [i][0] > dif) {
dif = temperaturas [i][1] - temperaturas [i][0];
resul = i;
}
}
return resul;
}
public static void main(String[] args) throws NumberFormatException,
IOException{
int [][] temperaturas = new int [7][2];
int minimaTemperatura, diferenciaTemperaturas;
leerMatriz (temperaturas);
minimaTemperatura = min (temperaturas);
diferenciaTemperaturas = maxDif (temperaturas);
System.out.println ("Resultados:");
System.out.println ("Temperatura minima: " + minimaTemperatura);
System.out.println ("Dia extremo: " + diferenciaTemperaturas);
}
}
ESTRUCTURAS DE DATOS INTRODUCCIN A LA PROGRAMACIN 39
1.4.2.1.3. N-dimensionales.
Por extensin, lo explicado para una y dos dimensiones se puede aplicar al caso de
matrices N-dimensionales.
Como ya se ha indicado, estn constituidas por un conjunto de tipos de datos (ya sean
datos simples u otras estructuras de datos) de diferente naturaleza. La forma bsica de
estructura de datos heterognea es el registro cuyos elementos se llaman campos (o
atributos)44.
Por ejemplo, la figura siguiente muestra un registro (alumno) cuyos campos son: el
nmero de matrcula (numeroMatricula), apellidos (apellidos), nombre (nombre), direccin
de correo electrnico (eMail), ao de nacimiento (anio) y calificacin (calificacion).
Para manejar este tipo de estructuras en Java45, se construye una clase dentro de la
cual se definen los datos que van a formar parte de la estructura, as como uno o varios
constructores, como se puede ver en el siguiente ejemplo (correspondiente a la figura):
class RegistroAlumno {
public String numeroMatricula;
public String apellidos;
public String nombre;
public String eMail;
public int ao;
public float calificacion;
public RegistroAlumno (){
numeroMatricula= null;
apellidos = null;
nombre = null;
eMail= null;
ao = 1980;
calificacion = 0;
}
44
Con frecuencia uno de los campos (o combinacin de ellos) se utiliza como identificativo del registro. A
dicho campo (o conjunto) se le denomina clave (key).
45
Existen otras operaciones. Consultar el manual del lenguaje.
40 INTRODUCCIN A LA PROGRAMACIN ESTRUCTURAS DE DATOS
Acceso:
o Al conjunto. Por ejemplo apuntar con una variable de tipo registro mismo sitio
que apunta otra del mismo tipo:
variable2_RegistroAlumno = variable1_RegistroAlumno;
o A un campo del registro:
<variable>.<campo>;
Con lo que se podr realizar cualquier operacin acorde con el tipo del
elemento correspondiente. Por ejemplo: alumno.eMail = esanchez@servidor.es;
Import java.io.*;
class RegistroAlumno {
public RegistroAlumno () {
numeroMatricula= null;
apellidos = null;
nombre = null;
eMail= null;
ao = 1980;
calificacion = 0;
}
public String aCadena () {
return numeroMatricula + " " + apellidos + " " + nombre + " " + eMail +
" " + ao + " " + calificacion;
}
public String numeroMatricula;
public String apellidos;
public String nombre;
public String eMail;
public int ao;
public float calificacion;
public void cargarRegistro () throws IOException {
BufferedReader linea = new BufferedReader (new InputStreamReader (System.in));
System.out.println ("Numero de matricula: ");
numeroMatricula = new String (linea.readLine ());
System.out.println ("Apellidos: ");
apellidos = new String (linea.readLine ());
System.out.println ("Nombre: ");
nombre = new String (linea.readLine ());
System.out.println ("Correo electronico: ");
eMail = new String (linea.readLine ());
System.out.println ("Ao de nacimiento: ");
ao = Integer.parseInt (linea.readLine());
System.out.println ("Calificacin: ");
calificacion = Float.parseFloat (linea.readLine());
System.out.println (this.aCadena ());
}
}
import java.io.*;
public class PruebaRegistro {
static void cargarTabla (RegistroAlumno [ ] alumnos) throws IOException {
int i;
for (i = 0; i < 6; i++) {
System.out.println ("Datos del alumno N: "+ i);
alumnos [i].cargarRegistro ();
}
}
static float mediaCalif (RegistroAlumno [ ] alumnos) {
float resul = 0;
int i;
for (i = 0; i < 6; i++) {
System.out.println(alumnos [i].aCadena ());
resul = resul + alumnos [i].calificacion;
}
return resul/6;
}
public static void main (String [ ] args) throws IOException {
RegistroAlumno [ ] alumnos = new RegistroAlumno [6];
float media;
int i;
for (i = 0; i < 6; i++)
alumnos [i]= new RegistroAlumno ();
cargarTabla (alumnos);
media = mediaCalif (alumnos);
System.out.println ("La media de las calificaciones es: " + media);
}
}
ESTRUCTURAS DE DATOS INTRODUCCIN A LA PROGRAMACIN 43
Otro aspecto a considerar es cmo organizar las fichas dentro del dispositivo
(fichero). Con soportes tradicionales la forma de organizacin es nica (por ejemplo,
alfabtica) y secuencial (una ficha tras otra, en el orden predefinido). La Informtica ha
heredado esta idea aunque permite otras modalidades de organizacin y modos de acceso
adicionales a los puramente nicos y secuenciales.
En un fichero de texto, cada una de sus fichas consiste en una cadena de caracteres
de longitud variable (lneas de texto). Las fichas se almacenan una tras otra sin mantener
ningn criterio de orden entre s. Por ejemplo (marsell.txt):
Entre cada una de las lneas existen cdigos invisibles cuyo efecto es hacer saltar al
inicio de la lnea siguiente. Estos cdigos se generan automticamente al pulsar la tecla
Intro. As mismo, para indicar el final del fichero de texto, el usuario deber haber
pulsado la tecla de funcin F6.
46
Este concepto est heredado de los antiguos ficheros (o archivadores) que contenan fichas (de papel)
cada una de las cuales representaba una informacin unitaria: ficheros de pelculas, personas, asignaturas.
44 INTRODUCCIN A LA PROGRAMACIN ESTRUCTURAS DE DATOS
import java.io.*;
public class prueba_fichero_texto {
lineaLeida public static void main(String[] args) throws IOException {
FileWriter fich_s = new FileWriter ("archivo.txt");
Marse.txt BufferedWriter bw = new BufferedWriter (fich_s);
PrintWriter salida = new PrintWriter (bw);
BufferedReader linea = new BufferedReader (new
InputStreamReader(System.in));
String lineaLeida;
System.out.println ("Escriba la primera linea: ");
lineaLeida = new String (linea.readLine());
salida.println (lineaLeida);
System.out.println ("Escriba la segunda linea: ");
lineaLeida = new String (linea.readLine());
salida.println (lineaLeida);
salida.close();
}
}
47
La ruta, nombre y extensin del fichero se eligen libremente (con las restricciones propias del sistema
operativo). En el ejemplo se han utilizado:
Ruta: (por omisin) la misma que el programa.
Nombre: archivo.
Extensin txt (para poder visualizarlo mediante el bloc de notas notepad- de Windows).
ESTRUCTURAS DE DATOS INTRODUCCIN A LA PROGRAMACIN 45
import java.io.*;
public class PruebaFicheroSalida {
El programador no es consciente del fichero fsico con que est trabajando. Se crea
un nombre simblico (por ejemplo fich_s), y sobre l se realizan todas las
operaciones48. Slo existe una excepcin, la sentencia:
FileWriter fich_s = new FileWriter ("archivo.txt");
establece una vinculacin entre el nombre fsico del fichero y el nombre lgico.
Se utiliza una variable de tipo String (en el ejemplo: lineaLeida) como puente
entre la memoria del ordenador y el dispositivo de almacenamiento (disco). Segn
sea el sentido de la transferencia se puede hablar de lectura: disco memoria
(readline) o de escritura memoria disco (println).
Hay que preparar el fichero en disco para utilizarlo (apertura) y dejarlo disponible
para posteriores usos (cierre).
1.5.1.2. Sintaxis de las principales operaciones relacionadas con los ficheros de texto49.
Proceso:
o Leer (transferir a la variable correspondiente) el contenido de una lnea del
fichero y prepararse para la siguiente.
<variable tipo String> = <buffer lectura>.readline();
o Escribir (transferir) el contenido de una lnea (<expresin tipo String>) al
fichero y prepararse para la siguiente:
<variable>.println = <expresin tipo String>;
48
Dicho fichero estar gestionado por el sistema operativo. Con frecuencia se cambia de ubicacin los
ficheros (fsicos) y de no seguir esta filosofa, esto implicara re-escribir parte del cdigo cada vez que un
fichero cambiase de ubicacin.
49
Para mayor informacin consultar el manual de programacin.
ESTRUCTURAS DE DATOS INTRODUCCIN A LA PROGRAMACIN 47
Terminacin:
o Dejar el fichero preparado para usos posteriores:
<variable>.close ();
Por ejemplo, si queremos leer un fichero hasta llegar al final lo podemos hacer
utilizando lo siguiente:
import java.io.*;
public class PruebaFicheroEntrada {
public static void main (String [ ] args) throws IOException {
String lineaLeida;
FileReader fichLeido = new FileReader ("archivo.txt");
BufferedReader entrada = new BufferedReader (fichLeido);
Para poder guardar objetos (por ejemplo, del tipo RegistroAlumno visto en apartados
anteriores) en un fichero hay que hacerlos serializables. Mediante la serializacin, un
objeto se convierte en una secuencia de bytes con la que se puede reconstruir
posteriormente manteniendo el valor de sus variables. Esto permite guardar un objeto en un
archivo o mandarlo por red. Una clase se serializa aadiendo en su definicin:
implements Serializable
Para poder leer y escribir objetos que se han declarado como serializables se utilizan
las clases ObjectInputStream y ObjectOutputStream, que cuentan con los mtodos
writeObject() y readObject().
50
Ver apartado 1.4.2 Estructuras de datos heterogneas.
48 INTRODUCCIN A LA PROGRAMACIN ESTRUCTURAS DE DATOS
51
Por simplicidad no se han considerado situaciones excepcionales (por excepcin). Por ejemplo:
No tiene sentido utilizar la opcin [2]: Cargar tabla de registros, si no existe el fichero en disco.
Tampoco lo tiene utilizar la opcin [3]: Calcular calificacin media, si no se ha ejecutado (con xito)
previamente la opcin [2].
ESTRUCTURAS DE DATOS INTRODUCCIN A LA PROGRAMACIN 49
Inicio
menu
Mdulo
Fin
principal op
import java.io.*;
public class PruebaFichES {
static void crearFichero (RegistroAlumno [ ] alumnos, String nombref) throws
IOException {
int i;
FileOutputStream fich = new FileOutputStream (nombref);
ObjectOutputStream objEscrito = new ObjectOutputStream (fich);
for (i = 0; i < 6; i++) {
alumnos [i] = new RegistroAlumno();
System.out.println ("Datos del alumno N: "+ i);
alumnos [i].cargarRegistro ();
objEscrito.writeObject (alumnos [i]);
}
fich.close ();
}
static void cargarTabla (RegistroAlumno [ ] alumnos, String nombref) throws
IOException, ClassNotFoundException {
int i;
FileInputStream fich =new FileInputStream (nombref);
ObjectInputStream objLeido = new ObjectInputStream (fich);
resul = 0;
for (i = 0; i < 6; i++) {
System.out.println (alumnos [i].aCadena ());
resul = resul + alumnos [i].calificacion;}
return resul/6;
}
TEMA 1. ....................................................................................................................... 1