Búsqueda Dicotómica o Binaria
Búsqueda Dicotómica o Binaria
En Ingeniera computacional
El algoritmo de bsqueda dicotmica es una manera muy eficiente de realizar bsquedas en una lista, siempre y cuando sus elementos se encuentren ordenados. No obstante, en algunos casos se utiliza en contextos que hacen que pierda su eficiencia comportndose incluso peor que una bsqueda secuencial. En este artculo describimos el fundamento de la bsqueda dicotmica y reflexionamos acerca de estas situaciones "peligrosas". Por supuesto, tambin proponemos una implementacin sencilla de este tipo de bsqueda.
Este algoritmo acepta como entrada una lista (llammosle v) de valores ordenados, junto con un valor que queremos comprobar si est en la lista (llammosle b). El algoritmo busca en la lista v el valor b, y si lo encuentra devolver la posicin de b dentro de la lista l. Si no lo encuentra, debe indicarlo de alguna manera. Antes de meternos en harina, vamos a reflexionar un poco acerca de las implicaciones que tiene utilizar este algoritmo. Vamos a pensar en una lista de valores que se puedan ordenar por algn criterio... Da igual que sean enteros, cadenas, reales, fechas, coches, perros... el caso es que se puedan ordenar. Utilizaremos enteros, ya que estamos muy familiarizados con el orden que mantienen. Por ejemplo, tomemos esta lista: 7, 4, 33, 18, 15, 20, 19, 26, 5 Los elementos en la lista siguen una secuencia... El 7 est en la primera posicion, el 4 en la segunda... etc... Sin embargo, no tienen orden. Bien... supongamos que quiero saber si el nmero 20 est en la lista, y si es as, qu posicin ocupa. Para qu? Bueno... en este caso puede que tenga poco sentido. Slo es un ejemplo, pero imagina que los elementos de la lista no son un simple entero, sino un objeto,
Universidad de Guadalajara Centro Universitario de los Altos CUALTOS Lic. En Ingeniera computacional
o una estructura o registro que representa a un coche, con su matrcula y un montn ms de caractersticas. Hacer una bsqueda ah por matricula tiene ms sentido no? Vale... pero volvamos al 20. Para saber si est en la lista, como no tiene orden, lo ms sencillo, aparentemente es realizar una bsqueda secuencial. Es decir, comparar el nmero que busco (20) con el primer elemento. Si es igual, ya lo he encontrado, si no, paso al segundo elemento y repito... y as hasta que lo encuentre o hasta que haya recorrido toda la lista. Si no lo encuentro, lo indicar de alguna manera. Este tipo de bsqueda tiene una complejidad lineal, del orden O(n) siendo n el tamao de la lista, es decir, el tiempo que tarda en realizarse en el peor caso crece proporcionalmente con el tamao de la lista. Sin embargo, si la lista est previamente ordenada antes de comenzar, podemos aplicar la estratgia de la bsqueda binaria o dicotmica. Cojamos la misma lista de antes pero ordenada. 4, 5, 7, 15, 18, 19, 20, 26, 33 Seguimos buscando el 20, pero ahora sabemos que la lista est ordenada. La estrategia es similar a la que utilizamos cuando buscamos una palabra en un diccionario gordo: como el diccionario tiene las palabras ordenadas, nunca lo abrimos por la primera hoja... lo abrimos aproximadamente por la mitad, y si la palabra que estamos buscando est antes que las palabras de la hoja que nos ha salido, volvemos a repetir la operacin con la primera mitad de hojas. Si est despus, lo hacemos con la segunda mitad. Es decir, vamos dando saltos porque el hecho de que las palabras estn ordenadas nos lo permite. Hagamos lo mismo con la lista de arriba. Vamos a comparar el 20 con el elemento que est exactamente en la mitad de la lista (para saber cual es, hagamos unos pocos clculos: el primer elemento est en la posicin 1, y el ltimo en la 9... la posicin intermedia ser (9+1)/2... es decir, el 5... ese es el nmero 18. Como el que buscamos es mayor (el 20) y la lista est ordenada, ya s que el 20 no est en el quinto lugar ni en los anteriores. 4, 5, 7, 15, 18, 19, 20, 26, 33 Ahora considerar del 6 al 9. El que queda enmedio es (6+9)/2, es decir 7. Compruebo si el 7 elemento es el que busco... Anda... pues s... As que ya he llegado. La gracia es que cada vez que comparo el elemento que busco con el el de enmedio del intervalo que estoy considerando y no es el que busco, elimino la mitad del intervalo de bsqueda. Eso est muy bien, porque significa que en el peor caso (que el nmero que
Universidad de Guadalajara Centro Universitario de los Altos CUALTOS Lic. En Ingeniera computacional
busco no est en el vector) realizo log2n veces la comparacin... es decir, el algoritmo tiene una complejidad logartimica. La verdad es que parece muy atractivo, y seguro que en muchas ocasiones nos sentimos tentados de implementarlo sin ms. No obstante, para aplicar ste mtodo es necesario hacer algunas consideraciones: Primera: el acceso a un elemento cualquiera de la lista debe tener un coste constante, es decir O(1). Si no es as, el coste del acceso al elemento debe tenerse en cuenta. Por ejemplo... El acceso mediante una lista enlazada a un elemento cualquiera suele tener un coste O(n). Eso significa que utilizar una bsqueda dicotmica nos cuesta O(n log2n), que es bastante peor que el coste de una simple bsqueda secuencial (O(n)). As que es necesario asegurarnos de esto. Slo los arrays, y algunas ingeniosas implementaciones de lista pueden proporcionarnos un coste constante (o casi) de acceso a cualquier elemento. Tambin lo podemos obtener en memoria secundaria con ficheros binarios de acceso aleatorio en los que todos sus registros tengan el mismo tamao. Segunda: Si se han de realizar varias bsquedas y la lista es susceptible de cambiar frecuentemente (porque insertemos o eliminemos elementos) debemos tener en cuenta que la lista debe mantenerse permanentemente en orden. Eso implica que las inserciones y los borrados deben mantener el orden, con lo cual, su complejidad no va a ser constante: probablemente estemos sacrificando la eficiencia de inserciones y borrados en pro de las bsquedas. Tenemos que asegurarnos de que nos compense. Tercera: Por supuesto, resultara absurdo realizar una ordenacin de la lista antes de cada bsqueda. Incluso los algoritmos ms eficientes de ordenacin tienen un coste bastante elevado, que habra que aadir al de la propia bsqueda. Cuarta: El hecho de que la lista est ordenada antes de realizar la bsqueda es obligatorio. Si se aplica una bsqueda dicotmica a una lista no ordenada (aunque slo fuera un elemento) se podra producir gigo. Por supuesto, no se puede comprobar algortmicamente esta condicin, ya que el coste de la comprobacin debera aadirse al de la bsqueda, haciendo que perdiera sus buenas propiedades. Cuantas cosas!!! Entonces Cundo es de utilidad la bsqueda dicotmica? Pues prcticamente, solo en una situacin: Cuando tengamos una lista de valores susceptibles de ser ordenados, y que la importancia que le demos a las operaciones de insercin o borrado de elementos sean muy muy muy muy inferior a la de las bsquedas. La elaboracin del algoritmo en s es bastante secilla y se pueden hacer bastantes variantes (con mnimas diferencias entre ellas). Aqu tienes un pseudocdigo que lo describe y un ejemplo en C#. Si el algoritmo encuentra el valor, devolver su posicin en el array, y si no lo encuentra, devolver un -1 (dado que las posiciones son positivas)
Universidad de Guadalajara Centro Universitario de los Altos CUALTOS Lic. En Ingeniera computacional
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
funcion busquedaBinaria( v:array[1..n] de enteros, b:entero ):entero variables: inferior, superior, medio:entero resultado:entero; empieza //empezamos suponiendo que no hemos //encontrado el valor resultado=-1; //el primer elemento que consideramos inferior=1; //el ultimo elemento que consideramos superior=n; mientras(resultado<0 y inferior<=superior) //calculamos la posicin del elemento medio //entre inferior y superior medio=(inferior+superior)/2; //division entera si v[medio]=x //si lo hemos encontrado en medio resultado=medio si no si b<v[medio] //esta en la mitad inferior superior=medio-1 si no //esta en la mitad superior inferior=medio+1 fin si fin si fin mientras devolver resultado terminar
Quiz te ests preguntando si en lugar de hacer una bsqueda "dicotmica" la hacemos "tricotmica" o "cuatricotmica" (es decir, dividir el intervalo de bsqueda en ms trozos) saldramos ganando algo... pues realmente no: el resultado sera igual o peor. Puedes hacer la prueba intuitivamente contando el nmero de comparaciones que haras en el peor caso. Ten en cuenta que si dividimos el intervalo en tres en lugar de en dos, en el peor caso son necesarias dos comparaciones por iteracin, en lugar de una.... En la bsqueda dicotmica, con dos comparaciones (en dos iteraciones) dividimos el intervalo en cuatro. Si hicieramos la bsqueda "tricotmica", para dividir el intervalo en tres considerando un caso promedio en unas ocasiones necesitamos una comparacin y en otras dos. En un caso promedio nos quedamos ms o menos igual, pero con un algoritmo ms complicado.