Sunteți pe pagina 1din 15

3 Arreglos

Concepto
Un arreglo es un conjunto de elementos del mismo tipo agrupados en una sola variable. Cada posicin de almacenamiento en un arreglo es llamada un elemento del arreglo. Para ingresar a un elemento en particular, utilizamos un ndice. Existen arreglos unidimensionales, bidimensionales y tridimensionales. Su uso ms comn es en la implementacin de cadenas de caracteres. Recuerda que en C no existen variables de tipo cadena por lo cual se utiliza un arreglo de caracteres. Fsicamente, un arreglo es un conjunto de localidades de memoria contiguas donde la direccin ms baja corresponde al primer elemento y la direccin ms alta al ltimo. En un arreglo de n elementos, stos ocuparan desde la casilla 0 hasta la n-1. Por si mismo, el nombre del arreglo apunta a la direccin del primer elemento del arreglo. Un arreglo se puede visualizar de la siguiente forma:

En este caso tenemos un arreglo que contiene datos de tipo entero (int), el numero de datos es 4, ntese que tenemos un subndice para acceder a cada posicin del arreglo, adems, un arreglo siempre comienza por el subndice o posicin 0.

Arreglos Unidimensionales
1

Un arreglo de una sola dimensin es un arreglo que tiene solamente un subndice. Un subndice es un nmero encerrado en corchetes a continuacin del nombre del arreglo. Este nmero puede identificar el nmero de elementos individuales en el arreglo. La forma general para definir un arreglo de slo una dimensin es la siguiente: Tipo_de_dato nombre_variable [tamao] tipo_de_dato: se refiere al tipo de dato de cada elemento del arreglo y tamao es la cantidad de elementos agrupados en la misma variable. Ejemplo float x [10]; int y [10];

Inicializacin de un Arreglo
Existen diferentes formas de inicializar un arreglo. Por omisin: Cuando tenemos un arreglo esttico utilizamos este mtodo, la forma de hacerlo es la siguiente: char letras[10]; Sin tamao especfico: Podemos crear un arreglo sin decirle el tamao, siempre y cuando le asignemos a este los elementos que lo conforman, as: char frase[]="arreglo sin longitud explcita"; lo cual nos crea un arreglo del tamao suficiente para guardar la frase. Definicin explcita: En este caso creamos un arreglo de tamao especfico y a la vez le asignamos los elementos que lo conforman: int numeros[3]={100,23,90}; Otro ejemplo es: int dgitos[5]={'0','1','2','3','4','5','6','7','8','9'};

Acceso a los Elementos del Arreglo

Para acceder a un elemento del arreglo utilizamos un subndice, el cual determina la posicin que ocupa dicho elemento dentro del arreglo. La sintaxis es: nombre_arreglo[subndice]; Supongamos que tenemos un arreglo: int numeros[3]={2,800,67}; S queremos acceder al elemento 1 el cual contiene el valor 800 entonces la instruccin es numeros[1]; Tamao (En Bytes) de un Arreglo Para determinar el tamao en bytes de un arreglo utilizamos la funcin sizeof asi: sizeof(nombre_arreglo);

Arreglos Bidimensionales
Un arreglo bidimensional es un arreglo de arreglos unidimensionales. Constituyen la forma ms simple de los arreglos multidimensionales. Un arreglo bidimensional tiene dos subndices.}

Declaracin de un Arreglo Bidimensional


Su forma general de declaracin es: tipo_dato variable[primer ndice][segundo ndice]; El primer ndice corresponde a la filas y el segundo a las columnas.

Arreglos n-dimensionales
Cmo su nombre lo indica son arreglos de varias dimensiones, es decir utilizan varios subndices para acceder a los elementos, se podran ver como una matriz:

Como se puede ver este es una arreglo bidimensional, la declaracin es similar a un arreglo normal, slo que en este caso utilizamos otro par de corchetes, por ser bidimensional. Si tiene de tres pares de corchetes en adelante el arreglo es multidimensional. En el dibujo si queremos acceder al elemento 20 y cambiar su valor por 1000 declaramos: int A[1][2]=1000;

Declaracin de un Arreglo n-dimensional


