C++. Линейный и двоичный поиск элементов в массиве


Линейный поиск в массиве
Очень часто требуется найти в массиве заданное значение или сообщить, что его там нет. Для этого нужно просмотреть все элементы массива с первого до последнего. Как только будет найден элемент, равный заданному значению X, надо завершить поиск и вывести результат. Такой алгоритм называется линейным.

Линейный алгоритм используют для поиска максимального (минимального) элемента массива. Это тоже алгоритм поиска. Но здесь мы вынуждены идти до конца массива, т.к. необходимо сравнивать все элементы, с текущим значением максимума (минимума) и в случае если текущий элемент больше (меньше) значения максимума (минимума) заменять значение максимума (минимума). 
 

Возможен еще один подход к решению этой задачи. Можно использовать досрочный выход из цикла, если найдено требуемое значение. 
В С++ для досрочного выхода из цикла используется оператор break;

Двоичный поиск
Двоичный (или бинарный) поиск является эффективным алгоритмом поиска, выполняется он быстрее чем линейный поиск. Например, для массива из 1024 элементов линейный поиск в худшем случае (когда искомого элемента нет в массиве) обработает все 1024 элемента, но бинарным поиском достаточно обработать 10 элементов. Такой результат достигается за счет того, что после первого шага цикла область поиска сужается до 512 элементов, после второго – до 256 и т.д.
 
Недостатками такого алгоритма является требование упорядоченности данных, а также возможности доступа к любому элементу данных за постоянное (не зависящее от количества данных) время. Таким образом алгоритм не может работать на неупорядоченных массивах.
 
Алгоритм
  1. Выбрать средний элемент A[c] и сравнить с X.
  2. Если X = A[c], то нашли (стоп).
  3. Если X < A[c], искать дальше в первой половине.
  4. Если X > A[c], искать дальше во второй половине.
     
Реализация
L = 0; R = N; // начальный отрезок
while ( L < R - 1)
{
	c = (L + R) / 2; // нашли середину
	if ( X < A[c] )  // сжатие отрезка
	    R = c;
	else 
	    L = c;
}
if ( A[L] == X)
    cout << "A[" << L << "]=" << X;
else
    cout << "Not found";


где:
А - исходный массив,
N - размер массива,
X - искомое число,

Возможны и другие реализации.
Например, с использованием досрочного выхода из цикла
L = 0; R = N - 1; 
while ( R >= L)
{
	c = (L + R) / 2; 
	if ( X == A[c] )
	{  
	    nX = c;
	    break;
	}
	if (X < A[c]) R = mid - 1;
	if (X > A[c]) L = mid + 1;
}
if ( nX < 0)
    cout << "Not found";
else
    cout << "A[" << nX << "]=" << X;

Сравнение алгоритмов линейного и двоичного поиска по числу сравнений
 
Примеры
Линейный поиск Двоичный поиск
2 2 2
16 16 5
1024 1024 11
1048576 1048576 21

Плюсы двоичной сортировки в том, что выполняется она быстрее.
Минусы - необходим предварительно отсортированный массив.