35
Arrays. Supongamos que queremos gestionar las notas de una clase de 10 alumnos, tal y como hicimos en el programa de ejemplo del bucle for. En este caso no obstante, queremos tener disponibles, en cualquier momento, las notas de cada alumno individualmente. Para guardar las notas individualmente, no nos sirve una estructura como la siguiente: . . for (i=1 ; i <= 10 ; i++) { printf(“Entrar la nota : %d “,y) ; scanf(“%d”,&nota) ; } Observe como todos los valores que se entran van a la misma variable nota , es decir, cuando se entra el valor de la segunda nota se pierde el valor entrado para la primera; cuando se entra el valor de la tercera se pierde el valor de la segunda, y así sucesivamente. Con los datos vistos hasta el momento, la única solución que se puede aplicar es la siguiente: . . int nota1, nota2, nota3, nota4, nota5, nota6, nota7, nota8, nota9, nota10 ; . printf(“Entrar la primera nota : “) ; scanf(“%d”, &nota1) ; printf(“Entrar la segunda nota : “) ; scanf(“%d”, &nota2) ; . . . printf(“Entrar la décima nota : “) ; scanf(“%d”, &nota10) ; . . La idea no es demasiado agradable, y aún menos si el programa se tuviera que hacer, por ejemplo, para gestionar una clase de 200 alumnos La mayoría de lenguajes de programación permiten definir estructuras de datos del mismo tipo, con un único nombre ( igual que cualquier variable ), pero que pueden guardar un conjunto de valores (recordar que deben ser variables del mismo tipo ).

Manejo de Arrays

Embed Size (px)

DESCRIPTION

Manejo de Arrays de datos en C

Citation preview

Page 1: Manejo de Arrays

Arrays.

Supongamos que queremos gestionar las notas de una clase de 10 alumnos, tal y como hicimos en el programa de ejemplo del bucle for. En este caso no obstante, queremos tener disponibles, en cualquier momento, las notas de cada alumno individualmente. Para guardar las notas individualmente, no nos sirve una estructura como la siguiente:.

.for (i=1 ; i <= 10 ; i++)

{printf(“Entrar la nota : %d “,y) ;scanf(“%d”,&nota) ;

}

Observe como todos los valores que se entran van a la misma variable nota, es decir, cuando se entra el valor de la segunda nota se pierde el valor entrado para la primera; cuando se entra el valor de la tercera se pierde el valor de la segunda, y así sucesivamente.

Con los datos vistos hasta el momento, la única solución que se puede aplicar es la siguiente:

.

.int nota1, nota2, nota3, nota4, nota5, nota6, nota7, nota8, nota9, nota10 ;

.printf(“Entrar la primera nota : “) ;scanf(“%d”, &nota1) ;printf(“Entrar la segunda nota : “) ;scanf(“%d”, &nota2) ;

.

.

.printf(“Entrar la décima nota : “) ;scanf(“%d”, &nota10) ;

.

.

La idea no es demasiado agradable, y aún menos si el programa se tuviera que hacer, por ejemplo, para gestionar una clase de 200 alumnos

La mayoría de lenguajes de programación permiten definir estructuras de datos del mismo tipo, con un único nombre ( igual que cualquier variable ), pero que pueden guardar un conjunto de valores (recordar que deben ser variables del mismo tipo ).Estas estructuras de datos reciben el nombre de Arrays. Algunos autores llaman dimensionar una variable, al proceso de declarar un array.

Declaración de arrays en lenguaje C.

En lenguaje C, un array se declara de la siguiente manera:

tipo Nombre_de_variable[número de elementos] ;

Por ejemplo, en el programa anterior declararíamos notas de la siguiente manera:

int Notas[10] ;

Page 2: Manejo de Arrays

Notas es un espacio de memoria suficientemente grande como para guardar 10 datos del tipo int. Esta definición, al igual que otras que veréis más adelante, servirán para ver los casos en los que puede ser útil la utilización de un array. La definición real de un array, qué es en realidad y cómo se guarda en la memoria, se verá en el tema de punteros.

En notación algorítmica se declararán los arrays tal y como lo hace Pascal.

Nombre_de_Variable : Array[1..Número Elementos] del Tipo ;

En el algoritmo del programa de las notas:

