Documentos de Académico
Documentos de Profesional
Documentos de Cultura
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 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.
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
inti, encontro=0;
if (vector[0] < valor || vector[n-1] > valor)
return encontro;
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
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).
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));
}
encontro=1;
Else
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
return 0;
if (vector[medio] == valor) return 1;
else
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.