Está en la página 1de 6

PROGRAMACIÓN AVANZADA

Alfonso Martı́nez Martı́nez

1 ALGORITMOS DE BÚSQUEDA Y ORDENAMIENTO


1.1 Búsqueda
La búsqueda de algún elemento de información, previamente almacenado, se puede realizar en la memoria o
en el dispositivo de almacenamiento escogido para dar persistencia a los datos generados por un programa:

Búsqueda en memoria en estructuras lineales: búsqueda lineal y búsqueda binaria.

Búsqueda en memoria en estructuras no lineales: tablas de dispersión (Hash), árboles binarios de


búsqueda.

Búsqueda en unidades de almacenamiento a gran escala: árboles ‘B’.

En relación a la búsqueda en la memoria de la computadora, se plantean las siguientes suposiciones:

• se tiene una colección fija de datos

• Los datos se encuentran en la memoria de la máquina (arreglo, lista o tabla)

• Los elementos a buscar tienen una estructura de registro y la búsqueda se realiza sobre la llave del
mismo.

1.1.1 Búsqueda Secuencial


Se utiliza cuando no se tiene información acerca de los datos buscados, procediendo a comparar el elemento
buscado con cada elemento del arreglo o tabla, en forma secuencial.

1. Nombre del algoritmo: busqueda sec

2. Entradas:

(a) Arreglo (ent a[ ]), que contiene todos los elementos y donde se realizará la búsqueda.
(b) El elemento a buscar (ent x).
(c) El número de datos contenidos en el arreglo (ent N).

3. Salida: El algoritmo regresa un entero que representa el ı́ndice del elemento encontrado o -1 si el
elemento no fue encontrado.

4. Algoritmo en lenguaje natural:

(a) mientras no se llegue al final del arreglo hacer:


i. comparar con el elemento buscado x.
ii. Si son iguales terminar.
iii. sino avanzar al siguiente elemento
(b) si se recorrió todo el arreglo, regresar -1
(c) en otro caso, regresar el ı́ndice donde se encuentra el elemento buscado

5. Algoritmo refinado
ent func busqueda sec(ent a[ ], ent x, ent N)
ent i;
comienza
i=0;
mientras(i < N y a[i] 6= x) haz

1
i=i+1
si(i == N-1) entonces
regresa -1;
otro
regresa i;
termina

1.1.2 Búsqueda Binaria


Es un algoritmo del tipo “Divide y Vencerás” en donde en una versión recursiva se plantea:

1. Nombre del algoritmo: busqueda bin

2. Entradas:

(a) Arreglo (ent a[ ]), que contiene todos los elementos y donde se realizará la búsqueda.
(b) El elemento a buscar (ent x).
(c) El lı́mite izquierdo (ent izq) dentro del arreglo, a partir de donde se realizará la búsqueda en
cada llamada recursiva.
(d) El lı́mite derecho (ent der) dentro del arreglo, que define el lı́mite hasta donde se puede realizar
la búsqueda en una llamada recursiva.

3. Salida: El algoritmo regresa un entero que representa el ı́ndice del elemento encontrado o -1 si el
elemento no fue encontrado.

4. Algoritmo en lenguaje natural:

(a) Se determina la mitad del arreglo


(b) El elemento buscado se compara con el elemento de la mitad del arreglo y si son iguales, se regresa
el ı́ndice del elemento del arreglo
(c) Sino, se verifica si el lı́mite izquierdo es menor al derecho, si no se cumple se regresa -1 indicando
que el elemento no se encuentra en el arreglo.
(d) Si el elemento buscado x es menor al de la mitad, se invoca a busqueda bin, enviando el arreglo,
x, izq como lı́mite izquierdo y mitad-1 como lı́mite derecho.
(e) Si el elemento buscado x es mayor al de la mitad, se invoca a busqueda bin, enviando el arreglo,
x, mitad+1 como lı́mite izquierdo y der como lı́mite derecho.

5. Algoritmo refinado
ent func busqueda bin(ent a[ ], ent x, ent izq, ent der)
comienza
si(izq ≤ der) entonces
comienza
mitad=(izq+der)/2;
si(a[mitad]==x) entonces
regresa mitad;
otro si(a[mitad] > x) entonces
regresa busqueda bin(a, x, izq, mitad-1);
otro;
regresa busqueda bin(a, x, mitad+1, der);
termina
otro;
regresa -1;
termina

