Está en la página 1de 7

Con el fin de ilustrar la forma de como un problema se puede resolver de diferentes maneras y

determinar el impacto en el cálculo de la complejidad, se plantearán los siguientes ejemplos:

EL PROBLEMA DE LA BUSQUEDA
Cómo determinar si un elemento se encuentra entre un arreglo cuyos elementos están ordenados
ascendentemente.

BUSQUEDA LINEAL

Sin aprovechar la información de que el arreglo está ordenado, se recorre el arreglo desde el principio
hasta el fin comparando el valor a buscar con cada uno de los elementos del arreglo y si lo encuentra la
respuesta es afirmativa, de lo contrario si llega al final del arreglo la respuesta es negativa.

int buscar1(intvector[ ],int n, int valor)


{

int i, encontro=0;
for(i = 0, i < n; i++)
if(vector[i] == valor)
encontro = 1;

return encontro;
}

Analizando el algoritmo de buscar1, se aprecia que este siempre recorrerá la totalidad del arreglo para
encontrar el resultado independientemente de si el valor se encuentra o no y de la posición que ocupe.
Ya que este algoritmo funciona independientemente de los datos que procesa, el mejor, peor y caso
promedio son siempre iguales, por lo tanto la complejidad es la misma O(n).

Object 1
BUSQUEDA LINEAL ACOTADA
En una segunda aproximación, se le puede introducir una mejora en la cual una vez encontrado el valor
entre el arreglo no siga buscando y retorne la respuesta.

int buscar2(intvector[ ],int n, int valor)


{

inti, encontro=0;
for(i = 0, (i < n && encontro ==0); i++)

if(vector[i] == valor)

return encontro;
}

Para algunos algoritmos, como buscar2, diferentes valores en las entradas para un tamaño dado pueden
requerir diferentes cantidades de tiempo en procesarlas, pudiéndose identificar algunas veces el mejor,
el peor y el caso promedio de solución. La ventaja de analizar cada caso radica en que se puede
determinar con el peor de los casos que al menos el algoritmo se desempeñará de esa forma o mejor.
Cuando un algoritmo se ejecuta muchas veces para diferentes valores de entrada, es importante
determinar el comportamiento promedio o típico, que se asemejará mas a la realidad.
Desafortunadamente, esto no siempre sucede y para determinar estrictamente la eficiencia de un
algoritmo se debe suponer el peor caso.
Para el algoritmo buscar2 que se está analizando, si el valor a buscar está en las primeras posiciones
del arreglo, la solución será muy rápida O(1), de lo contrario si el valor se encuentra en una de las
últimas posiciones o no se encuentra la solución será más lenta O(n).
Comparando buscar2 con buscar1, el primero es mas eficiente ya que en caso de encontrar el resultado
no recorrerá el resto del arreglo; el tiempo de ejecución dependerá de los datos, teniendo que en el
mejor caso el valor estará ubicado en la primer posición del arreglo vector [0], en el peor caso no se
encuentra siendo necesario recorrer la totalidad del arreglo comoen buscar1. Por lo tanto la
complejidad total de buscar2 es O(n).
Object 2

BUSQUEDA LINEAL ANALIZANDO EXTREMOS


Si se aprovecha la información suministrada en el problema indicando que el arreglo se encuentra
ordenado ascendentemente, se pueden realizar diferentes mejoras a la solución planteada así: si el valor
a buscar es menor que el primer elemento del arreglo o el valor a buscar es mayor que el último
elemento del arreglo eso significa que el valor no se encuentra y por lo tanto no será necesario realizar
su búsqueda.

int buscar3(intvector[ ],int n, int valor)


{

inti, encontro=0;
if (vector[0] < valor || vector[n-1] > valor)

return encontro;

for(i = 0, (i < n && encontro ==0); i++)

if(vector[i] == valor)

encontro = 1;

return encontro;
}
Teniendo en cuenta la mejora obtenida, la complejidad de todas maneras se debe analizar bajo el mejor,
peor y caso promedio, dándose el siguiente resultado:
En el mejor caso el elemento está por fuera de los límites del arreglo, saliendo en el primer condicional
lo que representa una complejidad constante de O(1),en el peor caso el elemento no se encuentra,
siendo necesario recorrer la totalidad del arreglo con una complejidad de O(n), y si el elemento se
encuentra en una de las posiciones intermedias del vector, su complejidad será de O(n/2) que es O(n).
Por lo tanto la complejidad global del algoritmo buscar3 es de O(n).