Notas : Array[1..10] de enteros ;

Referenciar los elementos de un array.

Una vez visto como se declaran y que son los arrays, se verá cómo se asignan valores a los diferentes elementos del array. Para asignar un valor a un elemento de un array, se deben utilizar índices. Los índices sirven para referenciar sobre cual de los elementos se quiere trabajar. Así por ejemplo, para asignar el valor 7 al tercer elemento del array notas se escribirá ( en lenguaje C ):

Notas[2] = 7 ;

Para assignar el valor 8 al quinto elemento del array Notas, se escribirá:

Notas[4] = 8 ;

Alerta, hemos dicho tercer elemento y hemos puesto Notas[2], y hemos dicho quinto elemento y hemos puesto Notas[4]. Esto se debe a que al primer elemento de un array en C le corresponde el índice 0. Ver el siguiente esquema:

Memoria.Notas[0]Notas[1]Notas[2]Notas[3]Notas[4]Notas[5]Notas[6]Notas[7]Notas[8]Notas[9]

Hábilmente pues, para hacer el programa para entrar 10 notas y guardarlas,

.

.for(i=0 ; i < 10 ; i++)

{printf(“Entreu la nota : “, i+1) ;scanf(“%d”, &nota[i]) ;

}..

Page 3: Manejo de Arrays

Alerta con lo que sigue,

for (i=1 ; i<= 10 ; i++){

printf(“Entrar la nota : “, i) ;scanf(“%d”, &nota[i]) ;

}

Este bucle se salta el primer elemento ( índice 0, empieza teniendo valor 1), pero lo más grave es que introduce un elemento en Notas[10],y ésta no forma parte del array. C no dará error al compilar el programa, pero cuando éste se ejecute entrará un elemento en una posición de memoria no reservada por el array. Para que quede claro que puede pasar, copie y ejecute el siguiente programa:

#include <stdio.h>#include <conio.h>

main(){

int variable1 ;int Notas[10] ;int variable2;

clrscr() ;variable2 = 5 ;Notas[10] = 7 ;printf(“%d”, variable2) ;

}

La sentencia printf es imprime el valor asignado a Notas[10],no el valor asignado a variable2. Vea el esquema siguiente para comprender que ha pasado:

Memoria.Notas[0]Notas[1]Notas[2]Notas[3]Notas[4]Notas[5]Notas[6]Notas[7]Notas[8]Notas[9]Variable2

Notas[10] coincide con la posición que ocupa Variable2. En C una vez definido un array, se puede utilizar cualquier índice (10, 100 o 3000); el compilador no marca error, el programa ejecuta la sentencia y los resultados pueden ser inesperados ( a veces desesperantes). El control de los elementos del array corre siempre a cargo del programador; alerta pues con los índices de los arrays. Si se declara un array de 1000 elementos, en el programa ejecutable se deberá reservar suficiente memoria para que los gestione, y no habrá ningún problema, siempre y cuando no se utilicen índices superiores a 999. Repetimos, el compilador no dirá

Page 4: Manejo de Arrays

nada, pero se estarán cambiando valores en posiciones de memoria no previstas por el programa (ni por el sistema), y entonces a saber cómo terminrá el programa.

Paso de arrays entre funciones.

Como es sabido mediante parámetros se pueden pasar valores de distintas variables a funciones. se puede utilizar un array como parámetro de una función, pero... copie el programa siguiente, ejecúteo y vea los resultados:

#include <stdio.h>#include <conio.h>

void sumardos(int tabla[],int Var) ;

main(){

int tabla[10] ;int Var;int i ;

clrscr() ;for (i=0 ; i < 10 ; i++)

tabla[i] = i+1 ;

Var=10;sumardos(tabla,Var) ;

printf(“\n\n %d”,a);

for (i=0 ; i <= 10 ; i++)printf(“Elemento %d és %d “, i, tabla[i]) ;

}

void sumardos(int tabla[],int Var){

int i ;

for (i=0 ; i < 10 ; i++)tabla[i] = tabla[i] + 2 ;

Var=Var+2;}

El programa entra los valores del 1 al 10 en array tabla en el primer bucle for.

El programa asigna el valor 10 a la variable Var.

Se pasa array tabla y variable Var a función sumados. En esta función se suma 2 a cada elemento del array y a la variable Var.

