REGISTROS
Definición: Es un tipo de dato estructurado constituido por un conjunto de elementos
individuales (datos) que pueden ser de diferentes tipos.
Los elementos de un registro se pueden utilizar como cualquier otra variable de tipo simple. Se
relaciona concatenando, mediante un punto, el nombre del dato con el del registro.
Ejemplo:
DATOS
miVehiculo: Vehículo (miRegistro:NombreRegistro)
TIPOS
Vehículo: Registro (NombreRegistro:Registro)
numeroChasis: String
numeroMotor: String
color: String
modelo: String
marca: String
anio: Entero
FinRegistro
Si queremos guardar ahora toda la información que teníamos, pero usando esta vez la variable
“miVehiculo” de tipo “Vehículo” hacemos:
miVehiculo.modelo = “Hilux”
miVehiculo.marca = “Toyota”
ARREGLOS
Un arreglo (ARRAY) es una estructura de datos compuesta que permite acceder a cada
componente por una variable índice, que da la posición del elemento dentro de la estructura
de datos. Es una colección de elementos que se guardan consecutivamente en la memoria y se
pueden referenciar a través de un índice.
Tipos: Vectores, matrices y tensores.
Características:
Homogéneo: Los elementos almacenados en la estructura son todos
del mismo tipo y además deben ser estáticos.
Estática: El tamaño de la estructura se conoce en el momento de la
declaración.
Indexada: Para acceder a cada elemento de la estructura se debe
utilizar una variable “índice” que es de tipo ordinal.
Declaración:
TIPO
NombredelArreglo = tipodeElemento array [dimensión]
Los tipodeElemento puede ser: Integer, char, boolean, real, String, Registro, otro
arreglo.
Ejemplo:
TIPO
numero = real array [10]
DATOS
num:números
ALGORITMOS DE BÚSQUEDA
Los procesos de búsqueda involucran recorrer un arreglo completo con el fin de encontrar
algo. Comúnmente se desea encontrar el menor o el mayor elemento del arreglo o buscar la
posición de un elemento determinado.
Búsqueda LINEAL: Se utiliza para obtener el mayor o menor elemento de un arreglo,
cuyos elementos no estén ordenados.
Implica recorrer todos y cada uno de los elementos del arreglo, partiendo de la suposición de
que el primero o el último de los elementos del arreglo es el mayor o el menor, para luego ir
comparando con cada uno de los demás elementos e ir actualizando según el caso.
Búsqueda SECUENCIAL: Consiste en ir comparando secuencialmente el elemento que
se busca con cada elemento del arreglo hasta encontrarlo o llegar al final del arreglo.
Ejemplo: Datos de entrada:
vector: vector en el que se desea buscar el dato.
tamaño: tamaño del vector.
dato: elemento que se quiere buscar.
Variables:
pos: posición actual en el vector.
encontrado: posición del elemento buscado.
encontrado = -1
pos = 0
Mientras (pos<tamaño) y (encontrado == -1)
si (vector[pos] == dato)
encontrado = pos
sino
pos = pos + 1
fin mientras
Retornar encontrado
Búsqueda BINARIA: Requiere que el arreglo esté ordenado. Compara si el valor
buscado está potencialmente en la primera mitad del arreglo o en la segunda. La mitad en la
que potencialmente esté es subdividida nuevamente, y así sucesivamente hasta encontrar el
valor.
Ejemplo: Datos de entrada:
vector: vector ordenado en el que se desea buscar el dato.
tamaño: tamaño del vector.
dato: elemento que se quiere buscar.
Variables:
I: posición izquierda en el vector.
r: posición derecha en el vector.
m: posición media.
encontrado: posición del elemento buscasdo.
encontrado = -1
I=0
r = (tamaño - 1)
Repetir
m = (I + r)/2
Si (vector[m]< = dato)
I = m-1
sino
r=m–1
hasta (I > r)
Si (vector[m] == dato)
encontrado = m
fin si
retornar encontrado
Búsqueda BIDIMENSIONAL: Si tenemos que buscar un elemento, debemos recorrer
todos los elementos de la matriz. Se requieren dos repeticiones anidadas, una por las filas y
otra por las columnas.
Ejemplo: Datos de entrada:
matriz: matriz sobre la cual buscar el valor máximo y mínimo.
filas: número de filas.
columnas: número de columnas.
Variables:
max: el valor máximo.
min: el valor mínimo.
i, j: índices para recorrer la matriz.
max = -1000
min = 1000
Repetir con i desde 0 hasta filas - 1
Repetir con j desde 0 hasta columnas - 1
Si (matriz[i][j] > max)
max = matriz[i][j]
Si (matriz[i][j] < min)
min = a[i][j]
Imprimir max, min
ALGORITMOS DE ORDENAMIENTO
Es un algoritmo que pone elementos de un arreglo en una secuencia dada por una relación de
orden, es decir, el resultado de salida ha de ser una permutación o reordenamiento de la
entrada que satisfaga la relación de orden dada.
Ordenamientos ITERATIVOS:
Burbuja o Bubble Sort
Inserción o Insertion Sort
Selección (mejora del Bubble)
Shell Sort (generalización del Insertion)
Burbuja: es uno de los más simples, consiste en verificar cada elemento del arreglo,
intercambiándolos de posición si están en orden equivocados. Es necesario revisar varias veces
toda la lista hasta que no se necesiten más intercambios.
Datos de entrada:
vec: vector que se desea ordenar.
tam: tamaño del vector.
Variables:
temp: variable temporal.
i, j: usadas para iterar.
Algoritmo:
Repetir desde i = 1 hasta tam
Repetir desde j = 0 hasta tam – i
Si vec [j] > vec [j + 1]
temp = vec [j]
vec [j] = vec [j + 1]
vec [j + 1] = temp
Fin
Inserción: Inicialmente se tiene un solo elemento, que es un conjunto ordenado.
Después, cuando hay K elementos ordenados de menor a mayor, se tomar el elemento k+1 y
se compara con todos los elementos ya ordenados, deteniéndose cuando se encuentra un
elemento menor (los elementos mayores se desplazan hacia la derecha) o cuando ya no se
encuentran elementos. En este punto se inserta el elemento k+1 debiendo desplazarse los
demás elementos.
Datos de entrada:
vec: vector que se desea ordenar.
tam: tamaño del vector.
Variables:
copia: variable temporal.
i, j: usadas para iterar.
Algoritmo:
Repetir desde i = 0 hasta tam
copia = vec [i]
j=i
Mientras j > 0 y copia < vec [j – 1]
vec [j] = vec [j - 1]
j=j-1
vec [j] = copia
Fin
RECURSIÓN
Es un algoritmo que expresa la solución de un problema en términos de una llamada así
mismo.
Se utiliza para realizar una llamada a una FUNCIÓN desde ella misma.
Solución a un problema X, en función de instancias más “pequeñas”, del mismo problema.
Características: Cuando se construye una solución recursiva se deben tener en cuenta:
Como definir el problema en términos de un problema mas pequeño del mismo tipo.
Como será disminuido el tamaño del problema en cada llamado recursivo.
Que instancia del problema servirá como CASO BASE.
CASO BASE:
Permiten frenar el proceso recursivo.
Conocemos el valor de lo que queremos calcular.
ORDENAMIENTO RECURSIVO
QuickSort: Divide al vector en dos partes que se ordenan recursivamente. Se puede resumir en
tres pasos.
1. Escoger un elemento de Pivote.
2. Particionar el vector en dos, una cuyos elementos son menores que el pivote y otra
cuyos elementos sean mayores.
3. Ordenar cada partición de manera recursiva con QuickSort.
PROCEDIMIENTO QuickSort (v: vector; izquierdo, derecho: Entero)
DATOS
posicionPivote : Entero
COMENZAR
posicionPivote = particionar(v, izquierdo, derecho)
Si (izquierdo >= derecho) //No hacer nada, intervalo ya ordenado
Sino
Si (izquierdo < posicionPivote – 1)
QuickSort(v, izquierdo, posicionPivote - 1)
Si (derecho > posicionPivote)
QuickSort(v, posicionPivote, derecho)
FIN
FUNCION Particionar(v: vector, izquierdo: Entero, derecho: Entero): Entero
DATOS valorPivote, temporal: Entero
COMENZAR
valorPivote = v[ (izquierdo + derecho) / 2 ]
Mientras (izquierdo <= derecho)
Mientras (v[izquierdo] < valorPivote)
izquierdo++
Mientras (v[derecho] > valorPivote)
derecho--
Si (izquierdo <= derecho)
temporal = v[izquierdo]
v[izquierdo] = v[derecho]
v[derecho] = temporal
izquierdo ++
derecho --
Particionar = izquierdo
FIN
MergeSort: Es un algoritmo recursivo para ordenar los elementos de un vector.
1. Se divide el vector en 2 partes iguales.
2. Se ordenan las dos partes recursivamente.
3. Se combinan las dos partes ordenadas para obtener el resultado.
PROCEDIMIENTO MergeSort(v: vector, izq: Entero, der: Entero)
DATOS
medio: Entero
COMENZAR
Si (der > izq)
medio = (der + izq) / 2
MergeSort(v, izq, medio)
MergeSort(v, medio+1, der)
MergeSort = Combina(v, izq, (medio + 1), der)
FIN
PROCEDIMIENTO Combina (v : vector, izq: Entero, med: Entero, der: Entero)
DATOS
temp: vector
izq_fin, num_elementos, tmp_pos: Entero
COMENZAR
izq_fin = (med - 1)
tmp_pos = izq
num_elementos = (der - izq + 1)
Mientras ((izq <= izq_fin) AND (med <= der))
Si (v [izq] <= v [med])
temp[tmp_pos++] = v [izq++]
Sino
temp[tmp_pos++] = v [med++]
Mientras (izq <= izq_fin)
temp[tmp_pos++] = v [izq++]
Mientras (med <= der)
temp[tmp_pos++] = v [med++]
Repetir num_elementos
v [der] = temp[der]
der--
FIN
ADMINISTRACIÓN DE MEMORIA
La cantidad de memoria es limitada, el sistema operativo es el encargo de administrarla y
compartirla entre distintos usuarios y/o aplicaciones.
La ejecución de un programa requiere que diversos elementos se almacenen en la memoria:
- Código del programa (instrucciones).
- Datos (permanentes y temporales).
- Direcciones para controlar el flujo de ejecución del programa.
- La memoria asignada a elementos fijos, es controlada por el compilador: Asignación
de memoria estática.
- A la asignación y posible recuperación de memoria durante la ejecución de un
programa, y bajo su control se la llama: Asignación de memoria dinámica.
- Define la cantidad de memoria necesaria para un programa durante el tiempo de
compilación.
- El tamaño no puede cambiar durante el tiempo de ejecución del programa, sí el
contenido.
Asignación dinámica: Permite declarar variables dinámicas o referenciadas, también conocidas
como PUNTEROS.
Un puntero es un tipo de variable usada para almacenar la dirección en memoria de
otra variable en lugar de un dato convencional.
Mediante la variable del tipo puntero se accede a una dirección, y en dicha dirección de
memoria se encuentra realmente el valor almacenado. EL CONTENIDO DE LA VARIABLE DE
TIPO PUNTERO ES UNA DIRECCIÓN DE MEMORIA.
Memoria: Un puntero ocupa una cantidad de memoria fija, independientemente del dato al
que apunta.
Dato referenciado: No tiene memoria asignada, o no existe inicialmente espacio reservado en
memoria para este dato.
LISTA ENLAZADAS
Definición: Colección de elementos homogéneos, con una relación lineal que los vincula, es
decir que cada elemento tiene un único predecesor (excepto el primero), y un único sucesor
(excepto el último).
Los elementos que la componen no ocupan posiciones secuenciales o contiguas de memoria.
Es decir pueden aparecer dispersos en la memoria, pero mantienen un orden lógico interno.
Lineal: Cada elemento tiene un único siguiente y un anterior.
Dinámica: Durante la ejecución del programa puede cambiar su cantidad de
elementos.
Homogénea: Los elementos son todos del mismo tipo.
Características:
Está compuesta por nodos.
Los Nodos se conectan por medio de enlaces o punteros.
Cuando se necesita espacio adicional, nuevos nodos pueden ser alocados y agregados
a la estructura (New).
Cuando existen nodos que ya no se necesitan, pueden ser borrados, liberando
memoria (Dispose).
Declaración:
1) En principio debemos crear el código de la clase Nodo para declarar una lista de enteros en
Java:
public class Nodo {
public int dato; //Cualquier tipo de los vistos
public Nodo siguiente; // Estructura recursiva
public Nodo(){
siguiente = null;}
}
2) Luego crearemos la clase ListaEnlazada para representar a la lista de enteros en Java:
public class ListaEnlazada {
public Nodo primero;
public ListaEnlazada(){
primero = null;}
}
Operaciones:
a> Crear una lista vacía.
b> Crear una lista agregando los elementos al inicio (adelante). PILA
c> Recorrer una lista.
d> Crear una lista agregando los elementos al final (atrás). COLA
e> Insertar un nuevo elemento en una lista ordenada.
f> Eliminar un elemento de la lista.
a)
public ListaEnlazada(){
primero = null;
}
private void listaVacia(){
Primero = null;
}
b) Para agregar un elemento a una lista debo:
1- Crear un nodo nuevo.
2- Si la lista no tiene elementos: entonces este nodo nuevo es el puntero inicial de la
lista.
Sino indico que el siguiente del nodo nuevo es el que era el puntero inicial.
Actualizo el puntero inicial de la lista.
Ejemplo:Realizar un programa que lea una secuencia de números hasta el número 48 y genere
una lista en donde los elementos se van insertando adelante.
Crear e inicializar la lista (lista)
Leo un número (n)
Mientras (n no sea 48)
agrego EnListaAdelante (lista, n)
Leo un número (n)
c) Dada una lista, implemente un módulo que imprima los elementos de la misma:
Para recorrer una lista debo: Mientras (no sea el final de la lista)
Imprimir el valor que contiene el nodo.
Avanzar al siguiente elemento de la lista.
d) Para agregar un elemento al final de una lista debo:
1- Crear un nodo nuevo.
2- Si la lista no tiene elementos entonces
este nodo nuevo es el puntero inicial de la lista
Sino
recorro hasta el final de la lista
modifico los punteros
e) Tenemos 4 casos:
0. La lista está vacía.
1. El elemento debe insertarse al principio.
2. El elemento debe insertarse al final.
3. El elemento debe insertarse al medio.
1. Crear el nuevo nodo.
El siguiente del nuevo nodo es pri.
Modificar el puntero inicial
2. Crear el nuevo nodo.
Indicar que el siguiente del último nodo es el nuevo nodo.
3. Crear el nuevo nodo.
El siguiente del nodo anterior es el nuevo nodo.
Indicar que el siguiente al nuevo nodo es el actual.
Para insertar ordenado en una lista debo:
1- Pedir espacio para el nuevo nodo.
2- Guardar nuevo dato.
3- Buscar posición donde se debe insertar (secuencialmente).
4- Reacomodar puntero. Considerar tres casos:
a) El nuevo elemento va en el inicio de la lista.
b) El nuevo elemento va en el medio de dos existentes.
c) El nuevo elemento va al final de la lista.
f) 1- Ubicarse al principio de la lista.
2- Mientras (no se termina la lista) y (no encuentro el valor)
actualizo el puntero anterior
actualizo el puntero actuar
Si (encontré el elemento a eliminar)
si (es el primer elemento)
avanzo el puntero inicial
sino
Si (es el último elemento)
el siguiente del puntero anterior es null
sino
realizo los enganches
Borro el elemento a eliminar.
PILAS (LIFO)
Una pila es un conjunto de elementos del mismo tipo que solamente puede crecer (o decrecer)
por uno de sus extremos. Una pila también se la conoce con el nombre de estructura de tipo
LIFO (Last In First Out), porque el último elemento en llegar es el primero en salir.
Push: Apilar
Pop: Desapilar
Para implementar la estructura PILA usamos la estructura Lista Enlazada.
- Para la operación apilar usaremos la operación insertar al principio que vimos para las
listas, actualizando en consecuencia el puntero al primer elemento.
- Para la operación desapilar procederemos a remover el primer elemento
actualizando dicho puntero en la pila.
El principio debemos crear el código de la clase Elemento (antes Nodo) para declarar una Pila
de enteros:
Public class Elemento {
public int dato;
public Elemento siguiente; estructura recursiva
Public Elemento(){
siguiente = null;}
Luego crearemos la clase Pila (antes ListaEnlazada) para representar a la pila de enteros:
Public class Pila {
public Elemento tope;
public Pila(){
tope = null;}
}
Operaciones:
1- Crear una pila vacía
public Pila {
tope = null;
public boolean esVacia(){
return tope == null;}
}
2- Apilar un elemento
Para agregar un elemento a una pila debo:
a- Crear un elemento nuevo.
b- Si la pila no tiene elementos entonces este nuevo elemento será el
tope de la pila actualizo el tope de la pila con el nuevo elemento.
3- Desapilar un elemento
Esta operación extraerá el actual tope de la pila:
a- El elemento a devolver será el actual tope
b- Si la pila tiene elementos entonces
tope = tope.siguiente
COLA (FIFO)
Una cola es un conjunto de elementos del mismo tipo en el que la operación de
inserción se realiza por un extremo (el posterior o final) y la operación de
extracción por el otro (el anterior o frente). Una cola también se la conoce con el
nombre de estructura de tipo FIFO (First In First Out), porque el primer elemento
en llegar es el primero en salir.
Operaciones:
Para implementar la estructura Cola haremos uso de la estructura Lista
Enlazada que vimos en la clase anterior con algunos agregados para facilitar las
operaciones.
a- Para la operación insertar usaremos la operación insertar al final que vimos para
las listas, actualizando en consecuencia el puntero al último elemento.
b- Para la operación extraer procederemos a remover el primer elemento
actualizando dicho puntero en la cola.
En principio debemos crear el código de la clase Elemento (antes Nodo) para
declarar una Cola de enteros.
Public class Elemento {
public int dato;
public Elemento anterior; estructura recursiva
Public Elemento(){
anterior= null;}
- Luego crearemos la clase Cola (antes ListaEnlzada) para representar a la cola de
enteros:
Public class Cola {
public Elemento primero;
public Elemento ultimo;
Public Cola(){
primero = null;
ultimo = null; }
Operaciones:
1- Crear una cola vacía
Public Cola {
primero = null;
ultimo = null; }
Public boolean colaVacia(){
return primero == null;
2- Insertar un elemento
Para agregar un elemento a una cola debo:
a- Crear un elemento nuevo.
b- Si la cola no tiene elementos entonces este nuevo elemento será el primero
y último de la cola sino indico que el anterior del último elemento es e nuevo y actualizo el
último de la cola con el nuevo elemento.
3- Extraer un elemento
a- El elemento a devolver será el actual primero
b- Si la cola tiene elementos entonces
primero = primero anterior
LISTA DOBLEMENTE ENLAZADAS
Ejercicios
1) Se necesita un programa que permita determinar el impuesto que debe cobrárseles a
un grupo de inversores. Dicho impuesto se aplica sobre las ganancias netas obtenidas,
pero el porcentaje es variable de acuerdo a las siguientes condiciones. Si la ganancia
neta:
• No supera el 20% de la inversión inicial realizada, el mismo será del 0%.
• No supera el 40% de la inversión inicial realizada, el mismo será del 2%.
• No supera el 60% de la inversión inicial realizada, el mismo será del 4%.
• Equivale a, o supera el, 60% de la inversión realizada, el mismo será del 10%.
¿Cómo se determina la ganancia neta? A la ganancia bruta obtenida se le resta la
inversión inicial y los gastos.
En total son 40 inversores y su programa debe requerir al inicio, para cada uno de
ellos:
• Monto correspondiente a la inversión inicial realizada.
• Monto total de gastos incurridos.
• Monto correspondiente a la ganancia bruta.
Luego de ingresados todos los datos, y de acuerdo al orden en el que fueron
ingresados, su programa deberá imprimir un reporte donde se indique para cada
inversor el monto del impuesto que deberá abonar, de la siguiente manera:
Inversor 1: $230,23 (2%)
Inversor 2: $1233,44 (10%)
Inversor 3: $0 (0%)
…
Inversor 40: $13223 (10%)
Por ejemplo, supongamos que uno de los inversores ganó $13700 a partir de una
inversión inicial de $6500 y tuvo gastos por $2360,80. Entonces:
Ganancia neta = ganancia bruta – inversión inicial – gastos
Ganancia neta = 13700 – 6500 – 2360,80 = 4839,20
Lo cual representa el:
6500 ________________ 100%
4839,20 ________________ x = (4839,20 * 100) / 6500 = 74,45% de la inversión inicial.
Entonces, aplica un porcentaje de impuesto del 10% sobre la ganancia neta de
$4839,20 por lo ese inversor pagará $483,92.
2) Se necesita un programa que permita determinar si una persona es apta o no para
recibir préstamo bancario y determinar el monto máximo del mismo. Este programa
deberá requerir, al inicio, la cantidad de solicitantes a procesar y, luego, pedir para
cada uno de ellos los siguientes datos: nombre y apellido; DNI; edad; estado civil (‘S’:
para soltero, ‘C’: para casado); ingresos y monto aproximado de deudas mensual.
3) La entidad bancaria, ha decidido que el solicitante es apto para recibir el préstamo
sólo si cumple con las siguientes condiciones: Debe ser mayor de 18 años y menor de
65 años. El monto mensual de sus deudas debe ser inferior al 35% de su sueldo.
Debe ganar más de $16.000 si es soltero, o más de $8.000 si es casado.
4) El programa debe responder, por cada solicitante, si el mismo es apto o no para recibir
el préstamo bancario dependiendo del resultado de la evaluación. Además, se deberá
indicar el monto máximo de dinero a prestar, teniendo en cuenta que puede ser de 50
veces sus ingresos menos sus deudas. El reporte deberá mostrarse de la siguiente
manera: por ejemplo: “Juan Pérez: APTO ($23400)”, o “Juan Pérez: NO APTO”.
5) El cine “Vea Más” tiene la siguiente disposición de butacas: Matrices: Ejercicio 2 Se
necesita un programa que permita reservar butacas en el cine y, además, que se
pueda obtener el precio correspondiente. Se reserva una butaca cada vez. Además, al
final de cada función, se quiere obtener un reporte del estado de ocupación de las
mismas.
6) El gerente de las salas de cine “Vea Más” desea conocer algunas estadísticas sobre el
funcionamiento del emprendimiento que gerencia. Las mismas 12 películas son
exhibidas en cada una de las 8 salas del cine. Para cada sala se conoce el total de
personas que han asistido a ver cada película. Se busca conocer cuál es la mejor
combinación sala-película y cuál de las 12 películas fue la más vista.
7) Escriba un programa que permita ordenar arreglos de números enteros por el método
burbuja. Su programa, además de ordenar los arreglos, deberá imprimir los datos
necesarios para hacer un seguimiento (número de iteración, que elementos del arreglo
está comparando en cada iteración, si hace o no un intercambio y, en caso afirmativo,
debe mostrar que elementos del arreglo está intercambiando).
8) Escriba un programa que permita ordenar arreglos de números enteros por el método
de ordenamiento por inserción. Su programa, además de ordenar los arreglos, deberá
imprimir los datos necesarios para hacer un seguimiento (número de iteración, que
elemento del arreglo está tomando en cada iteración, que corrimientos de elementos
está haciendo y en qué lugar queda ubicado finalmente el elemento tomado en cada
iteración).
9)