2
1.2 Ordenamiento
Los algoritmos de ordenamiento planteados en esta sección, consideran lo siguiente:
1. El ordenamiento se realiza en la memoria de la computadora: ordenamiento interno
2. Los datos a ordenar se encuentran almacenados en un arreglo a[ ], con N datos
3. Los elementos a ordenar tienen una estructura de registro y la búsqueda se realiza sobre la llave del
mismo, considerándola como entero.
4. El ordenamiento se realiza sobre el mismo espacio en memoria (a[ ], excepto el de ordenamiento por
intercalación, que requiere de un arreglo auxiliar.)

1.2.1 Ordenamiento por Intercambio (algoritmo de la burbuja).


1. Descripción. Si se requiere que a[i] ≤ a[i+1], se compara el elemento i con el i+1 y se intercam-
bian si a[i] > a[i+1]. Esto garantiza que en cada pasada al arreglo, el elemento mayor encuentre su
lugar y cada recorrido se realice con un elemento menos. Si se recibe un arreglo ordenado, no se deben
producir intercambios, detectándolo hasta completar un recorrido completo; en este caso después de
concluir el primer recorrido, el algoritmo debe detenerse.
2. nombre: burbuja ()
3. Entradas:
(a) Los elementos a ordenar contenidos en el arreglo ent a[ ].
(b) Un valor ent N que indica el número de elementos contenidos en a[ ]
4. Salida: el arreglo a con sus elementos ordenados
5. Algoritmo en lenguaje natural:
(a) Se establece un lı́mite inicial = N-1
(b) Iniciando con i=0, hasta el lı́mite establecido, se comparan a[i] con a[i+1]
i. Si a[i] > a[i+1], se intercambian sus valores
ii. Se pone una bandera para indicar que hubo intercambio.
(c) Se decrementa el lı́mite en uno
(d) Se repite desde 5b hasta que el valor del lı́mite es cero o si no se produjo algún intercambio
6. Algoritmo refinado:
proc burbuja(ent a[ ], ent N)
ent i, limite, auxiliar;
bool indicador;
comienza
limite=N-1;
repite
comienza
indicador = falso;
para i=0 hasta limite-1 haz;
si a[i] > a[i+1] entonces
comienza
auxiliar=a[i];
a[i]=a[i+1];
a[i+1]=auxiliar;
indicador=verdadero;
termina
limite=limite-1

3
termina;
hasta (limite==0) o (indicador==falso);
termina

1.2.2 Ordenamiento por Inserción.


1. Descripción. El arreglo a[ ] se recorre, desde i=2 hasta N, buscando el lugar que le corresponde
hacia la izquierda a cada elemento en turno. Una vez encontrado el lugar se inserta y se continua con
el elemento i+1.

2. Nombre ord por insercion()

3. Entradas

(a) Los elementos a ordenar contenidos en el arreglo ent a[ ].


(b) Un valor ent N que indica el número de elementos contenidos en a[ ]

4. Salida: el arreglo a con sus elementos ordenados

5. Algoritmo en lenguaje natural

(a) Para el segundo elemento de a[ ] hasta el último hacer:


i. Resguardar el elemento en turno en una variable auxiliar.
ii. recorrer el arreglo hacia la izquierda y mientras no se llegue al lı́mite izquierdo del arreglo y
el elemento en turno sea menor al auxiliar, recorrer el elemento en turno hacia la derecha.
iii. Si no se llegó al lı́mite izquierdo del arreglo, insertar el auxiliar en el lugar donde la condición
auxiliar < a[j] ya no se cumplió

6. Algoritmo refinado
proc ord por insercion(ent a[ ], ent N)
ent i, j, auxiliar;
bool indicador;
comienza
para i=1 hasta N-1 haz;
comienza
indicador = verdadero;
auxiliar=a[i];
j=i;
mientras indicador haz;
comienza
si j==0 entonces
indicador=falso;
otro si auxiliar < a[j-1] entonces
comienza
a[j]=a[j-1];
j=j-1;
termina
otro
indicador=falso;
termina
a[j]=auxiliar;
termina
termina

4
1.2.3 Ordenamiento por Intercalación (Merge Sort).
1. Descripción. Se trata de un algoritmo recursivo del tipo “divide y vencerás”. El arreglo de entrada
se divide a la mitad y se invoca a si mismo para ordenar por intercalación las dos mitades resul-
tantes; cuando las dos mitades han quedado ordenadas se invoca a un procedimiento para intercalarlas
almacenando el resultado en un arreglo temporal y regresándolo en el arreglo original.

2. Nombre: ord intercalacion()