Page 5: Manejo de Arrays

Una vez que el programa ha vuelto a la función main, imprime el valor 10 de la variable, la cual cosa no es sorprendente puesto que, tal y como recordamos, la variable Var de función main, pasa el valor a la variable Var de función sumardos(). Lo que si ha cambiado son los valores del array; cada elemento vale dos unidades más que el valor establecido antes de llamar a la función suma.

Al pasar un array a función, no se crea otro array en memoria , tal y como pasaba con las variables, sino que se trabaja con el mismo array. Para comprender qué pasa en realidad, primero se deben conocer mejor los punteros. Por el momento basta con tener en cuenta que siempre que se pasa un array a función, se trabaja sobre el array pasado.

Tanto en la declaración de la función, como en su prototipo, el argumento array se identifica con [], sin ningún valor dentro.

Inicialización de arrays.

Del mismo modo que se pueden asignar valores a una variable al declararla, se pueden asignar valores a los diferentes elementos de un array en la declaración.

int tabla[5] = {1, 2, 3, 4, 5} ;

o también:

int tabla[]= {1, 2, 3, 4, 5} ;

En el segundo caso la capacidad del array es asignada automáticamente por el compilador cuando éste cuenta el número de elementos de la inicialización.

La directiva #define

Observando los programas vistos hasta ahora, podrá comprobar el hecho de que declarar un array de N elementos conlleva que en todas las estructuras repetitivas que gestionen dicho array, la variable de control tome valores que vayan de 0 hasta N elementos; por ejemplo, el programa de las notas.

int Notas[10];..for (i=0; i < 10; i++)

.

.

Si ahora en vez de tener 10 notas tuviésemos 15, ó 5, ó 7, ó... se debería redefinir el array con el número de elementos y, cambiar todos los bucles que gestionanen el array. En este programa el problema se soluciona rápidamente cambiando el valor de la declaración del array, y después el del bucle. Si se tratará de un programa mucho más largo, con muchas estructuras repetitivas, a la hora de gestionar el array no sería tan fácil modificarlo ( por ejemplo, un programa con centenares de líneas en el cual se tuvieran que buscar las estructuras que gestionan el array ). Para solucionar este tipo de eventualidades se puede utilizar la directiva #define; ésta sirve para declarar un valor constante para todo el programa. Así pues, si se decide modificar la capacidad del array, lo único que hay que hacer es cambiar el valor de este identificador. El programa de Notas quedaría así:

Page 6: Manejo de Arrays

#include <stdio.h>#include <conio.h>

#define TAMANYO 10

main(){

int NotAes[TAMANYO];int i;

for (i=0 ; i < TAMANYO; i++){

printf(“EntrAs la Nota : %d“, i+1);scanf(“%d”, &nota[i]);

}}

Si ahora queremos gestionar una clase de 200 alumno, únicamente deberemos modificar la línea #define TAMANYO 10, por #define TAMANYO 200.

Las constantes #define se suelen a escribir en mayúscula, para diferenciar-las de las variables.

Una constante no ocupa memoria como una variable, lo único que hace el compilador es sustituir la constante por el valor que ésta representa.

No se puede cambiar el valor de una constante; por ejemplo, no se puede hacer la siguiente asignación:

TAMANYO = 15;

Page 7: Manejo de Arrays

Arrays bidimensionales.

Un array puede tener más de una dimensión. Pongamos por caso, que en el programa de la clase de alumnos, a parte de guardar la nota, se quisiera guardar la edat y el número de trabajos hechos en clase. Se podrían declarar tres tablas: una para Notas, otra para Edades y otra para Número de Trabajos, pero también sería posible declarar una tabla bidimensional de 3 columnas y 10 filas.

En lenguaje C una tabla bidimensional se declara de la siguiente manera:

Tipo identificador[Num Filas][Num Columnas] ;

En notación algorítmica se utilizará:

Variable : Array de [1..Num Filas][1..Num Columnas] de Tipo ;

Así, al declarar el array en C (se le cambia el nombre, en lugar de notas, alumnos):

int Alumnos[10][3] ; // 10 alumnos y tres datos por alumno.