Object 3

BUSQUEDA LINEAL LIMITADA SEGUN ORDEN


Se puede mejorar el algoritmo buscar3 de tal manera que aprovechando la información de que el vector
está ordenado, cuando se busque un elemento y se encuentre uno mayor que el buscado, es que dicho
elemento no se encuentra en el arreglo y no se debe continuar con la búsqueda.

int buscar4(intvector[ ],int n, int valor)


{

inti, encontro=0;
if (vector[0] < valor || vector[n-1] > valor)

return encontro;
i = 0;
while (i < n && vector[i]<=valor)
{
if(vector[i] == valor)
encontro = 1;

i++;
}
return encontro;
}

a pesar de que los algoritmos buscar3 y buscar4 son similares diferenciándose básicamente en la salida
del ciclo, su comportamiento es similar mejorando en el caso promedio ya que este evitará muchos
recorridos sobre el arreglo.
Su complejidad basada en el peor caso será de O(n).

BUSQUEDA LINEAL LIMLITADA SEGUN ORDEN RECURSIVA


Planteando una solución recursiva basada en el algoritmo buscar4 se tiene:

int buscar5 (intvector[ ],int n, int valor)


{

intencontro=0;
if (n==0)
return 0;
if (vector[n-1] == valor)
return 1; if (vector[0] < valor || vector[n-1] > valor) return 0; return (buscar5(vector, n-1,
valor));
}

este algoritmo se asemeja al comportamiento de la función buscar4, ya que la recursión se puede


comportar como un ciclo, ya que el tamaño del problema se reduce en 1 para cada llamado recursivo
con condiciones de salida iguales a las de buscar4, siendo su complejidad O(n).

BUSQUEDA BINARIA ITERATIVA


Aprovechando aun mejor la información de que el arreglo está ordenado se puede aplicar la estrategia
de búsqueda binaria dando como resultado:

int buscar6 (intvector[],int n, int valor)


{

intmedio, inicio=0, fin = n-1, encontro = 0;


while (inicio < fin && encontro ==0)
{
medio= (int) (incio+fin) / 2;
if (vector[medio] == valor)

encontro=1;

Else

if (vector[medio] > valor)

fin = medio – 1;

else

inicio = medio + 1;
}
return encontro
}

la búsqueda binaria divide el espacio de búsqueda cada vez a la mitad, comportándose de la siguiente
manera: n, n/2, n/4, n/8, n/16... esta serie tiene un comportamiento logarítmico, por lo cual el ciclo en el
peor de los casos se realizará (log2 n) veces, generando una complejidad de O(log2 n)).

Object 4

BUSQUEDA BINARIA RECURSIVA


una solución recursiva de buscar6 es la siguiente:

int buscar7rec (intvector[],int inicio, int fin, int valor)


{
intmedio=(int) (inicio+fin) / 2, encontro = 0;
if (inicio > fin)

return 0;
if (vector[medio] == valor) return 1;
else

if (vector[medio] > valor)

return (buscar7rec(vector, incio, medio – 1, valor));


else return (buscar7rec(vector, medio + 1, fin, valor)); }
int buscar7 (intvector[],int n, int valor)
{

if (vector[0] < valor || vector[n-1] > valor)

return 0;
return (buscar7rec(vector, 0, n-1, valor)); }
el algoritmo buscar7 se comporta de la misma manera que buscar6, solo que el ciclo se implementa
bajo el esquema recursivo, por lo que en el peor de los casos se realizarán (log2 n) llamados recursivos,
generando una complejidad del ordenO(log2 n).
Es importante anotar que desde el punto de vista computacional, los algoritmos recursivos consumen
más recursos que los algoritmos iterativos, ya que el hecho de guardar todas las variables de contexto y
el cambio de ambiente consumen más memoria y tiempo de CPU.

También podría gustarte