Su forma general de declaracin es: tipo_dato variable [long ind 1][longindice 2]...[long indice N] donde tipo_dato es el tipo de dato de los elementos del arreglo y long ind 1, long ind 2...long ind N es la longitud de cada dimensin del arreglo. Este tipo de arreglos no se utiliza muy frecuentemente debido al gran espacio en memoria que ocupan. Otra desventaja es que el acceso a un arreglo multidimensional dura ms tiempo que el requerido por uno del tipo unidimensional.

Mtodos de Ordenacin
Su finalidad es organizar ciertos datos (normalmente arrays o ficheros) en un orden creciente o decreciente mediante una regla prefijada (numrica, alfabtica...). Atendiendo al tipo de elemento que se quiera ordenar puede ser: 4

Ordenacin interna: Los datos se encuentran en memoria (ya sean arrays, listas, etc) y son de acceso aleatorio o directo (se puede acceder a un determinado campo sin pasar por los anteriores). Ordenacin externa: Los datos estn en un dispositivo de almacenamiento externo (ficheros) y su ordenacin es ms lenta que la interna.

Ordenacin Interna
Los mtodos de ordenacin interna se aplican principalmente a Arreglos unidimensionales. Los principales algoritmos de ordenacin interna son:

Seleccin
Este mtodo consiste en buscar el elemento ms pequeo del arreglo y ponerlo en primera posicin; luego, entre los restantes, se busca el elemento ms pequeo y se coloca en segundo lugar, y as sucesivamente hasta colocar el ltimo elemento. Por ejemplo, si tenemos el arreglo {40,21,4,9,10,35}, los pasos a seguir son: {4,21,40,9,10,35} <-cambia el 4 por el 40. {4,9,40,21,10,35} <-21. {4,9,10,21,40,35} <-el 40. {4,9,10,21,40,35} <-{4,9,10,21,35,40} <-el 40. Se coloca el 4, el ms pequeo, en primera posicin : se Se coloca el 9, en segunda posicin: se cambia el 9 por el Se coloca el 10, en tercera posicin: se cambia el 10 por Se coloca el 21, en tercera posicin: ya est colocado. Se coloca el 35, en tercera posicin: se cambia el 35 por

Si el arreglo tiene N elementos, el nmero de comprobaciones que hay que hacer es de N*(N-1)/2, luego el tiempo de ejecucin est en O(n2) int array[N]; int i,j,menor,aux; // Dar valores a los elementos del array for(i=0;i<N-1;i++) { for(j=i+1,menor=i;j<N;j++) if(array[j]<array[menor]) // Si el elemento j es menor que el menor: menor=j; // el menor pasa a ser el elemento j. aux=array[i]; // Se intercambian los elementos array[i]=array[menor]; // de las posiciones i y menor array[menor]=aux; // usando una variable auxiliar. } 5

Burbuja
Consiste en comparar pares de elementos adyacentes e intercambiarlos entre s hasta que estn todos ordenados. Con el arreglo anterior, {40,21,4,9,10,35}: Primera pasada: {21,40,4,9,10,35} <-- Se cambia el 21 por el 40. {21,4,40,9,10,35} <-- Se cambia el 40 por el 4. {21,4,9,40,10,35} <-- Se cambia el 9 por el 40. {21,4,9,10,40,35} <-- Se cambia el 40 por el 10. {21,4,9,10,35,40} <-- Se cambia el 35 por el 40. Segunda pasada: {4,21,9,10,35,40} <-- Se cambia el 21 por el 4. {4,9,21,10,35,40} <-- Se cambia el 9 por el 21. {4,9,10,21,35,40} <-- Se cambia el 21 por el 10. Ya estn ordenados, pero para comprobarlo habra que acabar esta segunda comprobacin y hacer una tercera. Si el arreglo tiene N elementos, para estar seguro de que el arreglo est ordenado, hay que hacer N-1 pasadas, por lo que habra que hacer (N-1)*(N-i-1) comparaciones, para cada i desde 1 hasta N-1. El nmero de comparaciones es, por tanto, N(N-1)/2, lo que nos deja un tiempo de ejecucin, al igual que en la seleccin, en O(n2). int array[N]; int i,j,aux; // Dar valores a los elementos del array for(i=0;i<N-1;i++) // Hacer N-1 pasadas. { for(j=0;j<N-i-1;j++) // Mirar los N-i-1 pares. { if(array[j+1]<array[j]) // Si el elemento j+1 es menor que el elemento j: { aux=array[j+1]; // Se intercambian los elementos array[j+1]=array[j]; // de las posiciones j y j+1 array[j]=aux; // usando una variable auxiliar. } } }