Notas Edades Núm. de Trabajos.[0][0] [0][1] [0][2][1][0] [1][1] [1][2][2][0] [2][1] [2][2][3][0] [3][1] [3][2][4][0] [4][1] [4][2][5][0] [5][1] [5][2][6][0] [6][1] [6][2][7][0] [7][1] [7][2][8][0] [8][1] [8][2][9][0] [9][1] [9][2]

La estructura para entrar valores en array podría ser:..for (i=0 ; i < 10 ; i++)

{printf(“Entrar la nota : “,i+1) ;scanf(“%d”, &Alumnos[0][i]) ;printf(“Entrar la Edad : “,i+1) ;scanf(“%d”, &Alumnos[1][i]) ;printf(“Entrar el Número de trabajos : “,i+1) ;scanf(“%d”, &Alumnos[2][i]) ;

}

En algunas ocasiones será mucho más conveniente y práctico, utilizar una estructura for anidada. Por ejemplo, suponiendo que se quiere guardar las temperaturas de los últimos 40 días, y que después se quiere obtener la media de cada cinco días; se podría declarar una estructura de array bidimensional para agrupar los 40 elementos de 5 en 5, así:

Page 8: Manejo de Arrays

int Temperatura[8][5];

El programa podría ser el siguiente:

#include <stdio.h>#include <conio.h>

#define FILAS = 8;#define COLUMNAS = 5;

main(){

int Temperaturas[FILAS][COLUMNAS];int i, j, Mediana;

clrscr();

// Las estructuras for sirven para entrar los elementos fila a fila

for (i=0; i<FILAS ; i++)for(j=0; j<COLUMNAS ;j++)

{printf(“Entrar la temperatura : “);scanf(“%d”,&Temperatura[i][j]);

}

// Cálculo de la media por cada 5 días

for(i=0; i<FILAS ; i++){

Media=0;for( j=0; j<COLUMNAS; j++)

{Media=Media+Temperaturas[i][j];

}Media=Media / COLUMNAS;printf(“La media de los %d 5 días es %d \n”,i+1,Media);

}

}

Arrays bidimensionales como argumentos de funciones.

Se especifican de la manera siguiente:

tipo_función nombre(tipo_datos nombre_array[][Num Columnas]) ;

Haciendo una función para entrar valores en el array Alumnos:

void entrar_valores(int Alumnos[][3]) ;

Page 9: Manejo de Arrays

Inicialización de arrays bidimensionales.

Los arrays bidimensionales se pueden inicializar en la declaración de la manera siguiente:

int tabla[3][3] = { {1, 2, 3}, {4, 5, 6}, { 7, 8, 9} } ;fila 0 fila 1 fila 2

Arrays de carácteres. Cadenas.

Después de esta sección será posible entrar textos desde el teclado y guardarlos; un texto no es más que un grupo de carácteres. Tal y como es de suponer, para guardar textos se utilizan arrays de carácteres.

Los arrays de carácteres tienen una particularidad; a menudo nos encontramos con que debemos entrar textos con distinto número de carácteres en un mismo array. Por ejemplo, en el programa de los Alumnos ( aquel que sólo guardaba las notas ), se sabía exactamente cuantas notas se debían entrar ( tantas como alumnos ), entonces en la declaración se debe dimensionar el array en consecuencia ; este caso nos lo encontraremos en la mayoría de programas que gestionan arrays numéricos. No obstante con los arrays de carácteres, normalmente no sucede esto; piense en un array de carácteres que se utilice para entrar el nombre de una persona, hay nombres de tres letras, de cuatro, de cinco...

Para saber el número de elementos que se encuentrán en un array de carácteres, o mejor dicho, dónde termina el texto introducido en un array de carácteres, se adoptó la convención de que el último carácter fuera el 0 binario. Todas las funciones de manejo de carácteres definidas en Turbo C siguen esta convención. Así pues, al guardar en un array por ejemplo el nombre Pepe, se deberá procurar guardar el nombre Pepe0. El 0 binario en lenguaje C se representa ‘\0’.

Funciones para entrada de carácter.

#include <stdio.h>#include <conio.h>

main(){

char nombre[10] ;

scanf(“%s”,nombre) ;printf(“%s”,nombre) ;

}

Si entramos un nombre compuesto, por ejemplo Mari Pili, la función printf sólo mostrará Mari; recordar la función scanf supone final de entrada un espacio en blanco.

