Предисловие научно-популярное
Первая статья о бинарном поиске была опубликована в 1946 году, но первый безошибочный метод бинарного поиска появился в 1962 году, с интервалом в 16 лет.
Сможете ли вы в 2019 году написать метод бинарного поиска без ошибок в процессе собеседования?
определение
В информатике,бинарный поиск(английский: бинарный поиск), также известный какПоловинный поиск(английский: полуинтервальный поиск),логарифмический поиск(английский: логарифмический поиск), представляет собойотсортированный массивнайти определенный элемент валгоритм поиска.
Процесс поиска начинается со среднего элемента массива, и если средний элемент является именно тем элементом, который нужно найти, процесс поиска заканчивается;
Если конкретный элемент больше или меньше среднего элемента, просмотрите половину массива, которая больше или меньше среднего элемента, и сравните со средним элементом, как и раньше.
Если на каком-то шаге массив пуст, значит, он не найден.
Этот алгоритм поиска уменьшает диапазон поиска наполовину для каждого сравнения.
бинарный поисковый код
В соответствии с вышеприведенным определением попробуем написать код метода бинарного поиска.
public static int binary(int[] arr, int data) {
int min = 0;
int max = arr.length - 1;
int mid;
while (min <= max) {
mid = (min + max) / 2;
if (arr[mid] > data) {
max = mid - 1;
} else if (arr[mid] < data) {
min = mid + 1;
} else {
return mid;
}
}
return -1;
}
Теперь я спрашиваю вас, есть ли проблема с приведенным выше кодом? Какой код глючит?
Пожалуйста, подумайте об этом через минуту.
Для приведенного выше кода проблема находится в строке 6:
mid = (min + max) / 2;
Этот код будет переполняться, когда min и max будут большими, что приведет к ошибке доступа к массиву.
Не смотрите на преуменьшение указания на эту ошибку сейчас, но в то время эта ошибка существовала много лет.
Как это улучшить? Общий подход таков:Превратите сложение в вычитание.
public static int binary(int[] arr, int data) {
int min = 0;
int max = arr.length - 1;
int mid;
while (min <= max) {
// 防止溢出
mid = min + (max - min) / 2;
if (arr[mid] > data) {
max = mid - 1;
} else if (arr[mid] < data) {
min = mid + 1;
} else {
return mid;
}
}
return -1;
}
Существует также более убедительный способ написания, который также является реализацией официального метода бинарного поиска: используйтебитовая операция.
public static int binary(int[] arr, int data) {
int min = 0;
int max = arr.length - 1;
int mid;
while (min <= max) {
// 无符号位运算符的优先级较低,先括起来
mid = min + ((max - min) >>> 1);
if (arr[mid] > data) {
max = mid - 1;
} else if (arr[mid] < data) {
min = mid + 1;
} else {
return mid;
}
}
return -1;
}
Я надеюсь, что благодаря сегодняшней статье читатели смогут правильно написать код на собеседовании, ведь у многих небольших компаний метод бинарного поиска появится в их письменных тестовых вопросах.