Insercin directa
6

En este mtodo lo que se hace es tener una sublista ordenada de elementos del arreglo e ir insertando el resto en el lugar adecuado para que la sublista no pierda el orden. La sublista ordenada se va haciendo cada vez mayor, de modo que al final la lista entera queda ordenada. Para el ejemplo {40,21,4,9,10,35}, se tiene: {40,21,4,9,10,35} <-- La primera sublista ordenada es {40}. Insertamos el 21: {40,40,4,9,10,35} <-- aux=21; {21,40,4,9,10,35} <-- Ahora la sublista ordenada es {21,40}. Insertamos el 4: {21,40,40,9,10,35} <-- aux=4; {21,21,40,9,10,35} <-- aux=4; {4,21,40,9,10,35} <-- Ahora la sublista ordenada es {4,21,40}. Insertamos el 9: {4,21,40,40,10,35} <-- aux=9; {4,21,21,40,10,35} <-- aux=9; {4,9,21,40,10,35} <-- Ahora la sublista ordenada es {4,9,21,40}. Insertamos el 10: {4,9,21,40,40,35} <-- aux=10; {4,9,21,21,40,35} <-- aux=10; {4,9,10,21,40,35} <-- Ahora la sublista ordenada es {4,9,10,21,40}. Y por ltimo insertamos el 35: {4,9,10,21,40,40} <-- aux=35; {4,9,10,21,35,40} <-- El array est ordenado. En el peor de los casos, el nmero de comparaciones que hay que realizar es de N*(N+1)/2-1, lo que nos deja un tiempo de ejecucin en O(n2). En el mejor caso (cuando la lista ya estaba ordenada), el nmero de comparaciones es N-2. Todas ellas son falsas, con lo que no se produce ningn intercambio. El tiempo de ejecucin est en O(n). El caso medio depender de cmo estn inicialmente distribuidos los elementos. Vemos que cuanto ms ordenada est inicialmente ms se acerca a O(n) y cuanto ms desordenada, ms se acerca a O(n2). El peor caso es igual que en los mtodos de burbuja y seleccin, pero el mejor caso es lineal, algo que no ocurra en stos, con lo que para ciertas entradas podemos tener ahorros en tiempo de ejecucin. int array[N]; int i,j,aux;

// Dar valores a los elementos del array for(i=1;i<N;i++) // i contiene el nmero de elementos de la sublista. { // Se intenta aadir el elemento i. aux=array[i]; for(j=i-1;j>=0;j--) // Se recorre la sublista de atrs a adelante para buscar { // la nueva posicin del elemento i. if(aux>array[j]) // Si se encuentra la posicin: { array[j+1]=aux; // Ponerlo break; // y colocar el siguiente nmero. } else // si no, sigue buscndola. array[j+1]=array[j]; } if(j==-1) // si se ha mirado todas las posiciones y no se ha encontrado la correcta array[0]=aux; // es que la posicin es al principio del todo. }

Insercin binaria
Es el mismo mtodo que la insercin directa, excepto que la bsqueda del orden de un elemento en la sublista ordenada se realiza mediante una bsqueda binaria, lo que en principio supone un ahorro de tiempo. No obstante, dado que para la insercin sigue siendo necesario un desplazamiento de los elementos, el ahorro, en la mayora de los casos, no se produce, si bien hay compiladores que realizan optimizaciones que lo hacen ligeramente ms rpido. Shell: Es una mejora del mtodo de insercin directa, utilizado cuando el array tiene un gran nmero de elementos. En este mtodo no se compara a cada elemento con el de su izquierda, como en el de insercin, sino con el que est a un cierto nmero de lugares (llamado salto) a su izquierda. Este salto es constante, y su valor inicial es N/2 (siendo N el nmero de elementos, y siendo divisin entera). Se van dando pasadas hasta que en una pasada no se intercambie ningn elemento de sitio. Entonces el salto se reduce a la mitad, y se vuelven a dar pasadas hasta que no se intercambie ningn elemento, y as sucesivamente hasta que el salto vale 1. Por ejemplo, lo pasos para ordenar el array {40,21,4,9,10,35} mediante el mtodo de Shell seran: Salto=3: Primera pasada:

{9,21,4,40,10,35} <-- se intercambian el 40 y el 9. {9,10,4,40,21,35} <-- se intercambian el 21 y el 10. Salto=1: Primera pasada: {9,4,10,40,21,35} <-- se intercambian el 10 y el 4. {9,4,10,21,40,35} <-- se intercambian el 40 y el 21. {9,4,10,21,35,40} <-- se intercambian el 35 y el 40. Segunda pasada: {4,9,10,21,35,40} <-- se intercambian el 4 y el 9. Con slo 6 intercambios se ha ordenado el array, cuando por insercin se necesitaban muchos ms. int array[N]; int salto,cambios,aux,i; for(salto=N/2;salto!=0;salto/=2) // El salto va desde N/2 hasta 1. { for(cambios=1;cambios!=0; ) // Mientras se intercambie algn elemento: { cambios=0; for(i=salto;i<N;i++) // se da una pasada if(array[i-salto]>array[i]) // y si estn desordenados { aux=array[i]; // se reordenan array[i]=array[i-salto]; array[i-salto]=aux; cambios++; // y se cuenta como cambio. } } }

Ordenacin rpida (quicksort): Este mtodo se basa en la tctica "divide y vencers", que consiste en ir subdividiendo el array en arrays ms pequeos, y ordenar stos. Para hacer esta divisin, se toma un valor del array como pivote, y se mueven todos los elementos menores que este pivote a su izquierda, y los mayores a su derecha. A continuacin se aplica el mismo mtodo a cada una de las dos partes en las que queda dividido el array. Normalmente se toma como pivote el primer elemento de array, y se realizan dos bsquedas: una de izquierda a derecha, buscando un elemento mayor que el pivote, y otra de derecha a izquierda, buscando un elemento menor que el pivote. Cuando se han encontrado los dos, se intercambian, y se sigue realizando la bsqueda hasta que las dos bsquedas se encuentran. Por ejemplo, para dividir el array {21,40,4,9,10,35}, los pasos seran: 9