En Turbo C existe una función definida para entrar cadenas de carácteres, se trata de la función gets(). También existe una función que puede substituir el prinf(“%s”) , la función puts(). Así el programa con estas dos nuevas funciones quedará de la manera siguiente:

Page 10: Manejo de Arrays

#include <stdio.h>#include <conio.h>

main(){

char nombre[10] ;gets(nombre) ;puts(nombre) ;

}

Tanto la función gets(), como la función scanf(“%s), ponen automáticamente un ‘\0’ al final del array que se entra.

Para entrar una cadena con scanf, ponga scanf(“%s”, cadena) sin el operador &. Por qué ? Sorpresa!! Lo verá en el tema de punteros.

Problemas de la función gets().

La función gets() presenta un problema. Supongamos que en el programa anterior se entra un nombre tal como Carlitos Alberto José, que tiene 22 carácteres, 21 del nombre más el carácter ‘\0’; en la declaración hemos definido Nombre, como un array de 10 carácteres, así pues se están poniendo carácteres en posiciones de memoria no reservadas para el programa. Recuerde que al hacer esto, los resultados pueden ser imprevisibles !!

Una posible solución sería construir una función para entrar cadenas de carácteres que controlará el número, y que al mismo tiempo, por compatibilidad con las funciones de gestión de cadenas definidas en C entre otras, acabarán en‘\0’. La entrada de carácteres cesaría al pulsar ENTER, o bien cuando el número de carácteres llegara a la longitud del array. Haremos una función llamada Entrar_Cadenas a la qual le pondremos como primer parámetro el array de carácteres sobre el qual se hace esta entrada ( recuerde que al pasar un array a función se trabaja con el array pasado ), y como segundo parámetro, un valor indicando el número máximo de carácteres que se pueden entrar en el array.

#include <stdio.h>#include <conio.h>

#define TAMANYO 11 // declaramos uno más por el ‘\0’

void entrar_cadenas(char cadena[], int Long_Cadena) ;

main(){

char nombre[TAMANYO] ;

entrar_cadenas(nombre, TAMANYO) ;puts(nombre) ;

}

Page 11: Manejo de Arrays

void entrar_cadenas(char cadena[], int Long_Cadena){

int i=0 ;

cadena[Long_Cadena-1] = ‘\0’ ; // ponemos‘\0’ en la última posición del array

do{

cadena[i] = getche() ;i=i+1 ;

}while(cadena[i-1] = 13 && i < Long_Cadena- 1) ;

// mientras no se pulse ENTER y haya espacio para los caracteres

if (cadena[i-1] == 13) // Si se ha salido con ENTERcadena[i-1] = ‘\0’ ;// poner 0 al final de la cadena

}

Por qué utilizamos el parámetre Long_Cadena, en vez de utilitzar directamente la constante TAMANYO. ???

Esta función es una posible solución, sin embargo, se puede mejorar. Vea el siguiente párrafo y pruebe de construir una función para entrar cadenas que permita borrar un carácter con la tecla borrar atrás.

Al pulsar la tecla de borrar anterior, se genera el carácter‘\x8’. Recomendación: no se debe entrar directamente el valor devuelve getche() en el array; entrelo sobre una variabe tipo char, y en función del valor que tome dicha variable, haga las acciones correspondientes. Vea el siguiente algoritmo:

ConstantesTAMANYO = 10 ;

TipoCadenaCar = Array [1..TAMANYO] de caracteres ;

VariablesCadena : CadenaCar ;

InicioEscribe(‘Entrar la cadena ‘) ;Entrar_Cadenas(Cadena, TAMANYO) ;

Fin.

Page 12: Manejo de Arrays

Función Entrar_Cadenas(cadena : CadenaCar ; Long_Cadena :Entero) ;

Variablesi : Entero;Tecla ; carácter ;

Inicioi :=0 ;Hacer

Tecla :=CogerCaracter() ; // Leer un carácter del tecladoSi (Tecla = BORRAR) Entonces

Inicioi:=i-1 ;cadena[i] := ‘\0’ ;

FinSino

Si Tecla <> ENTER EntoncesInicio

cadena[i] = Tecla ;i :=i+1 ;