3. Entradas:

(a) Los elementos a ordenar contenidos en el arreglo ent a[ ].


(b) Un valor ent N que indica el número de elementos contenidos en a[ ].
(c) Un arreglo temporal ent atemp[ ], en donde se almacenan resultados parciales.
(d) El lı́mite izquierdo (ent izq) dentro del arreglo, a partir de donde se realizará el ordenamiento
por intercalación en cada llamada recursiva.
(e) El lı́mite derecho (ent der) dentro del arreglo, que define el lı́mite hasta donde se realizará el
ordenamiento por intercalación en cada llamada recursiva.

4. Salidas: el arreglo a con sus elementos ordenados.

5. Algoritmo en lenguaje natural

(a) Se verifica que el lı́mite izquierdo sea menor que el derecho.


(b) Si se cumple
i. Se determina la mitad del arreglo de entrada a[ ].
ii. Se invoca a búsqueda binaria para ordenar la primera mitad.
iii. Se invoca a búsqueda binaria para ordenar la segunda mitad.
iv. Se invoca a un procedimiento intercala, para intercalar las dos mitades previamente ordenadas.

6. Algoritmo refinado
proc ord por intercalacion(ent a[ ], ent atemp[ ], ent izq, ent der)
ent mitad;
comienza
si izq < der entonces
comienza
mitad=(izq + der)/2;
ord por intercalacion(a, atemp, izq, mitad);
ord por intercalacion(a, atemp, mitad+1, der);
intercalar (a, atemp, izq, mitad+1, der);
termina
termina

1.2.4 Ordenamiento Rápido (Quick Sort)


1. Descripción. Éste algoritmo, al igual que el de intercambio, plantea la realización de intercambios
pero a distancias largas. Para ello se selecciona un elemento del arreglo (la selección puede ser aleatoria),
llamado pivote, para compararlo con los elementos de la derecha del arreglo y posteriormente con los
de la izquierda, e intercambiar un elemento del lado izquierdo, cuando es mayor al pivote, con un
elemento del lado derecho, cuando es menor al pivote. Se aplica recursivamente el proceso anterior
para los elementos que se encuentren del lado izquierdo del pivote y a los del lado derecho de éste.

2. Nombre: ord rapido()

3. Entradas:

5
(a) Arreglo (ent a[ ]), que contiene todos los elementos a ordenar.
(b) El lı́mite izquierdo (ent izq) dentro del arreglo, a partir de donde se realizará el ordenamiento.
(c) El lı́mite derecho (ent der) dentro del arreglo, que define el lı́mite hasta donde se puede realizará
el ordenamiento.
4. Salida: el arreglo a[ ] con sus elementos ordenados.
5. Algoritmo en lenguaje natural:
(a) Se selecciona algún elemento del arreglo a[ ] como pivote.
(b) Se recorre el arreglo desde la izquierda y mientras el elemento en turno sea menor que el pivote
se continua el recorrido. El recorrido se detiene cuando el elemento en turno es mayor o igual al
pivote.
(c) Se recorre el arreglo desde la derecha y mientras el elemento en turno sea mayor que el pivote
se continua el recorrido. El recorrido se detiene cuando el elemento en turno es menor o igual al
pivote.
(d) Si no se cruzaron los recorridos, se intercambian los elementos que se encontraban en turno en los
recorridos anteriores.
(e) Se repite el proceso desde el paso 5b, a partir de la detención de los recorridos, hasta que los
recorridos se cruzan. Con esto se garantiza que todos los elemento de la izquierda del pivote son
menores que éste y todos los elementos a la derecha son mayores al pivote.
(f) Si existen elementos a la izquierda del pivote, se ordenan invocando recursivamente a
ord rapido().
(g) Si existen elementos a la derecha del pivote, se ordenan invocando recursivamente a ord rapido().
6. Algoritmo refinado:
proc ord rapido(ent a[ ], ent izq, ent der)
ent i, j, auxiliar, pivote;
comienza
i=izq;
j=der;
pivote=a[(izq+der)/2]; /* la elección puede ser diferente */
repite
comienza
mientras a[i] < pivote haz;
i=i+1;
mientras a[j] > pivote haz;
j=j-1;
si i < j entonces
comienza
auxiliar=a[i];
a[i]=a[j];
a[j]=auxiliar;
i=i+1;
j=j-1;
termina
termina
hasta i > j;
si izq < j entonces
ord rapido(a,izq,j);
si i < der entonces
ord rapido(a,i,der);
termina

También podría gustarte