Estructura de Datos ARREGLOS
ESTRUCTURAS DE INFORMACIÓN Una estructura de datos o de información es una colección de datos que pueden ser caracterizados por su organización y las operaciones que se definen sobre ellos. Las estructuras de datos se utilizan generalmente para procesar una colección de valores que están relacionados entre sí por algún método. Las estructuras de datos básicas que soportan la mayoría de los lenguajes de programación son las estructuras estáticas. 2
ESTRUCTURAS ESTÁTICAS Una estructura de datos estática es aquella en la que el tamaño ocupado en memoria se define antes de que el programa se ejecute y no puede modificarse dicho tamaño durante la ejecución del programa. Entre las estructuras de datos estáticas se encuentran los arreglos (vectores y matrices), registros, archivos y cadenas de caracteres. 3
ARREGLOS Un arreglo es un conjunto finito y ordenado de elementos homogéneos. Ordenado: cada elemento puede ser identificado de manera individual. Homogéneo: todos los elementos son del mismo tipo de dato. 4
ARREGLOS De esta manera se puede decir que un arreglo es un conjunto de elementos del mismo tipo agrupados en una sola variable, donde: Se usa un índice para ingresar a cada elemento en particular. Los elementos del arreglo se almacenan en espacios consecutivos en memoria. 5
ARREGLOS Particularidades y consideraciones: Los arreglos ó conjuntos de datos ordenados (arrays) recolectan variables del mismo tipo, guardándolas en forma secuencial en la memoria. La cantidad máxima de variables que pueden albergar está sólo limitada por la cantidad de memoria disponible. El tipo de las variables involucradas puede ser cualquiera de los ya vistos, con la única restricción de que todos los componentes de un arreglo deben ser del mismo tipo. 6
ARREGLOS Por sí mismo, el nombre del arreglo apunta a la dirección del primer elemento del arreglo. Se puede referenciar a cada elemento, en forma individual, tal como se ha hecho con las variables anteriormente. El subíndice designa la posición del elemento en el vector. 7
ARREGLOS El tamaño o cantidad de elementos en un arreglo siempre debe ser constante. No se pueden utilizar variables para especificar el tamaño. 8
ARREGLOS UNIDIMENSIONALES El arreglo unidimensional o vector es el tipo de arreglo más simple. Sintaxis: tipo_dato identificador[tamaño]; o bien: tipo_dato nombre_variable[cantidad de elementos]; 9
Ejemplos: ARREGLOS UNIDIMENSIONALES int variable1[8]; char nombre_completo[50]; float calificaciones[10]; double cantidades[30]; 10
ARREGLOS UNIDIMENSIONALES int cantidad = 1000; int numeros[cantidad]; /* ERROR */ #define CANTIDAD 1000 int numeros[cantidad]; /* CORRECTO */ 11
ARREGLOS UNIDIMENSIONALES Operaciones: las operaciones que se pueden realizar con los vectores son: inicialización, asignación, lectura, escritura, recorrido, actualización (insertar, borrar, modificar), ordenación, búsqueda, etc. 12
ARREGLOS UNIDIMENSIONALES La inicialización de un arreglo local, puede realizarse en su declaración, dando una lista de valores iniciales: int numeros[8] = {2, 6, 5, -2, 3, 6, 8, 9}; Obsérvese que la lista está delimitada por llaves. Otra posibilidad, sólo válida cuando se inicializan todos los elementos del arreglo, es escribir: int numeros[] = {-3, -2, -1, 0, 1, 2, 3, 4, 5, 6}; donde, se obvia la declaración de la cantidad de elementos, ya que está implícita en la lista de valores constantes. 13
ARREGLOS UNIDIMENSIONALES También se puede inicializar parcialmente un arreglo, por ejemplo: int numeros[10] = {1, 1, 1}; en éste caso los tres primeros elementos del mismo valdrán 1, y los restantes 0. Se puede usar también un ciclo para inicializar todos los elementos de un arreglo a un valor determinado. int arreglo[10]; for (i = 0; i < 10; i++) arreglo[i] = -1; 14
ARREGLOS UNIDIMENSIONALES Asignación identificador[posición] = valor; arreglo[3] = 8; Lectura scanf( %d,&arreglo[6]); Escritura printf( El valor en la posición 6 es: %d,arreglo[6]); 15
Inserción: ARREGLOS UNIDIMENSIONALES /*Insertar un nuevo elemento k en la posición p, i corresponde al índice del último elemento*/ while (i >= p) { arreglo[i + 1] = arreglo[i]; i--; } arreglo[p] = k; 16
Eliminación: ARREGLOS UNIDIMENSIONALES /*Eliminar el elemento en la posición j, n corresponde al índice del último elemento*/ for (i = j; i < n; i++) arreglo[i] = arreglo[i + 1]; 17
#include <stdio.h> #include <conio.h> ARREGLOS UNIDIMENSIONALES int main(void) { int numeros[10]; for(int i = 0; i < 10; i++) { numeros[i] = i; printf("%d\n",numeros[i]); } getch(); return 0; } 18
ARREGLOS UNIDIMENSIONALES #include <stdio.h> #include <conio.h> #define N 10 int main(void) { int numeros[n]; int i = -1; double sum = 0.0; for(i = 0; i < N; i++) { printf( Elemento %d,i); scanf("%d",&numeros[i]); sum+=numeros[i]; } printf( La suma de los elementos es: %lf,sum); getch(); return 0; } 19
ARREGLOS BIDIMENSIONALES Un arreglo bidimensional o matriz se puede considerar como un vector de vectores. Es decir, un conjunto de elementos homogéneos y ordenados en el que se necesita especificar dos subíndices para poder identificar cada elemento del arreglo. 20
Sintaxis: ARREGLOS BIDIMENSIONALES tipo_dato identificador[filas][columnas]; o bien: tipo_dato nombre_variable[filas][columnas]; 21
ARREGLOS BIDIMENSIONALES Por ejemplo, si se declara: int matriz[3][4]; esquemáticamente la disposición espacial de los elementos sería: columnas: 0 1 2 3 filas: 0 [0][0] [0][1] [0][2] [0][3] matriz[0] 1 [1][0] [1][1] [1][2] [1] [3] matriz [1] 2 [2][0] [2][1] [2][2] [2] [3] matriz [2] 22
ARREGLOS BIDIMENSIONALES Operaciones: Las operaciones que se pueden realizar con matrices son: Inicialización, asignación, lectura, escritura, recorrido, actualización (insertar, borrar, modificar), ordenación, búsqueda, etc. 23
ARREGLOS BIDIMENSIONALES Inicialización: la inicialización de los arreglos bidimensionales o matrices sigue las mismas reglas ya vistas para los otros tipos de variables, es decir: Si se declaran como globales (afuera del cuerpo de las funciones y procedimientos) cada uno de sus elementos será automáticamente inicializado a cero. Si su declaración es local (dentro de una función o procedimiento), no se realiza ninguna inicialización, quedando a cargo del programa cargar los valores de inicio o bien a manos de programador dar los valores iniciales. 24
ARREGLOS BIDIMENSIONALES La inicialización de una matriz local, puede realizarse en su declaración, dando una lista de valores iniciales: int matriz[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; Obsérvese que la lista está delimitada por llaves. Otra posibilidad, sólo válida cuando se inicializan todos los elementos del arreglo, es escribir: int matriz[][3] = {{-3, -2, -1}, {0, 1, 2}, {3, 4, 5}}; donde, se obvia la declaración de la cantidad de filas, ya que está implícita en la lista de valores constantes, pero no así la de las columnas. 25
ARREGLOS BIDIMENSIONALES También se puede inicializar parcialmente una matriz, por ejemplo: int matriz[3][10] = {{1, 1, 1}, {2, 2, 2}, {3, 3, 3}}; en éste caso los tres primeros elementos de cada fila son inicializados y los restantes valdrán 0. Se pueden usar también los ciclos para inicializar todos los elementos de una matriz a un valor determinado. int matriz[2][2]; for (i = 0; i < 2; i++) for (j = 0; j < 2; j++) matriz[i][j] = -1; 26
ARREGLOS BIDIMENSIONALES Asignación identificador[fila][columna] = valor; arreglo[1][3] = 8; Lectura scanf( %d,&arreglo[3][2]); Escritura printf( El valor en la posición 2,3 es: %d,arreglo[2][3]); 27
#include <stdio.h> #include <conio.h> ARREGLOS BIDIMENSIONALES int main(void) { int matriz[3][4]; int cantidad = 1; for(int i = 0; i < 3; i++) for(int j = 0; j < 4; j++) { matriz[i][j] = cantidad; printf( %d,matriz[i][j]); cantidad*=2; } getch(); return 0; } 28
CADENAS DE CARACTERES Los conjuntos ordenados de caracteres o cadenas de caracteres (strings) son simplemente arreglos de caracteres, tal como se han visto hasta ahora, con el agregado de un último elemento constante: el carácter NULL (ASCII == 0, simbolizado por la secuencia de escape \0 o \x0). Éste agregado permite a las funciones que procesan a los mismos, determinar fácilmente la finalización de los datos. 29
CADENAS DE CARACTERES Se puede declarar una cadena de caracteres como: char cadena1[5] = {'A', 'B', 'C', 'D', 0}; char cadena2[] = { a', b', c', d', '\0'}; char cadena3[3 + 1] = { 1', 2', 3', '\0'}; Ambas maneras son equivalentes. Sin embargo hay, en el lenguaje C, una forma más compacta de declararlas: char cadena1[5] = "ABCD"; char cadena2[] = abcd"; char cadena3[3 + 1] = 123"; 30
CADENAS DE CARACTERES int texto[] = "renglón 1 \n renglón 2 \n "; /* ERROR */ Un caso interesante es el de la línea anterior (comentada como ERROR), con el fin de poder almacenar al carácter "\n" (ASCII 179) se intentó asignar a un arreglo de enteros una cadena constante de caracteres. Esto no es permitido por el compilador, que lo rechaza como una asignación inválida, ya que la cadena constante usada como valor derecho en la asignación es un apuntador a char y no a int. 31
CADENAS DE CARACTERES La solución más común para este caso es, declarar el arreglo como unsigned char, con lo cual se lleva el alcance de sus elementos a 255. unsigned char texto[] = "renglón 1 \n renglón 2 \n "; /* CORRECTO */ Si se tuviera el caso de tener que almacenar en la cadena el carácter EOF (-1) y al mismo tiempo con caracteres ASCII mayores que 127, se podría definir el arreglo como int, pero su inicialización se tendrá que hacer obligatoriamente usando llaves, como se vio anteriormente. Se deduce entonces, que una cadena de caracteres sigue siendo un arreglo de caracteres, con la salvedad del agregado de un terminador de cadena (carácter nulo). 32
#include <stdio.h> #include <conio.h> int main(void) { char palabra[5] = Hola ; for(int i = 0; i < 5, i++) printf("%c",palabra[i]); printf("\n"); printf("%s\n",palabra); getch(); return 0; } CADENAS DE CARACTERES 33
#include <stdio.h> #include <conio.h> CADENAS DE CARACTERES int main(void) { int i; char palabra[11]; for(int i = 0; i < 10; i++) palabra[i] = 65 + i; printf("%s\n",palabra); palabra[4]=0; printf("%s\n",palabra); getch(); return 0; } 34
CADENAS DE CARACTERES #include <stdio.h> #include <conio.h> #include <string.h> int main(void) { int i; char palabra1[25], palabra2[25]; printf( Dame la primer palabra: ); scanf("%s",palabra1); printf( Dame la segunda palabra: ); scanf("%s",palabra2); printf("%s vs %s\n",palabra1,palabra2); printf( Iguales? %s\n", (strcmp(palabra1,palabra2) == 0?"si":"no")); printf( Longitudes: %d y %d\n", strlen(palabra1), strlen(palabra2)); printf("concatenadas: %s\n", strcat(palabra1, palabra2)); getch(); return 0; } 35
ARREGLOS MULTIDIMENSIONALES Un arreglo puede ser definido de tres dimensiones, cuatro dimensiones, hasta de n- dimensiones. En general, un arreglo de n- dimensiones requiere que los valores de los n- subíndices puedan ser especificados a fin de identificar un elemento individual del arreglo. 36
Sintaxis: ARREGLOS MULTIDIMENSIONALES tipo_dato n]; identificador[dimensión 1][dimensión 2]...[dimensión o bien: tipo_dato nombre_variable[dimensión 1][dimensión 2]...[dimensión n]; int matriz[2][3][4][5]; 37
ARREGLOS MULTIDIMENSIONALES Se pueden realizar las mismas operaciones ya vistas en las variantes anteriores de los arreglos. 38