finfinBorrarPantalla();Escribe(Cadena) ;

Mientras(Tecla <> ENTER y i < Long_Cadena) ;

Si (Tecla = ENTER) EntoncesCadena[i] = ‘\0’

Fin.

El programa puede mejorar mucho todavía, control de teclas del cursor, control de la tecla SUPR, control de inserción o sobreescritura...

Siempre que se quiera recorrer una cadena de carácteres acabada en‘\0’, se puede utilizar la estructura siguiente:

i=0 ;while (cadena[i] != ‘\0’)

{....i++;

}

Ejemplo, programa que cuente cuantas ‘A’ hay en una cadena de carácteres.

.

.Entrar_Cadenas(Cadena; Long_Cadena) ;Num :=ContarVocales(Cadena) ;Escribe(‘La cantidad de vocales de la cadena es : “,Num) ;..

Función ContarVocales(Cadena : Tipo_Cadena, Long_Cadena:Entero) : Entero;

Variablesi, NumVocales :Entero ;

Page 13: Manejo de Arrays

Inicioi :=0 ;NumVocales :=0 ;

Mientras(Cadena[i] <> ‘\0’) HacerInicio

Si (Cadena[i] = ‘A’ O Cadena[i]=’a’ ) EntoncesNumVocales := NumVocales + 1 ;

i := i + 1 ;Fin ;

Devolver(NumVocales) ;Fin

Inicializar arrays de carácteres.

Puede utilizar cualquiera de las dos formas.

char saludación[5]= { ‘h’,’o’,’l’,’a’,’\0’} ;

o bien,

char saludación[5] = “Hola” ; // Declaramos el array de 5 porqué en la última posición

// del array ‘\0’, forma automática.

Funciones definidas en C por control de cadenas.

Para poder utilizar estas funciones recordar de poner la línea

#include <string.h>.

int strlen(char *cadena)Devuelve el número de carácteres de la cadena.

Longitud=strlen(Nombre) ;

char *strlwr(char *cadena) Convierte una cadena en minúsculas.

strlwr(Nombre) ;

char *strupr(char *cadena) Convierte una cadena en mayúsculas.

strupr(Nombre) ;

int strcmp(char *cadena1, char *cadena2) ;Compara dos cadenas, devuelve 0 si son iguales; un valor > 0 si cadena1 > cadena2 y un valor < 0 si cadena2 a cadena1.

Valor = strcmp(cadena1, “Pepe”) ;

Page 14: Manejo de Arrays

char *strcat(char *Cad_Desti,char *Cad_Origen) Añade al final de Cad_Destino, Cad_Origen.

Cad_Destino = “José ” ;Cad_Origen = “ María” ;strcat(Cad_Destino,Cad_Origen) ;puts(Cad_Destino) ; // Mostrará José María.

char *strcpy(char *Cad_Destino, char Cad_Origen) ;Copia en Cad_Destino la cadena Cad_Origen .

strcpy(Cad_Destino,Cad_Origen) ;

