Almaz Mubinov

Реализация алгоритма бинарного поиска на PHP

21 Июн 2012 г. 

Существует известный алгоритм поиска элемента в отсортированном массиве, называемый бинарным (двоичным) поиском. Его суть заключается в делении массива на половины и сравнении искомого с элементом, который располагается в середине вновь получившегося отрезка. Многие реализации грешат мелкими недочетами и работают только в указанном диапазоне. Предлагаю Вам еще один вариант, в котором я постарался учесть все возможные ситуации, сохранив при этом красоту и структуру кода. Алгоритм реализован на PHP.

  1. /**
  2.  * Функция бинарного поиска по упорядоченному массиву
  3.  * @param array $source_array Упорядоченный по возрастанию массив целых чисел
  4.  * @param int $search_value Искомая величина
  5.  * @return bool|int
  6.  */
  7. function binary_search(&$source_array, $search_value){
  8. $count = count($source_array);
  9. if($count < pow(2, 31) && is_int($search_value)){
  10. $start = 0;
  11. $end = $count — 1;
  12. while(true){
  13. $len = $end — $start ;
  14. if($len > 2){
  15. if($len % 2 != 0)$len++;
  16. $mid = (int) ($len/2 + $start);
  17. }elseif($len >= 0){
  18. $mid = $start;
  19. }else{
  20. return false;
  21. }
  22. if($source_array[$mid] == $search_value){
  23. while( ($mid != 0) && ($source_array[$mid — 1] == $search_value))
  24. $mid—;
  25. return $mid;
  26. }elseif($source_array[$mid] > $search_value){
  27. $end = $mid — 1;
  28. }else{
  29. $start = $mid + 1;
  30. }
  31. }
  32. }else{
  33. return false;
  34. }
  35. }

Алгоритм является классическим и в каких то особенных комментариях не нуждается.
Из полезного:

$count < pow(2, 31)

Здесь мы проверяем длину массива для защиты от переполнения буфера.


while( ($mid != 0) && ($source_array[$mid - 1] == $search_value))
$mid--;

Если в нашем исходном массиве нужное нам значение встречается несколько раз, то с помощью этого кода мы получим первое вхождение искомого значения в массив.

Использование:

$array = array(15,58,5954);
sort($array);
$search_value = 15;
if(false !== $result = binary_search(&$array, $search_value)){
var_dump("Result id:" . $result);
var_dump("Result value:" . $array[$result]);
}

Результатом работы функции является порядковый номер элемента в массиве (нумерация начинается с нуля). Если элемент не найден, то возвращается FALSE (необходимо строгое сравнение с false === или !==, т.к. функция может вернуть 0, если элемент в самом начале массива).


Разработка
Almaz Mubinov © 2010-2023