В бинарном поиске мы используем дробление отсортированного массива на половины.
// Сначала создаем массив и переменную для счета операций. Массив обязательно должен быть отсортирован.
const array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let count = 0;
// Далее мы создаем функцию с 2 аргументами. Первый - массив в котором ищем и второй - сам элемент который ищем.
function binarySearch(array, item) {
// Внутри функции мы создаем нужные для работы переменные
let start = 0; // Начальная позиция массива. Это наш первый элемент(индекс 0)
let end = array.length; // Конечная позиция. Это наш последний элемент(Вычесляем по длине массива)
let middle; // Это средний элемент в массиве. Вычеслять будем в цикле ниже.
let found = false; // Некий флаг который будет показывать нашли мы элемент или нет.
let position = -1; // И позиция которую мы будем возвращать если нашли элемент, если нет, то возвращаем -1
// Далее у нас идет цикл while. Цикл будет работать до тех пор пока мы не нашли элемент.
while (found === false && start <= end) { // если found false и начало меньше и не поровнялось с концом, то ищем дальше
count++; // С каждой итерацией прибавляем +1 к кол операций.
middle = Math.floor((start + end) / 2); // Мы берем начало и конец, прибавляем и делим на 2. Так мы находим середину
if (array[middle] === item) { // Если элемент под индексом middle (наша середина) равен, тому что ищем.
found = true; // тогда флаг наш в true
position = middle; // Добавляем наш индекс под которым находится средний элемент в позицию
return position; // и возвращаем индекс нашего искомого элемента.
}
if (item < array[middle]) { // если искомый элемент меньше чем элемент под индексом middle(наша середина)
end = middle - 1; // то мы в переменную где находится конец массива присваиваем нашу середину и отнимаем 1.
}
else { // иначе мы присваиваем середину в переменную где находится начало и прибавляем 1
start = middle + 1;
}
}
return position; // Возвращаем из функции позицию
}
//Выводим в консоль индекс искомого элемента и кол операций требуемых для этого:
console.log(binarySearch(array, 4)); // 3
console.log(count); // 3
Смотрим подробно на примере поиска 4 в нашем массиве - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Наша переменная start = 0
, а end = 10
.
let start = 0;
let end = array.length; // 10
Далее запускается цикл while
. Так как found
у нас false
, а 0
меньше чем 10
мы запускаем цикл и ищем середину массива.
while (found === false && start <= end) {
middle = Math.floor((start + end) / 2) // наша середина 5. Так как 0 + 10 = 10 / 2 = 5
}
Мы нашли середину - это 5
. Эта пятерка это индекс,не элемент!
Далее мы проверяем, равен ли элемент под индексом 5
нашему искомому элементу - item
// под индексом 5 у нас 6
if (array[middle] === item) { // 6 не равно 4,
found = true;
position = middle;
return position;
}
В нашем случае у нас под индексом 5
находится 6
, а ищем мы 4
. В таком случаее мы идем дальше
if (item < array[middle]) { // в item у нас 4 в array[middle] у нас 6
end = middle - 1; // 4 меньше чем 6. Поэтому выполняем это условие.
// в переменную end мы кладем значение из middle это 5 и отнимаем 1, значит в end у нас 4.
// отняли еденицу мы потому что элемент под индексом 5 мы проверили выше в условии (array[middle] === item)
// мы знаем, что искомый элемент меньше чем элемент под индексом 5. Поэтому все остальное включительно 5 нам не нужно и мы это отрезаем.
} else {
start = middle + 1;
}
В переменной start
у нас все еще 0
, а в end
уже 4
let start = 0;
let end = 4;
Далее опять идет цикл:
while (found === false && start <= end) {
middle = Math.floor((start + end) / 2) // Теперь 0 + 4 = 4 / 2 = 2
}
Теперь наша середина middle = 2
.
Далее условие:
if (array[middle] === item) { // под индексом 2 в массиве у нас 3.
found = true; // 3 не равно 4 поэтому идем дальше
position = middle;
return position;
}
Следующее условие:
if (item < array[middle]) { // 4 больше чем 3
end = middle - 1;
} else { // поэтому вполняем это условие
start = middle + 1; // все также как и было, только теперь мы меняем начальную позицию массива.
// Выше мы проверили элемент под индексом 2 (array[middle] === item), он нам больше не нужен, поэтому прибавляем +1
}
Теперь в переменной start
у нас 3
, а в end
все еще 4
let start = 3;
let end = 4;
Далее цикл:
while (found === false && start <= end) {
middle = Math.floor((start + end) / 2) // Теперь 3 + 4 = 7 / 2 = 3
// 7 / 2 будет 3.5, но метод floor округляет до 3.
}
Далее опять условие:
if (array[middle] === item) { // под индексом 3 в массиве у нас 4. Искомый элемент тоже 4
found = true; // 4 равно 4 поэтому выполняем эти условия
position = middle; // в position кладем 3
return position; // возвращаем из функции 3
}
Все конец.
console.log(binarySearch(array, 4)); // 3