Hay muchas más pero estas son las más utilizadas. Para ver todas las funciones que incluye Turbo C para la manipulación de cadenas de carácteres, teclear la palabra sting, poner el cursor encima y puslar CTRL+F1 ( tambien se puede poner el cursor encima de la palabra <string.h> de la cabecera.

Page 15: Manejo de Arrays

Métodos de ordenación.

Muchas de las funciones en las cuales se utlizan arrays, se agilizan mucho si éstos están ordenados. A continuación se muestran varios métodos de ordenación, que son efectivos siempre y cuando los arrays no sean muy extensos. Para ordenar arrays de mayor volumen mejor utilizar otros métodos, como por ejemplo QuickShort ( método que veremos en el tema de la recursividad ).

Los métodos siguientes se explican en notificación algorítmica; como ejercicio deberéis codificarlos vosotros en lenguaje C.

Método de selección directa.

Este método consite en:

1. Coger el elemento de la posición I de un array.2. Comparar este elemento con el resto, la trama que va desde posición I+1 hasta el final

para encontrar el elemento más pequeño, y la posición que ocupa.3. Intercambiar las posiciones del elemento de la posición I, con el más pequeño de la

trama.

Por ejemplo, para ordenar el array compuesto por los elementos 5, 8, 1, 3, 4

0 1 2 3 4 Posiciones; i es la variable índice que determina la posición del elemento tratado.

5 8 1 3 4 i=0; Elemento tratado = 5; Intercambio con 1 de posición 2

1 8 5 3 4 i=1; Elemento tratado= 8; Intercambio con 3 de posición 3

1 3 5 8 4 i=2; Elementos tratados = 5; Intercambio con 4 de posición 4

1 3 4 8 5 i=3; Elemento tratado = 8; Intercambio con 5 de posición 4

1 3 4 5 8 Array ordenado.

TipoTabla = Array[1..N] de Enteros;..

Función Ordenar_Selección(T:Tabla)

Variables;i : Entero; // Índice para recorrer el array.K:Entero; // Índice para recorrer la trama.Posición: Entero; // Variable para guardar la posición del más pequeño;Pequeño: Entero; // Variable para guardar el valor más pequeño de la trama.

Page 16: Manejo de Arrays

Inicio

Para i:=0 Hasta N-1 HacerInicio

Pequeño := T[i];Posición := i;

Para k := i+1 HastaN Hacer // Recorrer trama desde pos. i+1 hasta el finalInicio

Si (T[k] < Pequeño) Entonces // Si elemento de trama menor que el más pequeñoInicio

Pequeño:= T[k]; // Guardar valor más pequeñoPosición := K; // Guardar posición que ocupa

FisiFin

T[Posición] := T[i];// Intercambiar elemento de posición i por elemento más pequeñoT[i] := Pequeño;

FinParaFin;

Método de la burbuja.

Este método consiste en coger el último elemento del array, y bajarlo a la posición que le corresponde. Esto se consigue comparando el elemento de la posición N, con el elemento de la posición N-1. si el elemento de la posición N < elemento de la posición N-1, se intercambian los valores.

0 1 2 3 4 Posiciones; K es la variable índice que va de 4 a i

Bucle contador

5555

8881

1118

3333

4444

k=4; Elementos tratados 4 y 3; No hay cambiok=3; Elementos tratados 3 y 1; No hay cambiok=2; Elementos tratados 1y 8; Intercambiok=1; Elementos tratados 5 y 1; Intercambio

i=0

111

555

883

338

444

k=4; Elementos tratados 3 y 4; No hay cambiok=3; Elementos tratados 8 y 3; Intercambiok=2; Elementos tratados 5 y 3; Intercambio

i=1

11

33

55

84

48

k=4; Elementos tratados 4 y 8; Intercambiok=3; Elementos tratados 5 y 4; Intercambio

i=2

1 3 4 5 8 k=4; Elementos tratados 5 y 8; No hay cambio i=31 3 4 5 8 Array Ordenado i=4

Page 17: Manejo de Arrays

TipoTabla = Array[1..N];..

Función Ordenar_Burbuja(T:Tabla)VariablesAux: Entero; // Variable auxiliar para los intercambiosi,k : Entero; // Variables índice

InicioPara i:=0 hasta N Hacer// Pasar tantas veces como elementos haya en el array.

InicioPara k:= N Hasta i Hacer // Comparar los elementos hasta posición i

InicioSi (T[k] < T[k-1]) Entonces // Si elemento de posición K<elemento de

//posición K-1Inicio

Aux := T[k];T[k] := T[k-1]; // Intercambiar elementos.T[k-1] := Aux;

Fin;Fi

Fin;Fin;

Método de inserción directa.

El método de inserción directa consiste en coger los elementos de un array, uno a uno, a partir del segundo y hasta el final. El elemento cogido se guarda en una variable, y se compara con los elementos que le preceden en posición hasta encontrar uno de más pequeño, o bien hasta al límite del array ( posición 0 ). Los elementos del array, mayores que el elemento tratado se van subiendo una posición adelante.

0 1 2 3 4 Posición; i es la variable índice Elemento tratado5 8 1 3 4 i=1, sin cambios, el elemento tratado 8

es mayor que el anterior 58

5 8 1 3 4 i=2, se baja el elemento tratado 1 hasta la primera posición, 5 y 8 son menores que él, no se puede pasar de aquí ya que estamos en posición 0.

1

1 5 8 3 4 i=3, se baja el elemento tratado hasta la segunda posición, 8 y 5 son menores que él.

3

1 3 5 8 4 i=4, se baja el elemento tratado hasta la tercera posición, 8 y 5 son menores que él.

4

1 3 4 5 8 Array ordenado

Page 18: Manejo de Arrays

TipoTabla = Array [1..N] de Enteros;..

Función Ordenar_Inserción(T : Tabla);

Variablesi, k : Enteros; // Índices para recorrer arrayAux : Sencer; // Variable para guardar el elemento tratado

Inicio

Para i:=1 HastaN Hacer // Se empieza a partir del segundo elementoInicio

Aux := T[i]; // Se guarda en Aux el valor del elemento tratadok := i - 1; // Se empiezan a evaluar los elementos anteriores al tratadoMientras (T[k] > Aux i k >=0) Hacer // Mientras se encuentren elementos

mayores // que el tratado y haya elementos

InicioT[k+1] := T[k]; // Desplazar elementos mayores una posición a la derechak := k - 1; // Siguiente elemento

Fin;T[k+1] := Aux; //Poner elemento tratado en su nueva posición.

Fin

Fin;

Existen más métodos para ordenar Arrays, no obstante aquí no se estudiará ningún otro, ni se analizará cual de los tres es el más efectivo, cabe indicar pero, que el método de la burbuja es el de peor comportamiento. Para conseguir un análisis exhaustivo de los distintos métodos de ordenación, hay diversa bibliografía referente a ello. Le recomendamos, no sólo por los métodos de ordenación, sino también para programación en general, el libro de Niklaus Witrh ( creador de Pascal ), “ Algoritmos + Estructuras de datos = Programas “, de la editorial Ediciones del Castillo.

Búsqueda dicotómica o binaria.

Es un algoritmo que permite encontrar rápidamente, un elemento en un array ordenado. Consiste en partir el array en tramas, y mirar si el elemento central de la trama, es el elemento buscado. Funciona de la manera siguiente,

Si la trama es de N elementos, mirar el elemento que se encuentra en la posición N/2. En caso de serlo finaliza la búsqueda, de no ser así, se coge una nueva trama de N/2 elementos, siguiendo estos criterios:

Si el elemento buscado < elemento de posición N/2, la nueva trama irà desde posición 0, hasta posición N/2-1,

Si el elemento buscado > elemento de posición N/2, la nueva trama irà desde posición N/2 +1, hasta posición N

Entonces se volverá a comprobar el elemento que ocupa la posición central de la nueva trama. Estos pasos se irán repitiendo hasta que se encuentre el elemento, o hasta que no haya más elementos para buscar. Vea los ejemplos siguientes

Page 19: Manejo de Arrays

1 4 8 9 13 23 45 El. Busca. Ini. Trama Fi. Trama

Pos. Central Elem. Central

4 0 6 3 9 (>Busca.)4 0 2 1 4 (Encon.)

1 4 8 9 13 23 45 45 0 6 3 9 (<Busca.)45 4 6 5 23 (< Busca.)45 6 6 6 45(Encon.)

1 4 8 9 13 23 45 7 0 6 3 9 (> Busca.)7 0 2 1 4 (< Busca.)

3 2 No Encon.

* Cuando no se encuentra el elemennto Inicio Trama > Fin Trama.

TipoTabla : Array [1..N] de Enteros;..

// La función devuelve posición del elemento si lo encuentra, sino devuelve -1.

Función Búsqueda_Binaria(T : Tabla; Elem_Busca.: Entero): Entero;

VariablesInicio_Trama, Fin_Trama, Mitad_Trama : Entero;

InicioiMitad_Trama := (Inicio_Trama + Fin_Trama) / 2;

Mientras ( Elem_Buscado <> T[Mitad_Trama] i Inicio_Trama <= Fin_Trama)Inicio

Si (Elem_Busca. < T[Mitad_Trama]) EntoncesFin_Trama := Mitad_Trama - 1;

Si (Elem_Busca. > T[Mitad_Trama]) EntoncesInicio_Trama := Mitad_Trama + 1;

Mitad_Trama := (Inicio_Trama + Fin_Trama) / 2;Fini;

Si (Elem_Busca. = T[Mitad_Trama]) EntoncesVolver(Mitad_Trama);

Volver(-1);Fin;