Статья
Алгоритмы поиска

Алгоритмы поиска

25 ноября 2020

Линейный поиск


Самый простой алгоритм - циклически проходим по элементам массива (среза), сравнивая каждый элемент с искомым.
Алгоритмическая сложность - линейная O(N).

Пример на Go

package main

import "fmt"

func search(data []int, search int) int {
   for i := range data {
      if data[i] == search {
         return i
      }
   }

   return -1
}

func main() {
   testData := []int{7, 2, -5, 3, 1, 9, 8}

   fmt.Println(search(testData, 9)) // 5
   fmt.Println(search(testData, 4)) // -1
}


Пример на PHP

function search(array $data, int $search): int
{
    for ($i = 0; $i < count($data); $i++) {
        if ($data[$i] === $search) {
            return $i;
        }
    }

    return -1;
}

$testArray = [7, 2, -5, 3, 1, 9, 8];

echo search($testArray, 9) . PHP_EOL; // 5
echo search($testArray, 4) . PHP_EOL; // -1

 

 

Бинарный поиск


Работает только с отсортированными массивами (срезами). Определяем минимальный и максимальный индексы, далее рассчитываем индекс, находящийся между ними (середина). Если искомое значение меньше серединного, отбрасываем правую часть, если больше, то левую часть. Далее повторяем шаги рекурсивно.
Алгоритмическая сложность - логарифмическая O(log N).

Пример на Go

package main

import "fmt"

func search(data []int, search int) int {
   minIndex := 0
   maxIndex := len(data) - 1

   for minIndex <= maxIndex {
      middleIndex := (minIndex + maxIndex) / 2

      if search < data[middleIndex] {
         maxIndex = middleIndex - 1 // Отбрасываем правую часть
      } else if search > data[middleIndex] {
         minIndex = middleIndex + 1 // Отбрасываем левую часть
      } else {
         return middleIndex
      }
   }

   return -1
}

func main() {
   testData := []int{-4, -2, 0, 1, 4, 6, 7, 11}

   fmt.Println(search(testData, 6))  // 5
   fmt.Println(search(testData, -3)) // -1
}


Пример на PHP

function search(array $data, int $search): int
{
    $minIndex = 0;
    $maxIndex = count($data) - 1;

    while ($minIndex <= $maxIndex) {
        $middleIndex = intval(($minIndex + $maxIndex) / 2);

        if ($search < $data[$middleIndex]) {
            $maxIndex = $middleIndex - 1; // Отбрасываем правую часть
        } else if ($search > $data[$middleIndex]) {
            $minIndex = $middleIndex + 1; // Отбрасываем левую часть
        } else {
            return $middleIndex;
        }
    }

    return -1;
}

$testArray = [-4, -2, 0, 1, 4, 6, 7, 11];

echo search($testArray, 6) . PHP_EOL;  // 5
echo search($testArray, -3) . PHP_EOL; // -1

 

 

Интерполяционный поиск


Работает только с отсортированными массивами (срезами). Данный алгоритм похож на бинарный за одним исключением - он пытается угадать расположение элемента.
Алгоритмическая сложность - логарифмическая O(N) - наихудшая, O(log(log N)) - ожидаемая.

Пример на Go

package main

import "fmt"

func search(data []int, search int) int {
   minIndex := 0
   maxIndex := len(data) - 1

   for data[minIndex] <= search && data[maxIndex] >= search {
      middleIndex := minIndex + ((search-data[minIndex])*(maxIndex-minIndex))/(data[maxIndex]-data[minIndex])

      if search < data[middleIndex] {
         maxIndex = middleIndex - 1 // Отбрасываем правую часть
      } else if search > data[middleIndex] {
         minIndex = middleIndex + 1 // Отбрасываем левую часть
      } else {
         return middleIndex
      }
   }

   return -1
}

func main() {
   testData := []int{-4, -2, 0, 1, 4, 6, 7, 11}

   fmt.Println(search(testData, 7))  // 6
   fmt.Println(search(testData, -3)) // -1
}


Пример на PHP

function search(array $data, int $search): int
{
    $minIndex = 0;
    $maxIndex = count($data) - 1;

    while ($minIndex <= $maxIndex) {
        $middleIndex = $minIndex + intval((($search - $data[$minIndex]) * ($maxIndex - $minIndex)) / ($data[$maxIndex] - $data[$minIndex]));

        if ($search < $data[$middleIndex]) {
            $maxIndex = $middleIndex - 1; // Отбрасываем правую часть
        } else if ($search > $data[$middleIndex]) {
            $minIndex = $middleIndex + 1; // Отбрасываем левую часть
        } else {
            return $middleIndex;
        }
    }

    return -1;
}

$testArray = [-4, -2, 0, 1, 4, 6, 7, 11];

echo search($testArray, 7) . PHP_EOL;  // 6
echo search($testArray, -3) . PHP_EOL; // -1



Источники:
https://en.wikipedia.org/wiki/Linear_search
https://en.wikipedia.org/wiki/Binary_search_algorithm
https://en.wikipedia.org/wiki/Interpolation_search