{21,40,4,9,10,35} <-- se toma como pivote el 21. La bsqueda de izquierda a derecha encuentra el valor 40, mayor que pivote, y la bsqueda de derecha a izquierda encuentra el valor 10, menor que el pivote. Se intercambian: {21,10,4,9,40,35} <-- Si seguimos la bsqueda, la primera encuentra el valor 40, y la segunda el valor 9, pero ya se han cruzado, as que paramos. Para terminar la divisin, se coloca el pivote en su lugar (en el nmero encontrado por la segunda bsqueda, el 9, quedando: {9,10,4,21,40,35} <-- Ahora tenemos dividido el array en dos arrays ms pequeos: el {9,10,4} y el {40,35}, y se repetira el mismo proceso. La implementacin es claramente recursiva y suponiendo el pivote el primer elemento del arreglo, el programa sera: #include <stdio.h> void ordenar(int *,int,int); void main() { // Dar valores al array ordenar(array,0,N-1); // Para llamar a la funcin } void ordenar(int *array,int desde,int hasta) { int i,d,aux; // i realiza la bsqueda de izquierda a derecha // y j realiza la bsqueda de derecha a izquierda. if(desde>=hasta) return; for(i=desde+1,d=hasta; ; ) // Valores iniciales de la bsqueda. { for( ;i<=hasta && array[i]<=array[desde];i++); // Primera bsqueda for( ;d>=0 && array[d]>=array[desde];d--); // segunda bsqueda if(i<d) // si no se han cruzado, intercambiar { aux=array[i]; array[i]=array[d]; array[d]=aux; } else // si se han cruzado, salir del bucle break; } if(d==desde-1) // Si la segunda bsqueda se sale del array es que el d=desde; // pivote es el elemento ms pequeo: se cambia con l mismo aux=array[d]; // Colocar el pivote en su posicin array[d]=array[desde]; 10

array[desde]=aux; ordenar(array,desde,d-1); // Ordenar el primer subarray. ordenar(array,d+1,hasta); // Ordenar el segundo subarray. } En C hay una funcin que realiza esta ordenacin sin tener que implementarla, llamada qsort (incluida en stdlib.h): qsort(nombre_array,nmero,tamao,funcin); donde nombre_array es el nombre del array a ordenar, nmero es el nmero de elementos del array, tamao indica el tamao en bytes de cada elemento y funcin es un puntero a una funcin que hay que implementar, que recibe dos elementos y devuelve 0 si son iguales, algo menor que 0 si el primero es menor que el segundo, y algo mayor que 0 si el segundo es menor que el primero. Por ejemplo, el programa de antes sera: #include <stdio.h> #include <stdlib.h> int funcion(const void *,const void *); void main() { // Dar valores al array qsort(array,N,sizeof(array[0]),funcion); } int funcion(const void *a,const void *b) { if(*(int *)a<*(int *)b) return(-1); else if(*(int *)a>*(int *)b) return(1); else return(0); } Claramente, es mucho ms cmodo usar qsort que implementar toda la funcin, pero hay que tener mucho cuidado con el manejo de los punteros en la funcin, sobre todo si se est trabajando con estructuras. Intercalacin: no es propiamente un mtodo de ordenacin, consiste en la unin de dos arreglos ordenados de modo que la unin est tambin ordenada. Para ello, basta con recorrer los arreglos de izquierda a derecha e ir cogiendo el menor de los dos elementos, de forma que slo aumenta el contador del arreglo del que sale el elemento

11

siguiente para el array-suma. Si quisiramos sumar los arreglos {1,2,4} y {3,5,6}, los pasos seran: Inicialmente: i1=0, i2=0, is=0. Primer elemento: mnimo entre 1 y 3 = 1. Suma={1}. i1=1, i2=0, is=1. Segundo elemento: mnimo entre 2 y 3 = 2. Suma={1,2}. i1=2, i2=0, is=2. Tercer elemento: mnimo entre 4 y 3 = 3. Suma={1,2,3}. i1=2, i2=1, is=3. Cuarto elemento: mnimo entre 4 y 5 = 4. Suma={1,2,3,4}. i1=3, i2=1, is=4. Como no quedan elementos del primer array, basta con poner los elementos que quedan del segundo array en la suma: Suma={1,2,3,4}+{5,6}={1,2,3,4,5,6} int i1,i2,is; int array1[N1],array2[N2],suma[N1+N2]; for(i1=i2=is=0;i1<N1 && i2<N2;is++) /* Mientras no se me acabe ni array1 ni array2:*/ { if(array1[i1]<array2[i2]) // Si el elemento de array1 es menor: { suma[is]=array1[i1]; // se utiliza el de array1. i1++; } else // Pero si el elemento de array2 es menor: { suma[is]=array2[i2]; // se utiliza el de array2. i2++; } } for( ;i1<N1;i1++,is++) // Aadir los elementos de array1 (si quedan). suma[is]=array1[i1]; for( ;i2<N2;i2++,is++) // Aadir los elementos de array2 (si quedan). suma[is]=array2[i2];

Ejercicios Propuestos

12

1. Escribir un programa en Lenguaje C que rellene un arreglo con los nmeros enteros comprendidos entre 4 y 14. 2. Escribir un programa en Lenguaje C que rellene un arreglo con los nmeros pares comprendidos entre 1 y 10. 3. Escribir un programa en Lenguaje C que rellene un arreglo con los nmeros comprendidos entre 25 y 35 divididos por 3. 4. Escribir un programa en Lenguaje C que rellene un arreglo con cinco nmeros enteros consecutivos y haga una copia de ese arreglo en otro. 5. Escribir un programa en Lenguaje C que rellene un arreglo de 10 elementos con los nmeros comprendidos entre 23 y 32 y copie en otro arreglo esos nmeros multiplicados por 0.35. 6. Escribir un programa en Lenguaje C que rellene un arreglo con los veinte primeros nmeros pares y calcule su suma. 7. Escribir un programa en Lenguaje C que solicite cinco nmeros, los almacene en un arreglo y luego calcule la media aritmtica de esos nmeros. 8. Escribir un programa en Lenguaje C que tras asignar los nmeros, 23, 45, 68, 99, 10, 15 y 4 a un arreglo, determine la posicin del arreglo en la que se encuentra el mximo valor. 9. Escribir un programa en Lenguaje C que tras asignar los nmeros, -2, 5, 8, -9, 10, 15 y -4 a un arreglo calcule, independientemente, la suma de los elementos positivos y negativos. 10. Escribir un programa Lenguaje C que tras asignar los nmeros, 23, 45, 68, 99, 10, 15 y 4 a un arreglo, determine las posiciones del arreglo en las que se encuentran el mximo y el mnimo valor. 11. Escribir un programa en Lenguaje C que determine la posicin de la siguiente matriz en la que se encuentra el valor mximo. 23 45 68 34 99 12 25 78 89 12. Escribir un programa en Lenguaje C que sume, independientemente, los elementos positivos y negativos de la siguiente matriz: -12 23 32 45 -56 -10 25 78 89 13. Escribir un programa en Lenguaje C que multiplique por dos los elementos de la siguiente matriz: 4 7 8 6 9 1 5 0 3 14. Escribir un programa en Lenguaje C que almacene en la segunda fila de la siguiente matriz los cuadrados de los datos de la primera fila: 3 6 7 8 9 0 0 0 0 0 15. Escribir un programa en Lenguaje C que sume los datos de cada una de las filas de la siguiente matriz; el resultado se almacenar en la ltima posicin de cada fila: 3 6 7 8 9 0 13

16. Escribir un programa en lenguaje C que sume los datos de cada una de las columnas de la siguiente matriz; el resultado se almacenar en la ltima posicin de cada columna: 3 2 4 6 8 9 0 0 17. Escribir un programa en Lenguaje C que sume los elementos de cada una de las filas y de las columnas de la siguiente matriz; el resultado de cada suma se almacenar en la ltima posicin de la fila o columna correspondiente. Adems la suma total de todos los elementos de la matriz se almacenar en el elemento de la esquina inferior derecha de la matriz: 1 7 0 5 6 0 6 4 0 7 3 0 0 0 0 18. Escribir un programa en Lenguaje C que divida todos los elementos de una matriz M (3,4) por el elemento situado en la posicin 2,2. 19. Escribir un programa en Pascal que almacene en un arreglo los nmeros primos comprendidos entre 1 y 100. 20. Escribir un programa en Lenguaje C que genera la matriz transpuesta de una matriz de 3 filas y 4 columnas. La matriz transpuesta de una matriz M(m,n) se obtiene intercambiando filas por columnas y viceversa; el resultado se tiene que almacenar en una nueva matriz M_TRANS(n,m). 21. Escribir un programa en Lenguaje C que sume dos matrices bidimensionales. Las matrices para que puedan sumarse deben tener las mismas dimensiones. 22. Escribir un programa en Pascal que sume los datos de cada una de las columnas de la siguiente matriz; el resultado se almacenar en la ltima posicin de cada columna: 3 2 4 6 9 5 23. Escribir un programa en Pascal que sume los elementos de cada una de las filas y de las columnas de la siguiente matriz; el resultado de cada suma se almacenar en la ltima posicin de la fila o columna correspondiente. Adems la suma total de todos los elementos de la matriz se almacenar en el elemento de la esquina inferior derecha de la matriz: 1 7 0 5 6 0 6 4 0 7 3 0 0 0 0 14

24. Escribir un programa en Pascal que divida todos los elementos de una matriz M (3,4) por el elemento situado en la posicin 2,2. 25. Escribir un programa en Pascal que almacene en un arreglo los nmeros primos comprendidos entre 1 y 100. 26. Escribir un programa en Pascal que genera la matriz transpuesta de una matriz de 3 filas y 4 columnas. La matriz transpuesta de una matriz M(m,n) se obtiene intercambiando filas por columnas y viceversa; el resultado se tiene que almacenar en una nueva matriz M_TRANS(n,m). 27. Escribir un programa en Pascal que genera la inversa de una cadena de caracteres. La cadena original y la invertida deben almacenarse en arreglos independientes. 28. Escribir un programa en Pascal que sume dos matrices bidimensionales. Las matrices para que puedan sumarse deben tener las mismas dimensiones. 29. Escribir un programa en Pascal que elimine los blancos de una cadena de caracteres. La cadena original y la transformada deben almacenarse en arreglos independientes.

15

S-ar putea să vă placă și