1. Definir estructura de datos.
Identificar los arreglos dentro de la clasificación de los tipos de datos más frecuentes en los
diversos lenguajes de programación.
Definir un arreglo
Identificar las características basicas de un arreglo.
Enunciar y diferenciar los diferentes tipos de arreglos
Hasta ahora sólo habiamos visto estructuras de datos simples (como variables y constantes
enteras, reales y caracter ). pero estas no son suficientes para resolver problemas más
complejos.
Por ejemplo como responderiamos a estas interrogantes.
¿ Cómo almacenar y accesar a las
respuestas a 10 preguntas de 5
opciones múltiples 'A','B','C','D' y 'E'
?
¿Usaríamos las variables. rpta1,
rpta2, ....... rpta10 ?
¿ Cómo almacenar y localizar las indices Nombres Notas
notas y los nombres de 25 alumnos
de esta clase ? 0 Julio Perez 12
¿Usaríamos las variables. 1 Edgar Condori 4
Nombre1, Nombre2, .......
Nombre25 y 2 Erica Castro 11
Nota1, Nota2, ... Nota25?
2. 3 Luis Risco 9
.....
22 Miura Fernández 16
23 Ada Lugo 12
24 André Fernández 5
indices Nombre Sueldo
0 Ada Lugo 2400.6
¿ Cómo almacenar y localizar los
nombres y sueldos de los 40 1 Miura Fernández 3500.5
empleados de una pequeña empresa
2 André Fernández 2800.8
?
¿Usaríamos las variables. i ..... ...
Nombre1, Nombre2, .......
Nombre10 y 37 Gladys Garcia 3200.0
Sueldo1, Sueldo2, ...Sueldo39 ?
38 Jorge Barzola 2105
39 Maria Cano 3700.2
¿ Cómo almacenar y localizar la
cantidad de vehiculos ( bicicletas,
triciclos, motos, autos y camiones)
vendidos en cada uno de los 12
meses del año 2001, por una
importadora de vehiculos de
transporte y carga. ?
¿Usaríamos las variables. Can1,
Can2, Can3 ... Can30?
Ejemplos de Arreglos
Esas no serian las soluciones a los problemas planteados ¿verdad?
¡ Ya no es adecuado usar los tipos de datos simples (enteros reales o caracteres) porque
tendriamos que declarar muchas variables !
Para resolver problemas de este tipo se requieren datos estructurados más complejas,
capaces de almacenar datos relacionados entre sí.
3. Definición 1 Una estructura de datos es un modelo matemático o lógico de una organización
particular de datos.
Definición 2. Una estructura de datos es una colección de datos que se caracterizan por la FORMA
en que estos se ORGANIZAN, y por las OPERACIONES que se pueden definir sobre dichos datos.
Los tipos de datos mas frecuentes utilizados en los diferentes lenguajes de programación son:
Entero
Real
Tipo de Datos Simples Estándar Caracter
Lógico
(Datos Simples)
Definidos por el Subrango
usuario Enumerado
Característica :Un identificador de un tipo de dato simple (nombre de variable) representa a un
unico elemento
Array (Vectores y Matrices)
Registros
Estáticos Archivos
Conjuntos
Cadenas
Tipos de Datos Complejos
Pilas
(Datos estructurados) Listas Colas
Lineales
Listas enlazadas
Dinámicos Arboles
Listas
No Lin. Grafos
Característica:- Un identificador de un tipo de dato estructurado (nombre de variable) puede
representar a multiples datos individuales, pudiendo cada uno de ellos ser accesados de manera
independiente.
Tipos Abstractos de Datos
4. Definición 1: Es un conjunto ordenado y finito de elementos homogéneos.
Es decir, sus características básicas son:
"Finito”, porque se requiere definir el tamaño del array (definir el tamañ antes de ser utilizado).
Ejm : el array Notas que almacena las notas de los 25 alumnos de una clase es de tamaño 25
"Homogéneos”, porque todos los elementos del array son del mismo tipo.
Ejm: en el array Notas, todas las notas almacenadas son de tipo entero.
"Ordenado”, porque se pueden identificar a cada elemento del array por la posición que
ocupan: el primero, el segundo, el tercero,..., el n-esimo, etc.
Ejm: en el array Notas, la nota del tercer alumno de la clase (puede ser en orden alfabetico),
ocupa la posición 3.
Definición 2 :
Son posiciones en memoria consecutivas relacionadas entre sí por el hecho de que tienen
el mismo nombre y los datos que contiene son todos Del mismo tipo.
Son entidades estáticas ya que conservan el mismo tamaño durante toda la ejecución del
programa.
5. Los arreglos se clasifican en:
En matemática es conocido como Vector.
a) Arreglo unidimensional Ejm:
Cantidad de canastas anotadas por el equipo Tamaño
( array lineal o vector ) peruano en cada uno de los 5 partodps del 5
Sudamericano 2000
Dos o mas vectores de igual tamaño donde
Arreglos unidimensionales sus elementos de igual indice estan
paralelos relacionados. Ejm:
Descripcion de productos y sus respectivos precios Tamaño
(8 tipos de productos). 8
En matemática es conocido como Matriz,
Arreglo bidimensional o en base de datos como tabla. Ejm: Los
(array bidimensional o matriz ) sueldos de 10 empleados en cada uno de los Tamaño
meses de Enero a Junio 2000. 10x6
Arreglo multidimensional ( n - Ejm: Estados (libre u ocupado) de las 10 aulas en
dimensional) cada uno de los 4 pisos de los 5 pabellones. Tamaño
10x4x5
Definir un arreglo unidimensional.
Saber declarar un arreglo unidimensional de cualquier tipo.
Declarar arreglos unidimensionales en el contexto de un problema, diferencinadolos de los
datos simples.
Conocer, citar y utilizar las reglas que definen un arreglo unidimensional.
Operaciones:
Citar los diferentes tipos de operaciones que se pueden realizar sobre los arreglos
unidimensonales.
Saber Inicializar arreglos unidimensionales de diversos tipos.
Saber asignar o dar valores a los elementos de un arreglo unidimensional.
Saber leer y mostrar todo un arreglo unidimensional.
Identificar los procesos para solucionar un problema que requiera de recorrido, visitado o
barrido de un arreglo unidimensional.
Sumar los elementos numericos de un arreglo.
Conocer y aplicar los algoritmos para calcular el minimo y maximo valor de un arreglo
unidimensional.
Diseñar el desarrollo de problemas que requieran sumar o restar arreglos.
6. Diseñar el desarrollo de problemas que requiera multiplicar un arreglo unidimensional por un
escalar y multiplicar arreglos unidimensionales.
Conocer el algoritmo para borrar o insertar un elemento en un arreglo unidimensional.
Conocer y emplear el algoritmo burbuja para clasificar arreglos unidimensionales de tipo
numerico y/o cadenas.
Cada Lenguaje de Programación tiene sus reglas para declarar un arreglo Pero cada
declaración debe incluir 3 clases de información acerca del arreglo:
· El nombre del arreglo.
· El tipo de los datos del arreglo
· El conjunto de índices del arreglo(tamaño).
Ejm En PASCAL: Autos[1..16] OF integer
Ejm: En C++ int Autos[16];
Al declararse un arreglo unidimensional se reserva espacio en la memoria principal para una
cantidad de elementos del tipo declarado.
A este tipo de estructura se le denomina estatico, porque la longitud del arreglo no
puede variarse durante la ejecución del programa.
Las estructuras dinámicas pueden cambiar su tamaño (aumentar o disminuir)
durante la ejecución del programa
Ordenación en Arreglos
La importancia de mantener nuestros arreglos ordenados radica en que es mucho más rápido
tener acceso a un dato en un arreglo ordenado que en uno desordenado.
Existen muchos algoritmos para la ordenación de elementos en arreglos, enseguida veremos
algunos de ellos.
a)Selección Directa
Este método consiste en seleccionar el elemento más pequeño de nuestra lista para colocarlo
al inicio y así excluirlo de la lista.
Para ahorrar espacio, siempre que vayamos a colocar un elemento en su posición correcta lo
intercambiaremos por aquel que la esté ocupando en ese momento.
El algoritmo de selección directa es el siguiente:
i <- 1
mientras i<= N haz
min <-i
j <- i + 1
mientras j <= N haz
si arreglo[j] < [min] entonces
min <-j
j <- j + 1
intercambia(arreglo[min],arreglo[i])
7. i <- i +1
b)Ordenación por Burbuja
Es el método de ordenación más utilizado por su fácil comprensión y programación, pero es
importante señalar que es el más ineficiente de todos los métodos .
Este método consiste en llevar los elementos menores a la izquierda del arreglo ó los mayores
a la derecha del mismo. La idea básica del algoritmo es comparar pares de elementos
adyacentes e intercambiarlos entre sí hasta que todos se encuentren ordenados.
i <- 1
mientras i < N haz
j <- N
mientras j > i haz
si arreglo[j] < arreglo[j-1] entonces
intercambia(arreglo[j],arreglo[j-1])
j<j-1
i <- i +1
c)Ordenación por Mezcla
Este algoritmo consiste en partir el arreglo por la mitad, ordenar la mitad izquierda, ordenar la
mitad derecha y mezclar las dos mitades ordenadas en un array ordenado. Este último paso
consiste en ir comparando pares sucesivos de elementos (uno de cada mitad) y poniendo el
valor más pequeño en el siguiente hueco.
procedimiento mezclar(dat,izqp,izqu,derp,deru)
inicio
izqa <- izqp
dera <- derp
ind <- izqp
mientras (izqa <= izqu) y (dera <= deru) haz
si arreglo[izqa] < dat[dera] entonces
temporal[ind] <- arreglo[izqa]
izqa <- izqa + 1
en caso contrario
temporal[ind] <- arreglo[dera]
dera <- dera + 1
ind <- ind +1
mientras izqa <= izqu haz
temporal[ind] <- arreglo[izqa]
izqa <- izqa + 1
ind <- ind +1
mientras dera <= deru haz
temporal[ind] <=dat[dera]
dera <- dera + 1
ind <- ind + 1
para ind <- izqp hasta deru haz
arreglo[ind] <- temporal[ind]
fin
8. Para entender el método ordenaremos de menor a mayor la lista de 8 datos enteros, usando el método
de burbuja ( N = 8 ). Sea el arreglo A:
A
30 50 28 89 76 24 16 60
Paso1:
Objetivo: Obtener el mas grande al final de la lista. Para ello se compara cada elemento A[j] con el
siguiente A[j+1], donde j varia de 1 a N -1 ( 7 comparaciones)
Es decir : si A[j] > A[j +1] es verdad se intercambia.
Finalmente el arreglo queda así :
30 28 50 76 24 16 60 89
A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8]
El elemento más grande está en la posición 8.
Paso2 :
Objetivo: Obtener el mas grande al final de la lista (con 7 elementos). Para ello se compara cada
elemento A[j] con el siguiente A[j+1], donde j varia de 1 a N -2.(6 comparaciones)
Es decir : si A[j] > A[j +1] es verdad se intercambia.
Finalmente el arreglo queda así :
28 30 50 24 16 60 76 89
A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8]
El elemento más grande está en la posición 7
Paso 3:
Objetivo: Obtener el más grande al final de la lista (con 6 elementos). Para ello se compara cada
elemento A[j] con el siguiente A[j+1], donde j varia de 1 a N -3.(5 comparaciones)
Es decir: si A[j] > A[j +1] es verdad se intercambia.
9. Finalmente el arreglo queda así :
28 30 50 24 16 60 76 89
A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8]
El elemento más grande está en la posición 6
Paso 4:
Objetivo: Obtener el más grande al final de la lista (con 5 elementos). Para ello se compara cada
elemento A[j] con el siguiente A[j+1], donde j varia de 1 a N -4 (4 comparaciones).
Es decir : si A[j] > A[j +1] es verdad se intercambia.
Finalmente el arreglo queda así :
28 24 16 30 50 60 76 89
A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8]
El elemento más grande está en la posición 5
Paso 5:
Objetivo: Obtener el más grande al final de la lista (con 4 elementos). Para ello se compara cada
elemento A[j] con el siguiente A[j+1], donde j varia de 1 a N -5 (3 comparaciones).
Es decir : si A[j] > A[j +1] es verdad se intercambia.
Finalmente el arreglo queda así:
28 24 16 30 50 60 76 89
A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8]
El elemento más grande está en la posición 4
Paso 6:
10. Objetivo: Obtener el más grande al final de la lista (con 3 elementos). Para ello se compara cada
elemento A[j] con el siguiente A[j+1], donde j varia de 1 a N -6 (2 comparaciones).
Es decir : si A[j] > A[j +1] es verdad se intercambia.
Finalmente el arreglo queda así :
16 24 28 30 50 60 76 89
A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8]
El elemento más grande está en la posición 3
Paso 7:
Objetivo: Obtener el más grande al final de la lista (con 2 elementos). Para ello se compara cada
elemento A[j] con el siguiente A[j+1], donde j varia de 1 a N -7 ( 1 comparación).
Es decir : si A[j] > A[j +1] es verdad se intercambia.
Finalmente el arreglo queda así (ordenado de mayor a menor):
16 24 28 30 50 60 76 89
A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8]
El elemento más grande está en la posición 2
EL ARRAY YA ORDENADO DE MENOR A MAYOR
16 24 28 30 50 60 76 89
A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8]
Observación : Si se desea ordenar de mayor a menor, lo unico que cambia es la pregunta para hacer
el intercambio, con el objetivo de obtener en cada paso el más pequeño al final de la lista
Es decir : si A[j] < A[j +1] es verdad se intercambia.
11. Algoritmo BURBUJA Programa C++ BURBUJA
INICIO {
COM: Declaracion de variables // Declaracion de variables
entero A[10], k , J, Aux , N=8 int A[10], k , J, Aux , N=8;
const int N=10; const int N = 10;
COM: Inicialización o lectura del arreglo A // Inicialización o lectura del arreglo A
para (i=1, hasta N, i = i+1) for (i=0; i < N ; i = i+1)
{ Leer A[i] } { cin>> A[i] ; }
COM: Algoritmo de ordenamiento burbuja // Algoritmo de ordenamiento burbuja
COM: k = Numero de pasos (1 a N-1) // k = Numero de pasos (1 a N-1)
para ( k =1 hasta N -1; k=k+1 ) for ( k = 0 ; k < N -1 ; k = k+1 )
{ {
COM: Nro de compar. j depende del Nro de paso // Nro de comparac. j depende del Nro de paso
para(J=1, hasta N–1-k;J =J +1) for (J = 0 ;J < N –1-k ; J =J +1)
{ {
SI ( A [J ] > A [J+1] ) if ( A [J ] > A [J+1] )
{ COM: Intercambiamos A[J] y A[J+1] { // Intercambiamos A[J] y A[J+1]
Aux = A [ J ] Aux = A [ J ];
A [ J ] = A [ J+1] A [ J ] = A [ J+1] ;
A [ J+1] = Aux A [ J+1] = Aux;
} }
} COM: fin del PARA interior } // fin del para interno
} COM: fin del PARA exterior } //COM: fin del PARA exterior
COM: Se muestra el arreglo ordenado // Se muestra el arreglo ordenado
para (i=1, hasta N, i = i+1) for (i=0 : i < N ; i = i+1)
{ Mostrar A[i] } { cout<< A[i] <<" "; }
FIN }
G) Operaciones entre arreglos unidimensionales
G1) Sumar
Sumar los elementos de dos arreglos A y B para obtener un tercer arreglo S:
A En A[1] A[2] A[ i ] .... A[n-1] A[n]
pseudocodigo 1 2 i n
B En B[1] B[2] B[ i ] .... B[n-1] B[n]
pseudocodigo 1 2 i n-1 n
A[1] + B[1] A[2] + B[2] A[i]+B[i] A[n] + B[n]
S En
12. pseudocodigo 1 2 i n-1 n
S[i]=A[i]+B[i]
// a cada elemento A[i] se le suma el respectivo elemento B[i]
G2) Restar
Restar los elementos de dos arreglos A y B para obtener un tercer arreglo R:
A En A[1] A[2] A[ i ] .... A[n-1] A[n]
pseudocodigo 1 2 i n
B En B[1] B[2] B[ i ] .... B[n-1] B[n]
pseudocodigo 1 2 i n-1 n
A[1] - B[1] A[2] - B[2] A[i]-B[i] A[n] - B[n]
R En
pseudocodigo 1 2 i n-1 n
R[i]=A[i]-B[i]
// a cada elemento A[i] se le resta el respectivo elemento B[i]
Programas en C++ para sumar y restar arreglos unidimensionales
SUMA ARREGLOS RESTA ARREGLOS
void main() void main()
{ {
const int N=20; const int N=20;
// Declaración de Variables // Declaración de Variables
int i; int i;
double A[N], B[N] S[N]; double A[N], B[N], R[N];
........ // Leer o inicializar Arreglo A ........ // Leer o inicializar Arreglo A
....... // Leer o inicializar Arreglo B ....... // Leer o inicializar Arreglo B
// Recorrido del Array A // Recorrido del Array A
13. for ( i= 0 ; i < N ; i =i+1 ) for ( i= 0 ; i < N ; i =i+1 )
{ // suma elemento por elemento { // Multiplica elmento por elemento
S[i] = A [ i ] + B[i] R [i] = A [ i ] - B[i]
; ;
} }
.... // Muestra arreglo S ...... // Muestra arreglo R
} }
G3) Multiplicar arreglo unidimensional por un escalar
Multiplicar cada elemento del arreglo A por un escalar K:
A En A[1] A[2] A[i] .... A[n-1] A[n]
pseudocodigo 1 2 i n
k*A[1] k*A[2] k *A[i] k*A[n]
C En
pseudocodigo 1 2 i n-1 n
C[i] = k * A[i]
// cada elemento de A[i] es multiplicado por el escalar k
G4) Multiplicar arreglos unidimensionales
Multiplicar los elementos de dos arreglos A y B para obtener un tercero P:
A En A[1] A[2] A[ i ] .... A[n-1] A[n]
pseudocodigo 1 2 i n
B En B[1] B[2] B[ i ] .... B[n-1] B[n]
pseudocodigo 1 2 i n-1 n
A[1] * B[1] A[2] * B[2] A[i]*B[i] A[n] * B[n]
P En
14. pseudocodigo 1 2 i n-1 n
P[i]=A[i]*B[i]
// a cada elemento A[i] se le multiplica por su respectivo elemento B[i]
Programas en C++ para multiplicar arreglos unidimensionales entre si y por un escalar
MULTIPLICA POR ESCALAR MULTIPLICA ARREGLOS
void main() void main()
{ const int N=20; { const int N=20;
// Declaración de Variables // Declaración de Variables
int i; int i;
double A[N],C[N], k ; double A[N], B[N], P[N];
........ // Leer o inicializar Arreglo A ........ // Leer o inicializar Arreglo A
....... // Leer o inicializar Arreglo B ....... // Leer o inicializar Arreglo B
// Recorrido del Array A
....... // Leer o inicializar k
// Recorrido del Array A for ( i= 0 ; i < N ; i =i+1 )
for ( i= 0 ; i < N ; i =i+1 ) { // Multiplica elmento por elemento
{ // suma elemento por elemento P [ i ] = A [ i ] *
C[ i ] = k * A [ i ] ; B[i] ;
} }
.... // Muestra arreglo A ...... // Muestra arreglo M
} }
G5) Mezcla o intercalación
Combinar dos listas en una sola.
Vectores Originales:
A 3 4 7 19
1 2 3 4
B -5 0 4 13 17 19 90 95
1 2 3 4 5 6 7 8
15. C
1 2 3 4 5 6 7 8 9 10 11 12
Ver proceso de mezcla_algoritmos
Vectores Mezclados:
A 3 4 7 19
1 2 3 4
r
varía
desde
B -5 0 4 13 17 19 90 95
j=7
hasta
8
1 2 3 4 5 6 7 8
C k = k+1=9 -5 0 3 4 7 13 17 19 90 95
k = k+1=10 1 2 3 4 5 6 7 8 9 10 11 12
Ver proceso de mezcla_c++
Programas en algoritmos y en C++ para la mezcla de los vectores A y B, se obtiene el vector mezcla C
ALGORITMO PROGRAMA C++
INICIO INICIO
constante entero M=4,N=8 const int M=4,N=8;
// Declaración de Variables // Declaración de Variables
entero i , j , k , r int i , j , k , r
real A[M],B[N],C[M+N] ; double A[M],B[N],C[M+N] ;
........ // Leer o inicializar Arreglo A ........ // Leer o inicializar Arreglo A
....... // Leer o inicializar Arreglo B ....... // Leer o inicializar Arreglo B
COM: Inicializa i , j ,k // Inicializa i , j ,k
i=1, j=1, k=0 i =1; j =1; k = 0;
Mientras ((i<=M) y (j<=N)) while (( i < M ) && ( j< N ))
16. { { k=k+1;
k=k+1 if ( A[ i ] < B[ j ] )
si (A[ i ] < B[ j ]) { C[ k ] = A[ i ];
{ C[ k ] = A[ i ] i = i +1;
i = i +1 }
} else
sino { C[ k ] = B[ j ];
{ C[ k ] = B[ j ] if (A[ i ] == B[ j ])
j = j +1 { i=i+1; j=j+1;}
} j = j +1;
} }
si (i<=M) }
{ if ( i < M)
para(r=i hasta M, r=r+1) {
{ k=k+1 for(r= i ;r< M; r=r+1)
C[ k ] = A[ r ] { k = k+1;
} C[ k ] = A[ r ];
} }
sino }
{ else
para(r=j hasta N, r=r+1) {
{ k=k+1 for (r= j ;r< N; r=r+1)
C[ k ] = B[ r ] { k = k +1;
} C[ k ] = B[ r ];
} }
COM: Muestra arreglo C intercalado o mezclado }
para(i=1, hasta k, i=i+1) // Muestra arreglo C intercalado o mezclado
{ cout<< C[ k ]<<" "; } for (i=0; i<= k, i=i+1)
FIN { cout<< C[ k ]<<" "; }
cout<<endl;getch();
}
Ejemplo - Aplicación: El administrador de una embotelladora utiliza los arreglos UVMan y UVTar
para almacenar las unidades vendidas (cajas) en la mañana y tarde respectivamente y en el arreglo
PreUni se almacena el precio de venta de cada unidad (cajas) de producto. Hacer un algoritmo y su
programa respectivo en C++ para calcular las unidades vendidas en todo el dia y a cuanto asciende la
venta en soles por cada producto. Se comercializan 10 variedades de productos.
ALGORITMO Ventas PROGRAMA Ventas
INICIO {
COM: declaracion de variables
// declaracion de variables
entero UVMan[10], UVTar[10]; entero
o UVDia[10], VenTotD o int UVMan[10], UVTar[10];
int UVDia[10], VenTotD;
real PreUni[10], VentaD[10]
17. double PreUni[10], VentaD[10];
COM: Lectura del arreglo UVMan / Lectura del arreglo UVMan
para ( i= 1 hasta 120 ,i=i+1 ) for ( i= 0 ; i<10 ; i=i+1 )
{ LEER UVMan [ i ] } { cin>> UVMan [ i ]; }
COM: Lectura del arreglo UVTar // Lectura del arreglo UVTar
para ( i= 1, hasta 120, ,i=i+1 ) for ( i= 0; i <10 ; i=i+1 )
{ LEER UVTar [ i ] } { cin>> UVTar [ i ]; }
COM: Lectura del arreglo PreUni // Lectura del arreglo PreUni
para ( i= 1 hasta 120 ,i=i+1 ) for ( i= 0; i <10 ; i=i+1 )
{ LEER PreUni [ i ] } { cin>> PreUni [ i ]; }
COM: Calculo del arreglo UVDia que almacena las unidades vendidas COM: Calculo del arreglo UVDia que almacena las unidades vendidas
en el dia en el dia
para ( i= 1 hasta 120 ,i=i+1 ) for ( i= 0; i <10 ; i=i+1 )
{ // Visita cada uno de los elemento de los arreglos { // Visita cada uno de los elemento de los arreglos
UVDia[i] = UVMan[ i ]+UVTar[i]; UVDia [ i ] = UVMan [ i ] + UVTar [ i ];
} }
COM: Calculo dle arreglo VentaDia que almacena la venta del dia en // Calculo dle arreglo VentaDia que almacena la venta del dia en soles
soles en c/u de los productos. en c/u de los productos.
para ( i= 1, hasta 10 ,i=i+1 ) for ( i= 0; i <10 ; i=i+1 )
{ // Visita cada elemento i { // Visita cada elemento i
VentaD[i]=UVDia[i] * PreUni[i] } VentaD[i]= UVDia[i]*PreUni[i]; }
COM: Calculo de la VentaTotal del dia en soles VenTotDia // Calculo de la VentaTotal del dia en soles VenTotDia
VenTotD= 0 VenTotD= 0
para ( i= 1 hasta 10 ,i=i+1 ) for ( i= 0; i <10 ; i=i+1 )
{ // Visita al elemento , acumula { // Visita al elemento , acumula
VenTotD =VenTotD +VentaD[ i] VenTotD =VenTotD + VentaD[ i ];
} }
Mostrar VenTotD cout<< VenTotD<<endl;
FIN }
18. Definir un arreglo bidimensional.
Saber declarar un arreglo bidimensional de cualquier tipo.
Demostrar como accesar un arreglo unidimensional.
Conocer, citar y utilizar las reglas que definen un arreglo bidimensional.
Operaciones:
Citar los diferentes tipos de operaciones que se pueden realizar sobre los arreglos
bidimensonales.
Saber inicializar arreglos bidimensionales de diversos tipos.
Saber asignar o dar valores a los elementos de un arreglo bidimensional.
Saber leer y mostrar todo un arreglo bidimensional.
Identificar los procesos para solucionar un problema que requiera de recorrido, visitado o
barrido de un arreglo bidimensional(ejm contar)
Conocer y aplicar los algoritmos para calcular el máximo y el minimo valor de un arreglo
bidimensional.
Diseñar el desarrollo de problemas que requieran sumar o restar arreglos bidimensionales.
Diseñar el desarrollo de problemas que requiera multiplicar un arreglo bidimensional por un
escalar y multiplicar 2 arreglos bdimensionales.
Saber sumar filas para obtener el vector vertical a partir de una matriz
Saber sumar columnas para obtener el vector horizontal a partir de una matriz
Se puede considerar como un vector de vectores. Por tanto es un conjunto de elementos
todos del mismo tipo en el que se utilizan dos subíndices para especificar un elemento.
Ejm Una cadena de tiendas está formada por 10 sucursales y cada uno consta de 5
secciones (Lacteos/Bebidas/... /carnes). En la siguiente tabla o matriz (matemático) se
representan las ventas mensuales en soles.
Secciones
VENTAS 0 1 .... 3 4
1 2 ... 4 5
Sucursales
19. 01 2400 3600 5600 7200 3100
12 1800 5120 3490 5690 5670
Los indices en ... ... ... ... ...
psuedocodigo y en
C++ ... ... ... ... ...
45 3490 3460 5671 4567 5423
56 1780 3450 6740 4356 3210
En un array bidimensional cada elemento del array se referencia a través de dos índices.
En pseudocodigo : VENTAS [1] [2] =3600 VENTAS [2][4] = 5690
En C++ VENTAS [0] [1] =3600 VENTAS [1][3] = 5690
EJEMPLO DE DECLARACION DE ARREGLOS BIDIMENSIONALES
EN ALGORITMOS (seudocódigo) y en C++ (código) respectivamente
real nota[25][4] declara nota, las 4 notas de cada uno de los 25 alumnos. Reserva
double nota[25][4]; celdas de memoria.para 100 datos double
real Peso[20][12] declara Peso, los pesos promedios de 30 deportistas en cada uno
de los 12 meses del 2001. Reserva celdas de memoria para 240
double Peso [20][12]; datos double.
entero DocCasacas[3][30] declara DocCasacas, las docenas de casacas de 3 tallas ('S',
'M','L') confeccionadas en cada uno de los 30 dias del mes de
int DocCasacas[3][30]; Junio. Reserva celdas de memoria para 90 datos iint.
entero unidInsumo[5][12] declara unidInsumo, las unidades de 5 variedades de insumo
comprados en cada uno de los 12 meses del 2000 Reserva celdas
int unidInsumo[5][12]; de memoria para 60 datos int
caracter Rpta[45][10] declara Rpta, las respuestas de 45 alumnos a 10 preguntas de
opcion muiltiple ('a',...'e'). Reserva celdas de memoria para 450
char Rpta[45][10]; datos char.
A) Inicialización de Matrices
Al igual que con las variables simples (no estructurados) y los vectores, las matrices se
pueden inicializar al momento de declararse. Ejm:
B) Asignación
Permite dar valor a uno o varios elementos de un vector.
20. Asignación de valores a los elementos de un vector. En algoritmos (pseudocódigo) y en C++
entero A[15][30]; int A[15][30];
caracter Rpta [50] [10]; char Rpta [50][10];
A[10] [20] = 45 A[10] [20] = 45;
Asigna el valor 45 al elemento de la fila 10 y columna 20 del arreglo bidimensional A.
Rpta [2][5] = 'c' Rpta [2][5] = 'c';
Asigna 'c' al elemento de la fila 2 y columna 5 del arreglo Rpta
C) Operaciones de Entrada/Salida
Lectura/Escritura .- Permite dar valor (leer o ingresar por teclado) o mostrar (en pantalla) el
valor de los elementos de un arreglo bidimensional Ejm:
Lectura / Escritura de elementos de un arreglo bidimensional en pseudocódigo y en C++ respectivamente
Leer V[3][5] Permite Leer el elemento de la fila 3 y columna 5 del
cin>> V[3] [5] ; arreglo bidimensional V
Mostrar V[3][5] Permite Mostrar el elemento de la fila 3 y columna 5 del
cout<< V[3] [5]; arreglo bidimensional V
Lectura / Escritura de los elementos de un arreglo por grupos en pseudocódigo y en C++
respectivamente
constante entera M = 10, N=12; const int M=10, N=12;
entero V[10][12] int V[10][12];
real Peso[M][N] double Peso[M][N];
para (i = 1 ; hasta i <= M ; con i=i+1)
Lee los elementos de la matriz V cuyo indice i varia desde
{ para (j=1 hasta j <=N ; con j=j+1)
1 hasta M, y j varia desde 1 hasta N.
{ Leer V [ i ][ j ]; }
Nota: M y N deben ser conocidos.
}
for (i = 0 ; i < M ; i=i+1)
{ for ( j = 0 ; j < N ; j=j+1) En C++: Lee los elementos de la matriz V cuyo indice i
{ cin>> V [ i ][ j ]; } varia desde 0 hasta M-1 y j varia desde 1 hasta N-1.
} Nota M y N debe ser conocido.
para (i = 1 ; hasta i<= M ; con i=i+1)
{ Muestra los elementos de la matriz V cuyo indice i varia
para (j=1 hasta j <=N ; con j=j+1) desde 1 hasta M, y j varia desde 1 hasta N.
{ Mostrar Peso [ i ][ j ]; } Nota: M y N deben ser conocidos.
}
21. for (i = 0 ; i< n ; i = i+1)
{ En C++: Muestra los elementos de la matriz V cuyo indice
for (j = 0 ; j< n ; j = j+1) i varia desde 0 hasta M-1 y j varia desde 1 hasta N-1.
{ cout<< Peso [ i ][ j ]; } Nota M y N debe ser conocido.
}
Ejemplo: Ejemplo:
entero V[5][3] int V[5[13];
real Peso[5][3] double Peso[5][3];
Permite ingresar por teclado los valores para cada
para (i = 0 ; i< 5 ; i = i+1)
elemento del arreglo V:
{ para ( j = 0 ; j< 3 ; j = j+1)
V[0][0], V[0][1], V[0][2], V[1][0] , V[1][1], V[1][2], V[2][0],
{ Leer V [ i ][ j ]; }
V[2][1], V[2][2], V[3][0], V[3][1], V[3][2], V[4][1], V[4][2],
}
V[4][3]
Permite ingresar por teclado los valores para cada
for (i = 0 ; i< 5 ; i = i+1)
elemento del arreglo V:
{ for ( j = 0 ; j< 3 ; j = j+1)
V[0][0], V[0][1], V[0][2], V[1][0] , V[1][1], V[1][2], V[2][0],
{ cin>> V [ i ][ j ]; }
V[2][1], V[2][2], V[3][0], V[3][1], V[3][2], V[4][1], V[4][2],
}
V[4][3]
Ejemplo Ejemplo
para (i = 1 ; Hasta i<= 5 ; con i=i+1) Muestra en pantalla los valores almacenados en cada
{ para (j = 1;hasta j<= 3 ; con j=j+1) elemento del arreglo: Peso[1][1], Peso[1][2] Peso[1][3],
Peso[2][1], Peso[2][2], Peso[2][3] ,Peso[3][1] Peso[3][2],
{ Mostrar Peso [ i ][ j ]; }
Peso[3][3], Peso[4][1], Peso[4][2] Peso[4][3], Peso[5][1],
} Peso[5][2], Peso[5][3]
Muestra en pantalla los valores almacenados en cada
for (i = 0 ; i< 5 ; i = i+1) elemento del arreglo: Peso[0][0], Peso[0][1] Peso[0][2],
{ for ( j = 0 ; j< 3 ; j = j+1) Peso[1][0], Peso[1][1], Peso[1][2] ,Peso[2][0] Peso[2][1],
{ cout >> Peso [ i ][ j ]; } Peso[2][2], Peso[3][0], Peso[3][1] Peso[3][2], Peso[4][0],
} Peso[4][1], Peso[4][2
E) Operaciones entre arreglos Bidimensionales
E1) Sumar Matrices:
Sean las matrices A y B, representadas en matemáticas así: :
Observación: para la suma y resta de matrices, el rango de las matrices A y B deben ser
iguales, es decir m x n
A Columnas B Columnas
1 2 j n 1 2 j n
1 A11 A12 A1j A1n B11 B12 B1j B1n
2 A21 A22 A2j A2n B21 B22 B2j B2n
i +
m-
1 Ai1 Ai2 Aij Ain Bi1 Bi2 Bij Bin
22. m
Am-11 Am-12 Am-1j Am-1n Bm-11 Bm-12 Bm-1j Bm-1n
Am1 Am2 Amj Amn Bm1 Bm2 Bmj Bmn
La matriz suma será:
Columnas
S 1 2 j n
1
A11+ B11 A12+ B12 ... A1j+ B1j ... A1n+ B1n
2
A21+ A21 A22+ B22 ... A2j+ B2j ... A2n+ B2n
i
Ai1+ Bi1 Ai2+ Bi2 ... Aij+Bij .. Ain+ Bin
m- Am-11+ Bm-11 Am-12+ Bm-12 ... Am-1j+ Bm-1j ... Am-1n+ Bm-1n
1 Am1+ Bm1 Am2+ Bm2 ... Amj+ Bmj ... Amn+ Bmn
m
La instrucción representativa para cada elemento de la matriz suma S, será:
En Matemáticas: Sij = Aij + Bij
En algoritmos y en C++ S [ i ] [ j ] = A[ i ] [ j ] + B[ i ] [ j ]
Se repite para cada elemento de la matriz S
E2) Restar Matrices:
La matriz Resta será :
Columnas
R 1 2 j n
A11-B11 A12-B12 A1j-B1j A1n -B1n
1
A21-A21 A22-B22 A2j-B2j A2n-B2n
2
i
m- Ai1-Bi1 Ai2-Bi2 Aij-Bij Ain-Bin
1
m
Am-11-Bm-11 Am-12-Bm-12 Am-1j-Bm-1j Am-1n-Bm-1n
23. Am1-Bm1 Am2-Bm2 Amj-Bmj Amn-Bmn
La instrucción representativa para cada elemento de la matriz resta R será:
En Matemáticas: Rij = Aij + Bij
En algoritmos y en
R [ i ] [ j ] = A[ i ] [ j ] - B[ i ] [ j ]
C++
Se repite para cada elemento de la matriz R
Programas en C++ para sumar y restar arreglos Bidimensionales
SUMA ARREGLOS RESTA ARREGLOS
void main() void main()
{ {
const int M=4, N=5; const int M=4, N=5;
// Declaración de Variables // Declaración de Variables
int i; int i;
int A[M][N], B[M][N], S[M][N]; int A[M][N], B[M][N], R[M][N];
........ // Leer o inicializar Arreglo A ........ // Leer o inicializar Arreglo A
....... // Leer o inicializar Arreglo B ....... // Leer o inicializar Arreglo B
// Recorrido del Array A // Recorrido del Array A
for ( i= 0 ; i < M ; i =i+1 ) for ( i= 0 ; i < M ; i =i+1 )
{ {
for (j=0; j<N ; j=j+1) for (j=0; j<N ; j=j+1)
{// suma elemento por elemento {// suma elemento por elemento
S[i] = A [ i ] + B[i] R[i] = A [ i ] - B[i]
; ;
} }
} }
.... // Muestra arreglo S .... // Muestra arreglo S
} }
E3) Multiplicar escalar por Matriz:
Columnas
C 1 2 j n
k*A11 k*A12 k*A1j k*A1n
1 k*A21 k*A22 k*A2j k*A2n
2
i
m-
k*Ai1 k*Ai2 k*Aij k*Ain
1
m k*Am-11 k*Am-12 k*Am-1 k*Am-1n
k*Am1 k*Am2 k*Amj k*Amn
24. La instrucción representativa para cada elemento de la matriz C, será :
En Matemáticas: Cij = k * Aij
En algoritmos y en C++ C [ i ] [ j ] = k * A[ i ] [ j ]
Se repite para cada elemento de la matriz C
Un subprograma es una serie de instrucciones escritas independientemente del programa
principal. Este subprograma está ligado al programa principal mediante un proceso de
transferencia/retorno.
Ejemplo 12
• Título:
– Subprograma de suma
• Nombre
– Ej12
• Descripción
– Escribir un subprograma que calcule la suma de dos números
• V1: función con dos parámetros de entrada y devuelve el resultado
• V2: procedimiento con dos parámetros de entrada y uno de salida
• V3: procedimiento con un parámetro de entrada y otro de entrada/salida
• Observaciones
– Ejemplo ilustrativo con cuerpo de cálculo evidente
– Paso de parámetros
– Los procedimientos no “devuelven” nada (usan parámetros de salida)
25.
26.
27.
28. ¿Que es una función?
Una función es un grupo de instrucciones con un objetivo en particular y que se ejecuta
al ser llamada desde otra función o procedimiento. Una función puede llamarse
múltiples veces e incluso llamarse a sí misma (función recurrente).
Las funciones pueden recibir datos desde afuera al ser llamadas a través de los
parámetros y deben entregar un resultado.
Se diferencian de los procedimientos porque estos no devuelven un resultado.
En general las funciones deben tener un nombre único en el ámbito para poder ser
llamadas, un tipo de dato de resultado, una lista de parámetros de entrada y su código.
Cuando una función es invocada se le pasa el control a la misma, una vez que esta
finalizó con su tarea el control es devuelto al punto desde el cual la función fue llamada.
29. ¿Que es un procedimiento?
Porción de código dentro de un programa más grande, que realiza una tarea específica
y es relativamente independiente del resto del código. La mayoría de los lenguajes de
programación incluyen soporte para la creación de procedimientos (u otros tipos de
subrutinas, como funciones o módulos).
Los procedimientos suelen utilizarse para reducir la duplicación de códigos en un
programa, permitir reusar los códigos, descomponer problemas complejos en piezas
simples (mejorando la mantenibilidad y facilidad de extensión del código), mejora la
lectura del código de un programa, oculta o regula parte de un programa, etc.
Los procedimientos son ejecutados cuando son llamados desde otros procedimientos,
funciones o módulos. Los procedimientos pueden recibir parámetros, pero no necesitan
devolver un valor como las funciones.
Ejemplo 1
Programa que suma dos numeros utilizando un Procedimiento.
Pseudocódigo
1Inicio
2dN1<-0, dN2<-0
3Leer "Numero 1", dN1
4Leer "Numero 2", dN2
5Llama Suma (dN1)
6Fin
1//Aqui empieza el procedimiento
2Procedimiento Suma (dN1a, dN2a)
3dSuma <- 0
4dSuma<-0 dN1a+dN2a
5Imprimir "El total es: ", dSuma
6Fin Procedimiento
Diagrama de Flujo
Vemos que tenemos un nuevo símbolo el cual corresponde a la llamada a un procedimiento o
funcion.
30. Este es el diagrama correspondiente al principal.
Este es el diagrama correspondiente al procedimiento.
31. Código
1 #include<iostream.h>
2 #include<conio.h>
3
4 //DECLARACION DE PROCEDIMIENTO
5 void fSuma(float,float);
6
7 //INICIO DEL PRINCIPAL
8 main()
{
9
//DECLARACIÓN DE VARIABLES
10
float dN1,dN2;
11
12
//DATOS DE ENTRADA
13
cout<<"Numero 1:";
14
cin>>dN1;
15
cout<<"Numero 2:";
16
cin>>dN2;
17
18
//LLAMADA A PROCEDIMIENTO
19
fSuma(dN1,dN2);
20getch();
21}
22
23//INICIO DE PROCEDIMIENTO
24void fSuma(float dN1a,float dN2a)
25{
26//DECLARACIÓN DE VARIABLES
27float dSuma;
32. 28
29//PROCESO
30dSuma=dN1a+dN2a;
31
32//SALIDA
33cout<<"El total es: "<<dSuma;
}
34
35
Ejemplo Ejecutado
Un puntero es una variable que tiene la dirección de memoria de otra variable que contiene
un valor.
Gráfica 1. Dirección de memoria.
33. La dirección es la posición que ocupa en la memoria una variable, un arreglo, una cadena,
una estructura, otro puntero, etc.
Normalmente las variables contienen valores específicos. En cambio, los punteros contienen
direcciones de variables que contienen valores específicos.
Si una variable contiene la dirección de otra variable entonces se dice que: “la primera variable
apunta a la segunda”.
Gráfica 2. Puntero de una variable a otra variable.
En este sentido, los nombres de variables hacen referencia directa a un valor y los
punteros hacen referencia indirecta a un valor. La referencia a un valor a través de un
puntero se llama indirección.
Gráfica 3. Referencia directa e indirecta a una variable.
cont hace referencia directa a una variable cuyo valor es 23
cont hace referencia indirecta a una variable cuyo valor es 23
Existen tres razones para usar punteros en la creación de programas:
- Los punteros proporcionan los medios mediante los cuales las funciones modifican sus
argumentos de llamada.
- Se pueden utilizar para soportar las rutinas de asignación dinámica del C++.
- Se puede sustituir por arreglos en muchas situaciones para incrementar la eficacia.
34. Variable Puntero
Sintaxis : tipo *nombre_variable;
Propósito : Declarar si una variable contiene una dirección de memoria. Donde tipo puede
ser cualquier tipo base del C++, y éste define a que tipo de variable puede apuntar el puntero.
Ejemplo : int *punt, k;
Esta sentencia declara que punt apunta a un valor u objeto de tipo entero. Cada variable que
se declara como puntero debe ir precedida por un *.
Los punteros se deben inicializar a 0, a NULL o a una dirección, al declararlos o mediante una
asignación, para evitar que apunten a áreas desconocidas de memoria.
Operadores Puntero
Existen dos operadores especiales de punteros:
& : Operador de dirección, devuelve la dirección de memoria de su operando (variable a la
que precede).
Gráfica 4. Aplicación del operador de dirección.
punt = &cont;
Coloca la dirección de memoria 3500 de la variable cont en punt y la variable puntero punt
está ubicada en la dirección 4000. Esta dirección es una posición interna del ordenador y no
tiene que ver con el valor de cont.
Se lee que punt “recibe la dirección del valor” cont.
* : Operador de indirección, es el complemento de &, devuelve el valor de la variable
situada en la dirección que sigue (sinónimo de la variable hacia el que apunta su operando).
valt = *punt;
Si punt contiene la dirección de memoria de la variable cont, entonces coloca el valor de cont
en valt. Ejemplo, si cont al inicio tenía el valor 23, entonces, después de esta asignación, valt
tendrá el valor 23 ya que es el valor guardado en la posición 3500, que es la dirección de
memoria que asignó a punt.
Recordar al * como “en la dirección”.
Se lee como que valt “recibe el valor de dirección” punt.
El proceso que consiste en reportar el valor de una variable precedida por un * se conoce
como desreferenciación de un puntero.
Ejemplo: cout<<*punt;
Esta sentencia reporta el valor de la variable cont, es decir 23.
También puede utilizarse un puntero desreferenciado del lado izquierdo de una sentencia de
asignación.
Ejemplo: *punt = 25;
Esta sentencia asigna el valor 25 a la variable cont.
35. El puntero desreferenciado también puede usarse para recibir un valor de entrada.
Ejemplo: cin>>*punt;
Como el signo de multiplicación y el de “en la dirección” es el mismo, al escribir un programa,
tener en cuenta que estos operadores no tienen relación.
& y * tienen una precedencia más alta que el resto de operadores aritméticos.
El tipo base del puntero determina el tipo de datos que el compilador asumirá que apunta el
puntero.
Como punt es un puntero entero, C++ copia dos bytes en valt desde la dirección a la que
apunta punt.
Expresiones con Punteros
a) Se puede usar un puntero en la parte derecha de una sentencia de asignación para
asignar el valor del puntero a otro puntero. Ejemplo:
int t, *x, *y;
t = 450; x = &t; y = x;
cout<<“La dirección es : ”<< y;
Este fragmento de programa visualiza la dirección de t en hexadecimal, y no el valor de t.
b) En aritmética convencional el resultado de 3000+2 es 3002. Pero en aritmética de
punteros esto no es así, pues si a un puntero se le suma (+) o resta (-) un entero; dicho
puntero no aumenta o disminuye en la misma cantidad que el entero, sino en el entero por el
número de bytes de la variable hacia la que apunta. Número de bytes depende de tipo de dato
de variable.
Ejemplo: x += 7;
Si la variable x es de tipo entero; entonces, después de esta operación, x apuntará a la
dirección 3014 (3000 + 7 * 2), ya que los enteros poseen dos bytes.
Si el ejemplo hubiera sido: x – = 4;
Entonces x apunta a la dirección 2992 (3000 – 4 * 2).
c) Se pueden incrementar (++) o disminuir (- -) punteros. Por ejemplo: sea y un puntero a
un número flotante con la dirección actual 3500.
Después de la expresión: y++; la dirección de y será 3504 y no 3501.
Cada vez que se incrementa y, la computadora apuntará al siguiente flotante, que usa cuatro
bytes.
Gráfica 5. Variación de un puntero.
36. d) Es posible asignar un apuntador a otro, si ambos son del mismo tipo. De otro modo, es
necesario emplear un operador de conversión mediante cast para convertir el valor del
apuntador del lado derecho de la asignación al tipo de apuntador a la izquierda de la
asignación.
e) Es posible comparar dos punteros en una relación:
if(g>h) cout<<“g apunta a dirección más alta que h”;
Se usan las comparaciones de punteros, generalmente, cuando dos o más punteros apuntan
a un objeto común.
f) No se pueden realizar otras operaciones sobre punteros; es decir, no se puede multiplicar
o dividir punteros, no se puede sumar o restar dos punteros y no se puede sumar o restar los
tipos float o double a punteros.
Punteros y Arreglos
Como la velocidad es una consideración frecuente en programación, el uso de punteros es
más común que el método de indexación de arreglos, debido a que C++ tarda más en indexar
un arreglo que lo que hace el operador *.
El método de los punteros requiere de las siguientes consideraciones:
a) Un nombre de arreglo sin índice, es la dirección del comienzo del arreglo. Es decir, el
nombre de un arreglo es un puntero al arreglo. Ejemplo:
char w[50], *x;
x = w;
Aquí se pone en x la dirección de 1er. elemento de w.
b) Debido a que los índices de arreglos comienzan en cero; para acceder a un determinado
elemento de un arreglo; por ejemplo el cuarto elemento de w, se puede escribir:
w[3] ó *(w+3)
c) En el caso del arreglo bidimensional g, cuyos contadores i y j se inicializan a partir de
cero, el acceso puede especificarse como:
g[i][j] ó *(*(g + i) + j)
d) Se puede indexar un puntero como si fuera un arreglo: int g[7] = {1, 2, 3, 4, 5, 6, 7}; int j,
*x;
x = g; for(j=0; j<7; j++) cout<<x[j];
Aquí se visualiza en la pantalla los números del 1 al 7.
37. e) El C++ trata a las cadenas como punteros al primer carácter de cadena y no como
cadena propiamente dicha
strlen(char *q) {
int j = 0;
while(*q) { j++; q++; }
return j; }
Recordar que toda cadena termina en un nulo (o falso).
while(*q)
Es verdad hasta que se alcance el final de la cadena.
f) Si se quiere acceder al arreglo aleatoriamente, es mejor la indexación, ya que es tan
rápido como la evaluación por punteros y porque es más fácil programar.
g) Se puede asignar la dirección de un elemento específico de un arreglo aplicando el & a
un arreglo indexado:
q = &y[7];
Esta sentencia coloca la dirección del octavo elemento de y en q. Esto es útil en la localización
de subcadenas.
char w[60],*y; int t;
cout<<“Introducir una cadena: ”; gets(w);
for(t=0; w[t] && w[t]==’’;t++);
y = &w[t]; cout<<y;
Esto imprime el resto de una cadena, que se introdujo por teclado, desde el punto en que la
computadora encuentre el primer espacio o el final de la cadena.
h) Recordar que el acceso a una cadena individual se especifica solamente con el índice
izquierdo.
gets(y[i]);
Esta sentencia es funcionalmente equivalente a:
gets(&y[i][j]);
i) Se pueden hacer arreglos de punteros. Ejemplo:
int *b[10];
Declara un arreglo de punteros int de tamaño 10.
j) Para asignar una dirección de variable entera llamada z al quinto elemento del arreglo de
punteros, se escribirá:
b[4] = &z;
y para encontrar el valor de z se escribirá: *b[4]
38. Las listas son una sucesión de cero o más elementos.
Esta es una definición muy simple y que no aclara demasiado en términos informáticos, así
que profundizaremos un poco más.
Hay varios tipos de listas, las hay enlazadas, no enlazadas, ordenadas y no ordenadas.
Nosotros vamos a estudiar las listas enlazadas, tanto ordenadas como no ordenadas.
La diferencia que existe entre las listas enlazadas y las no enlazadas es que las enlazadas
utilizan punteros, es decir, asignación dinámica de memoria, lo que optimiza la gestión de la
misma. Una lista no enlazada es un simple array, y por lo tanto es un bloque contiguo de
memoria, mientras que una lista enlazada es un conjunto de nodos que no tienen porque
ocupar posiciones contiguas de memoria.
La diferencia entre listas ordenadas y no ordenadas es obvia, las ordenadas mantienen cierto
orden entre sus elementos.
A partir de ahora nos centraremos en las listas enlazadas no ordenadas.
Una lista es una sucesión de nodos en la que a partir de un nodo se puede acceder al que
ocupa la siguiente posición en la lista. Esta característica nos indica que el acceso a las listas
es secuencial y no indexado, por lo que para acceder al último elemento de la lista hay que
recorrer los n-1 elementos previos ( n es el tamaño de la lista).
Para que un nodo pueda acceder al siguiente y la lista no se rompa en varias listas cada nodo
tiene que tener un puntero que guarde la dirección de memoria que ocupa el siguiente
elemento. De esta forma un nodo se podría representar esquemáticamente así:
En el campo información se almacena el objeto a guardar y el puntero mantendrá la conexión
con el nodo siguiente.
De esta forma al ir añadiendo nodos se iría formando una sucesión de nodos encadenados
mediante punteros.
39. Operaciones básicas de las listas
En toda estructura de datos hay dos operaciones que sobresalen por encima del resto:
Insertar y borrar. Estas dos operaciones aparecerán en toda estructura de datos, puede que
con otro nombre, o con una funcionalidad ligeramente diferente, pero su filosofía será la
misma, proporcionar unas operaciones para la construcción de la estructura de datos.
Insertar
La operación insertar consiste en la introducción de un nuevo elemento en la lista.
En una lista no ordenada no es necesario mantener ningún orden, por lo tanto la inserción de
elementos se puede realizar en cualquier lugar de la lista, al principio, al final, en una posición
aleatoria,...
Generalmente se realiza la inserción de tal forma que la complejidad temporal sea mínima, es
decir, que sea una operación sencilla para que se realice en el menor tiempo posible. La
operación más sencilla depende de la implementación de la estructura de datos, en unos
casos puede ser la inserción al inicio, en otros la inserción al final y en este caso la inserción
la realiza en el segundo nodo de la lista.
Si tenemos la lista...
... e insertamos el elemento 0, la lista quedaría de la siguiente forma:
Borrar
La operación borrar consiste en la eliminación de la lista de un elemento concreto. El elemento
a borrar será escogido por el programador.
La eliminación en una lista no conlleva ningún trabajo adicional más que el propio de la
eliminación del elemento en sí. Para borrar un elemento cualquiera habría que realizar un
recorrido secuencial de la lista hasta encontrar el nodo buscado y una vez localizado
reestructurar los punteros para saltarse el nodo a borrar y así poder eliminarlo.
Vamos a verlo con un ejemplo. Borrado del elemento 76 en la lista anterior:
Paso 1: Localizar el elemento a borrar.
Paso 2: Reestructurar punteros y eliminar nodo.
Otras operaciones
A partir de estas dos operaciones básicas cada lista puede presentar muchas operaciones
diferentes, vamos a comentar algunas de ellas, dejando claro que las dos básicas que
siempre aparecerán son las anteriores.
40. Tamaño: Esta operación suele informar sobre el número de elementos que tiene en ese
instante la lista.
Buscar: Comprueba si existe un determinado elemento en la lista.
Recorrer lista: Recorre toda la lista, realizando una operación en cada nodo. Por
ejemplo, mostrar el contenido por pantalla.
En este capítulo se definirá el concepto de pilas implementada con arreglo de registros.
Además se describen algunas de sus operaciones más importantes.
Definición
Una PILA es una estructura ordenada y homogénea, en la que podemos apilar o desapilar
elementos en una única posición llamada CIMA, siguiendo una política LIFO (Last In, First
Out).
Pilas
Representación de pilas con arreglos
Utilizaremos un arreglo llamado Pila de tamaño máximo MaxElemPila y una variable llamada
Cima que indicará cual es el último elemento ocupado en el arreglo (es decir la variable Cima
contiene la posición del elemento que se encuentra en la cima de la pila).
Representación de pilas con arreglos
41. Operaciones
Las operaciones son:
- CrearPila : Inicializa la pila en el estado vacío.
- PilaVacía : Determinar si la pila está vacía.
- PilaLlena : Determina si la pila está llena.
- Apilar : Agrega un nuevo elemento a la pila.
- Desapilar : Elimina el dato que se encuentra en la cima de la pila.
- CimaPila : Permite capturar el elemento que está en la cima de la pila, sin eliminarlo.
Implementación:
Archivo:
- Pilas.vb
- Pilas.cpp
Operación Crear Pila
{
Objetivo : Inicializar al estado vacío.
Entrada : Pila, Cima, MaxElemPila
Precondiciones : Cima correspondiente a una pila
Salida : Cima
Postcondiciones: Pila está vacía. Cima tiene valor inicial de cero
}
Función CrearPila (?Pila, ?Cima, MaxElemPila)
Inicio
Pila = Memoria [MaxElemPila]
Cima = 0
Fin
Operación Pila Vacía
{
Objetivo: Indica si pila está vacía.
Entrada: Cima
Precondiciones: Cima de una pila
Salida: Valor verdadero o falso.
Postcondiciones: PilaVacia es un valor lógico verdadero si pila está vacía y falso en caso
contrario
}
42. Logico Función PilaVacia (Cima )
Inicio
Si ( Cima == 0 ) entonces
retorna verdadero
Sino
retorna falso
Fin_si
Fin
Operación Pila Llena
{
Objetivo: Indica si pila está llena.
Entrada: Cima, MaxElemPila
Precondiciones: Parámetros de la pila a ser probada
Salida: Valor lógico de la función.
Postcondiciones: valor lógico verdadero si pila está llena y falso en caso contrario
}
Logico Función PilaLlena (Cima, MaxElemPila )
Inicio
Si (Cima ==MaxElemPila) entonces
retorna verdadero
Sino
retorna falso
Fin_si
Fin
Operación Apilar
{
Objetivo: Añade NuevoElemento a la cima de la pila
Entrada: Pila, Cima, NuevoElemento, MaxElemPila
Precondiciones: Pila no está llena
Salida: Pila
Postcondiciones: Pila original con NuevoElemento añadido a la cabeza.
}
Procedimiento Apilar (?Pila, ?Cima, NuevoElemento, MaxElemPila )
Inicio
Si (PilaLlena (Cima, MaxElemPila) == verdadero) entonces
43. Escribir “Pila llena”
Sino
Cima = Cima + 1
Pila [Cima] = NuevoElemento
Fin_si
Fin
Operación Desapilar
{
Objetivo: Quita el elemento cima de la pila y lo devuelve en ElemSacado.
Entrada: Pila, Cima, ElemSacado.
Precondiciones: Pila no está vacía, ElemSacado no tiene valor
Salida: Pila, Cima, ElemSacado.
Postcondiciones: Pila original con elemento cima quitado. Pila y ElemSacado con valor.
}
Procedimiento Desapilar (?Pila, ?Cima, ?ElemSacado )
Inicio
Si (PilaVacia (Pila,Cima) == verdadero) entonces
Escribir “Pila vacia”
Sino
ElemSacado = Pila [Cima]
Cima = Cima - 1
Fin_si
Fin
Operación CimaPila
{
Objetivo : Captura el elemento que está en la cima de la pila sin eliminarlo.
Entrada : Pila, Cima
Precondiciones : Pila no está vacía
Salida : Pila, Cima, valor de la función
Postcondiciones : Pila original
}
Entero Funcion CimaPila (Pila,Cima)
Inicio
Si (PilaVacia Cima) == verdadero) entonces
Escribir “Pila vacia”
44. Retorna -1
Sino
retorna Pila [Cima]
Fin_si
Fin
Aplicaciones de pilas
Las Pilas son una estructura de datos muy usado en la solución de diversos tipos de
problemas. Estos son algunos de los casos más representativos de aplicación de pilas:
- Llamadas a subprogramas.
- Tratamiento de expresiones aritméticas.
Llamadas a subprogramas
Uno de los usos más comunes de la pila es el de almacenar la información de las sucesivas
llamadas a subrutinas en un programa, lo que nos permitirá volver de las mismas tras su
finalización.
Fig. 5.3 Llamadas a subprogramas
En el programa P, la instrucción r-1 es una llamada al procedimiento A1; sabemos que esta
instrucción implica pasar a la ejecución de A1 y cuando éste finalice, pasa a ejecutar la
instrucción siguiente, esto es la r.
Por su parte, la instrucción s-1 de A1 supone la ejecución de una llamada a A2. Se pasa el
control a A2 y cuando finalice pasa a ejecutar la posición s. Este proceso puede repetirse un
número cualquiera de veces, y es necesario disponer de un mecanismo que nos permita
ejecutar las instrucciones en el orden adecuado.
En la memoria del ordenador, el Sistema Operativo reserva una zona que se denomina pila
que se maneja como una estructura de datos de este tipo, es decir, siguiendo una política
LIFO. El uso de esta pila nos ayuda a almacenar la información necesaria para poder devolver
el control de forma correcta después de cada llamada: cuando se realiza una llamada a un
subprograma, además de otra información relacionada con los argumentos del mismo, se
almacena en la pila la dirección de retorno. Cada vez que finalice la ejecución de un
subprograma, en la cima de la pila tendremos la información necesaria para saber en que
instrucción nos habíamos quedado cuando realizamos la llamada. Al volver del subprograma,
45. eliminaremos del tope de la pila la dirección de retorno, lo que dejará como nuevo tope la
información necesaria para volver al finalizar el subprograma actual.
Información en la pila durante el desarrollo del programa
El gráfico de la figura representa en forma simplificada, la información que tendremos en la
pila del sistema durante el desarrollo del programa del ejemplo anterior:
Tratamiento de expresiones aritméticas
Un problema interesante en computación es poder convertir expresiones en notación infija a
su equivalente en notación postfija (o prefija).
Notación Infija : ejemplo A + B, operador entre operandos.
Notación Postfija : ejemplo AB+, operador después de los operandos.
Notación Prefija : ejemplo +AB, operador antes de los operandos.
Ventaja: En las expresiones en notación prefija y postfija no son necesarios los paréntesis
para indicar orden de operación ya que este queda establecido por la ubicación de los
operadores con respecto a los operandos.
Prioridad de los operadores
1. ( ) paréntesis
2. ^ potencia
3. *, / multiplicación y división
4. +, - sumas y restas
Los operadores con igual prioridad se procesan de izquierda a derecha.
Ejemplo
Traducir la expresión infija X + Y *W a notación postfija.
46. Notación postfija
Ejemplo
Traducir la expresión infija X + Y *W a notación prefija.
Notación prefija
Recursividad
La recursividad es una característica de los lenguajes de programación en virtud de la cual se
permite que un procedimiento haga referencia a sí mismo dentro de su definición.
La definición recursiva debe estar hecha de manera que la cadena de invocaciones termine en
algún momento con una llamada que no genere nuevas invocaciones.
La recursión en los subprogramas puede darse de dos maneras diferentes:
a) Directa: El subprograma se llama directamente a sí mismo.
Recursión directa
b) Indirecta: El subprograma llama a otro subprograma y éste a su vez llama al primero.
Recursión indirecta
47. La construcción de estos procedimientos no sigue una fórmula concreta, pero el programador
puede utilizar la noción de inducción de la siguiente forma:
1. Solucionar el caso/s más simple. Caso base.
2. Expresar el caso general en función de casos más simples que tiendan hacia el caso base.
3. Desarrollar el algoritmo recursivo, que en general tendrá la siguiente estructura:
Si estamos en un caso base entonces
Devolver la solución al caso base
Sino
- Descomposición del problema
- Llamada recursiva
- Obtención de la solución a partir del resultado obtenido en la llamada recursiva.
- Devolver solución.
Fin si
Ejemplo 1:
Escriba una función recursiva que permite calcular el factorial de un número entero positivo.
¨ Caso base:
Factorial (0) =1
¨ Enunciado General:
Factorial(n) = n * Factorial(n-1)
¨ Algoritmo recursivo:
Entero Función Factorial (n)
Inicio
Si (n = 0) entonces
Fact =1
Sino
Fact = n * Factorial(n-1)
Fin si
Devolver Fact
Fin
48. Simulación de ejecución del algoritmo
Ejercicios Resueltos
Ejercicio1. Considere la operación Reemplazar (Pila, ElemAntiguo, ElemNuevo) que consiste
en reemplazar todas las ocurrencias de un valor ElemAntiguo en la pila Pila por un nuevo
valor ElemNuevo. Escribir el algoritmo para esta operación. Utilice las operaciones sobre pilas
estudiadas en clase pero no asumir ninguna representación de pilas
Solución:
Algoritmo Reemplazar (?Pila, CimaPila, MaxElemPila, ElemAntiguo, ElemNuevo)
Inicio
CrearPila (PilaAux,cimaAux, MaxElemPilaAux)
Repetir mientras (PilaVacia (cimaPila)==Falso)
Desapilar (Pila, CimaPila, X)
Si(X== ElemAntiguo) entonces
Apilar (PilaAux, cimaAux, ElemNuevo, MaxElemPilaAux)
Sino
Apilar (PilaAux, cimaAux, X, MaxElemPilaAux)
Fin si
Fin repetir
Repetir mientras (PilaVacia (cimaAux) ==Falso)
Desapilar (PilaAux, CimaAux, X)
Apilar (Pila, CimaPila, X, MaxElemPila)
Fin repetir
Fin
49. Ejercicio 2. Formule un algoritmo que particione una pila P en dos pilas P1, P2, de la
siguiente manera: los valores menores que un valor dado x son ubicados en P1, los otros se
ubican en P2. Emplee solo operaciones de pilas. No asuma ninguna implementación en
particular.
Solución:
Algoritmo Particionar (?P, CimaPila, max, X, ?P1, ?P2, ?cimaP1, ?cimaP2)
Inicio
CrearPila (P1,cimaP1, max)
CrearPila (P2, cimaP2, max)
Repetir mientras (PilaVacia (CimaPila)== Falso)
Desapilar (P, CimaPila, z)
Si ( z < X) entonces
Apilar (P1, cimaP1, z, max)
Sino
Apilar (P2, cimaP2, z, max)
Fin si
Fin repetir
Fin
Ejercicio 3. Considere la operación CopiaArriba (P1, cimaP1, P2, cimaP2, P3, cimaP3, tam3)
que copia la primera pila P1 en la segunda pila P2 en el mismo orden. Escriba el algoritmo
correspondiente a esta operación. Use las operaciones de Pila.
Solución:
Algoritmo CopiaArriba (P1, cimaP1, P2, cimaP2, ?P3, ?cimaP3, tam3)
Inicio
MaxAux=tam3
CrearPila(P3,cimaP3, cimaP3)
CrearPila (PAux, cimaAux, MaxAux)
Repetir mientras (PilaVacia (cimaP1) == falso)
Desapilar (P1, cimaP1, X)
Apilar (PAux, cimaAux, X, maxAux)
Fin repetir
50. Repetir mientras (PilaVacia (cimaP2) == falso)
Desapilar (P2, cimaP2, X)
Apilar (PAux, cimaAux, X, maxAux)
Fin repetir
Repetir mientras (PilaVacia (cimaAux) == falso)
Desapilar (PAux, cimaAux, X)
Apilar (P3, cimaP3, X, tam3)
Fin repetir
Fin
Ejercicio 4. Considere la operación EliminarDato (Pila, cimaPila, Dato, MaxElemPila), que
consiste en eliminar de la pila P el elemento Dato. Escriba el algoritmo correspondiente a esta
operación. Use las operaciones de Pila.
Solución:
En caso hubieran más elementos Dato, solamente elimina el primero.
Algoritmo EliminarDato (?Pila, ?cimaPila, Dato, MaxElemPila)
Inicio
maxAux= MaxElemPila
CrearPila (PAux, cimaAux, maxAux)
Sw = 0
Repetir mientras (PilaVacia (cimaPila) == Falso y Sw == 0)
Desapilar (Pila, cimaPila, x)
Si (x ¹Dato) entonces
Apilar (PAux, cimaAux, x, MaxAux)
Sino
Sw= 1
Fin si
Fin repetir
Repetir mientras (PilaVacia (cimaAux) ==Falso)
Desapilar (PAux, cimaAux, Y)
Apilar (Pila, cimaPila, Y, MaxElemPila)
Fin repetir
51. Fin
Ejercicio 5. Considere un arreglo lineal llamado A el cual almacena n números enteros,
escriba un algoritmo recursivo que permita buscar un elemento llamado Val.
Solución:
Lógico Función BuscarValor (A, n, Val)
Inicio
Si (n ==1) entonces
Si A[n]= Val entonces
Buscar = verdadero
Sino
Buscar = BuscarValor(A, n-1, Val)
Fin si
Sino
Buscar = falso
Fin si
Devolver Buscar
Fin
Ejercicio 6. Considere un arreglo lineal llamado A el cual almacena n números enteros,
escriba un algoritmo recursivo que permita calcular el elemento más grande.
Solución:
Entero Función Mayor (A, n)
Inicio
Si (n==1) entonces
May = A[n]
Sino
Si (A[n]> Mayor(A, n-1)) entonces
May = A[n]
Sino
May = Mayor(A, n-1)
Fin si
Fin si
Devolver May
Fin
Ejercicio 7. El coeficiente binomial C(n, m) indica el número de maneras de escoger m
objetos entre n objetos.
52. Se conoce la relación C(n, m) = C(n-1, m-1) + C(n-1, m)
a) Formule un algoritmo recursivo para calcular C(n, m).
Solución
Entero Función C (n, m)
Inicio
Si (m == 1) entonces
Comb = n (Caso Base 1)
Sino si (n == m) entonces
Comb = 1 (Caso Base 2)
Sino (Caso General)
Comb = C (n-1, m-1) + C (n -1, m)
Fin si
Devolver Comb
Fin
b) Identifique el caso base.
Solución
m = 1, ? C = n
m = n, ? C = 1
Colas
En este capítulo se definirá el concepto y uso de la estructura y algoritmos de colas. Será
implementado con arreglos, describiéndose las operaciones en colas simples, colas circulares,
colas con prioridades y bicolas.
Definición y uso
Es una lista de elementos en la que las eliminaciones se realizan solo en un extremo llamado
el frente y las adiciones se realizan en el otro extremo llamado final (FIFO, First Input First
Output). La atención de un grifo es un ejemplo de cómo funciona una cola,
Colas
Se utilizan por ejemplo en los sistemas operativos en las salidas a impresora formando una
cola de impresión. Los trabajos en proceso forman cola para ser atendidos.
53. Representación de colas con arreglos
Una cola se puede implementar mediante un arreglo. Además se requiere una variable Frente
(la posición del extremo izquierdo) por donde se extrae elementos y una variable Final (la
posición del extremo derecho) por donde se añaden elementos. Además se requiere un
tamaño de cola N.
Representación de colas con arreglos
La implementación utiliza la siguiente definición: Cola: arreglo [1..N]
Operaciones
Las operaciones de cola son:
- Crear cola: inicializa la cola en el estado vacío.
- Cola vacía: determina si la cola está vacía.
- Cola llena: determina si la cola está llena.
- Encolar: añadir un nuevo elemento a la cola. Implica incrementar en uno el valor de Final y
luego ubicar el último elemento en la nueva posición.
- Desencolar: extraer el elemento que se encuentra en el frente y avanzar Frente un lugar.
Implementación
Archivo:
- PrincipalCola.cpp
- PrincipalCola.vb
Crear cola
{
Objetivo: Crear una cola vacía
Entrada: Frente, Final
Precondición: Ninguna
Salida: Frente, Final
Postcondición: Cola definida y vacía
}
54. Procedimiento CrearCola(#Cola, N, #Frente, #Final)
Inicio
{Definir Cola de tamaño N}
Frente = 0
Final = 0
Fin
Cola vacía
{
Objetivo: Indicar si la cola tiene o no elementos
Entrada: Frente
Precondición: Ninguna
Salida: Valor lógico
Postcondición: Indica si está vacío o no
}
Lógico Función ColaVacía(Frente)
Inicio
Si (Frente == 0) entonces
retornar verdadero
Sino
retornar falso
Fin si
Fin
Cola Llena
Cola llena
{
Objetivo: Indicar verdadero si la cola tiene el máximo número de elementos
Entrada: Final,N
Precondición: Ninguna
Salida: Indicador lógico
Postcondición: Indica si está llena o no
55. }
Lógico Función ColaLlena(Final, N)
Inicio
Si (Final == N) entonces
retorna verdadero
Sino
retorna falso
Fin si
Fin
Agregar un elemento a la cola – Encolar
{
Objetivo: Añade un elemento al final de la cola
Entrada: Cola, Frente, Final, N, NuevoElemento
Precondición: Ninguna
Salida: Cola, Frente, Final
Postcondición: Cola original con nuevo elemento añadido al final
}
Procedimiento Encolar(Cola, Frente, Final, N, NuevoElemento)
Inicio
Si (ColaLLena (Final, N) == verdadero) entonces
Escribir “Cola llena”
sino
Si (ColaVacia (Frente) == verdadero) entonces
Frente = 1
Final = 1
Sino
Final = Final + 1
Fin si
Cola [Final] = NuevoElemento
Fin si
Fin
Extraer un elemento a la cola – Desencolar
{
Objetivo: Extraer un elemento del frente de la cola
Entrada: Cola, Frente, Final, ElementoExtraido (sin valor)
Precondición: Ninguna
56. Salida: Cola, Frente, Final, ElementoExtraido (con valor)
Postcondición: Cola con elemento extraído del frente
}
Procedimiento Desencolar(Cola, Frente, Final, ElementoExtraido)
Inicio
Si (ColaVacia (Frente) == verdadero) entonces
Escribir “Cola vacía”
Sino
ElementoExtraido = Cola [Frente]
Si (Frente == Final) entonces
Frente = 0
Final = 0
Sino
Frente = Frente + 1
Fin si
Fin si
Fin
Cola circular
Observando el gráfico de la figura, aparentemente la cola está llena, Final = N, sin embargo
podemos observar que existen celdas disponibles en la cual se pueden añadir más elementos.
Para usar este espacio se usan las Colas Circulares.
Cola con celdas disponibles
Colas circulares
57. Se debe tener en cuenta que en las colas circulares se presentan dos casos los cuales se
muestran en la figura.
Casos circulares
Operaciones de cola circular
Las operaciones de cola circular que son diferentes a las de cola simple son:
- Cola llena.
- Encolar.
- Desencolar.
Implementación
Archivo:
- PrincipalColaCircular.cpp
- PrincipalColaCircular.vb
Cola llena en cola circular
{
Objetivo: Indica si la cola está llena
Entrada: Frente, Final, N
Precondición: Ninguna
Salida: Indicador lógico
Postcondición: Indica si está llena o no
}
Lógico Función ColaLlenaCircular (Frente, Final, N)
Inicio
Si (Frente == 1 y Final == N o Final + 1 == Frente) entonces
retornar verdadero
Sino
retornar falso
58. Fin si
Fin
Encolar en cola circular
{
Objetivo: Añade un elemento al final de la cola
Entrada: Cola, Frente, Final, N, NuevoElemento
Precondición: Cola no llena
Salida: Cola, Frente, Final.
Postcondición: Cola original con nuevo elemento añadido al final
}
Procedimiento EncolarCircular (Cola, Frente, Final, N, NuevoElemento)
Inicio
Si (ColaLLenaCircular (Frente, Final, N) == verdadero) entonces
Escribir “Cola circular llena”
Sino
Si (ColaVacia (Frente) == verdadero) entonces
Frente = 1
Final = 1
Sino
Si (Final ==N) entonces
Final = 1
Sino
Final = Final + 1
Fin si
Fin si
Cola [Final] = NuevoElemento
Fin si
Fin
Desencolar cola circular
{
Objetivo: Extraer un elemento del frente de la cola
Entrada: Cola, Frente, Final, N, ElemExtraido
Precondición: Cola no está vacía
Salida: Cola, ElementoExtraido
Postcondición: Cola original con elemento del frente extraido
}
59. Procedimiento DesencolarCircular (?Cola,?Frente, ?Final, N, ? ElemExtraido)
Inicio
Si (ColaVacia (Frente) = verdadero) entonces
Escribir “Cola Circular vacía”
Sino
ElemExtraido = Cola [Frente]
Si (Frente = Final) entonces {la cola tiene un solo elemento}
Frente = 0
Final = 0
Sino
Si Frente = N entonces {si está en la última posición}
Frente = 1
Sino
Frente = Frente + 1
Fin si
Fin si
Fin si
Fin
Cola con prioridades
Son colas en que los elementos tienen asociada una prioridad. La implementación de colas
con prioridades puede ser utilizando listas enlazadas, arreglos paralelos y mediante arreglos
bidimensionales.
En el caso de arreglos bidimensionales, cada fila del arreglo bidimensional es considerada
una cola circular. Dos arreglos Frente y Final almacenan las posiciones de los elementos que
están en el frente y final de cada cola. Además cada fila representa la prioridad que tienen
esos elementos en ser procesados.
60. Cola con prioridades
Se aplican en sistemas operativos, en los que los programas de mayor prioridad se procesan
primero, a igualdad de prioridades se mantiene el orden de la cola.
Inserción en cola con prioridades con arreglos bidimensionales
Se busca la fila correspondiente a la prioridad del elemento a ser insertado y luego se inserta
al final de la cola, siempre que no esté llena.
Extracción en cola con prioridades con arreglos bidimensionales
Se busca la primera cola no vacía y se procede a extraer el elemento que está al frente de la
cola.
Bicolas
En este caso, se puede añadir o extraer elementos por cualquier extremo. Puede
implementarse en un arreglo como cola circular. En este caso se cumpliría que Bicola[Der] va
detrás de Bicola[Izq].
Bicolas
Ejercicios Resueltos
Ejercicio1. Algoritmo que elimina Dato de la Cola.
Procedimiento Eliminar(?Cola, ?Frente, ?Final, N, Dato)
Inicio
CrearCola( C1, N1, Frente1, Final1)
Sw = 1
61. Repetir mientras (ColaVacia (Frente) ==Falso y Sw ==1 )
Desencolar (Cola, Frente, Final, X)
Si (X ==Dato) entonces
Sw = 0
Sino
Encolar (C1, Frente1, Final1, N1, X)
Fin si
Fin repetir
Repetir mientras (ColaVacia (Frente) == Falso)
Desencolar (Cola, Frente, Final, X)
Encolar (C1, Frente1, Final1, N1, X)
Fin repetir
Repetir mientras (ColaVacia (Frente1) == Falso)
Desencolar (C1, Frente1, Final1, X)
Encolar (Cola, Frente, Final, N, X)
Fin repetir
Fin
Ejercicio 2. Algoritmo que invierte el contenido de una Cola. (Utilizar sola las operaciones de
cola.)
Procedimiento InvertirCola(?Cola, ?Frente, ?Final, N)
Inicio
CrearPila (PAux, cima, maxPila)
Repetir mientras (ColaVacia (Frente) == Falso)
Desencolar (Cola, Frente, Final, num)
Apilar (PAux, cima, maxPila, num)
Fin repetir
Repetir mientras (PilaVacia (cima) == Falso)
Desapilar (PAux, cima, X)
Encolar (Cola, Frente, Final, N, X)
Fin repetir
Fin
Implementación
Archivo:
- PrincipalEjercicioCola.cpp
- PrincipalEjercicioCola.vb