4874

Поиск в массивах. Последовательный, бинарный и интерполяционный поиск

Лекция

Информатика, кибернетика и программирование

Поиск в массивах. Последовательный, бинарный и интерполяционный поиск. Под поиском в массиве будем понимать задачу нахождения индекса, по которому в массиве располагается некоторый заданный элемент. Тривиальный алгоритм поиска заключается в последов...

Русский

2012-11-28

48.5 KB

109 чел.

Поиск в массивах. Последовательный, бинарный и интерполяционный поиск.

Под поиском в массиве будем понимать задачу нахождения индекса, по которому в массиве располагается некоторый заданный элемент. Тривиальный алгоритм поиска заключается в последовательном переборе элементов массива до тех пор, пока не будет обнаружен искомый или не будут просмотрены все элементы массива. В случае, когда нет никакой дополнительной информации о характере расположения элементов в массиве, такой алгоритм представляется единственно возможным. Нетрудно подсчитать, что, в худшем случае, для поиска в массиве, состоящем из N элементов, потребуется N операций сравнения. Пример реализации такого алгоритма приведен ниже:

// Последовательный поиск

// A - указатель на массив

// N - размер массива

// d - искомый элемент

int serialSearch( double * A, int N, double d )

{

 // Индекс по умолчанию, при неудачном поиске

 int index = -1;

 

 for ( int i = 0; i < N; ++i )

 {

 // Нашли искомый элемент

 if ( A[i] == d )

 {

  index = i;

  break;

 }

}

 return index;

}

Если известно, что данные в массиве расположены упорядоченно (будем считать, что элементы отсортированы по возрастанию), то можно предложить намного более эффективный способ поиска элементов. Суть метода заключается в том, что после каждой операции сравнения элемента массива с искомым, диапазон поиска сужается по следующим правилам:

  •  если элемент массива оказался больше искомого, будем искать элемент в «левой» половине текущего диапазона;
  •  если элемент массива оказался меньше искомого, будем искать элемент в «правой» половине текущего диапазона;
  •  если элемент массива совпадает с искомым – поиск успешно завершается;
  •  если диапазон поиска на текущем шаге уменьшился до 1 – искомый элемент в массиве отсутствует, поиск завершается.

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

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

// A - указатель на массив

// N - размер массива

// d - искомый элемент

int binarySearch( double * A, int N, double d )

{

 // Индекс по умолчанию, при неудачном поиске

 int index = -1;

 

 // Индексы нижней и верхней границы диапазона поиска

 int lowerIndex = 0;

 int upperIndex = N-1;

 

 do

{

 // Середина текущего диапазона поиска

 int midIndex = ( upperIndex + lowerIndex ) / 2;

 // Определяем новый диапазон поиска

 if ( A[ midIndex ] > d )

  upperIndex = midIndex;

 else if ( A[ midIndex ] < d )

  lowerIndex = midIndex;

 else // искомый элемент - в середине текущего диапазона

 {

  index = midIndex;

  break;

 }

}

 while( upperIndex - lowerIndex > 1 );

 return index;

}

Алгоритм бинарного поиска обладает недостатком, связанным с тем, что при вычислении очередного «суженного» диапазона поиска никак не учитывается величина искомого элемента и величины элементов, находящихся на границах интервала. Если предположить, что данные в массиве не только упорядочены, но и распределены достаточно «равномерно», то можно значительно ускорить «сходимость» процесса поиска, осуществляя дробление интервала поиска из следующих неформальных соображений: если предположить, что элементы массива принимают значения от 1 до 1000 и нам необходимо найти число 10, то при первом шаге дробления всего диапазона поиска гораздо эффективнее делить его не пополам (учитывая предположение о «равномерности» распределения данных в массиве, новые интервалы будут содержать значения приблизительно 1-500 и 501-1000), а взять «левый» интервал более узким, т.к. предположительно, число 10 окажется гораздо ближе к левой границе исходного диапазона. Более строго, формулу для вычисления индекса, соответствующего разбиению интервала, можно вывести из следующих простых соображений:

Реализация интерполяционного алгоритма поиска приведена ниже.

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

// A - указатель на массив

// N - размер массива

// d - искомый элемент

int interpSearch( double * A, int N, double d )

{

 // Индекс по умолчанию, при неудачном поиске

 int index = -1;

 

 // Индексы нижней и верхней границы диапазона поиска

 int lowerIndex = 0;

 int upperIndex = N-1;

 

 do

{

 // Индекс разбиения текущего интервала

 int divIndex = lowerIndex;

 

 // Проверка на "вырожденный" случай

 if ( A[upperIndex] != A[lowerIndex] )

  divIndex = lowerIndex + ( upperIndex - lowerIndex ) * ( d - A[lowerIndex] ) / ( A[upperIndex] - A[lowerIndex] );

 else if ( A[lowerIndex ] != d )

  break;

 // Определяем новый диапазон поиска

 if ( A[ divIndex ] > d )

  upperIndex = divIndex;

 else if ( A[ divIndex ] < d )

  lowerIndex = divIndex;

 else // искомый элемент оказался в точке разбиения

 {

  index = divIndex;

  break;

 }

}

 while( upperIndex - lowerIndex > 1 );

 

 return index;

}


iL

R

iX

AL

AR

X

индексы

значения


 

А также другие работы, которые могут Вас заинтересовать

40499. Пословицы и поговорки 21.5 KB
  Общественная ценность пословиц: философский жанр многосторонняя и глубоко осмысленная картина жизни: Вчера не догонишь от завтра не уйдешь. эстетическая ценность простота краткость содержательность выразительность.
40500. Похоронная обрядовая поэзия 20.5 KB
  Отношение живых к умершим: существо злое смысл обряда защититься существо доброе смысл обряда обеспечить канал связи.
40501. Пушкин и фольклор 21 KB
  Пушкин и фольклор. Концепция Пушкина вершина декабристской концепции. Пушкин художник. Пушкин первым ощущает себя профессиональным литератором.
40502. Свадебная обрядовая поэзия 25.5 KB
  Песни пелись во время всего процесса: песни величальные песни корильные причитания невесты Во всех песнях участвуют князь и княгиня а также образы: воли символические образы горя полуразрушенный дом и радости блестит звенит Функции песен: величальные возвеличивание жениха и невесты. Песни имели магическое значение песниобереги. Причитание принципиально строится иначе чем остальные свадебные песни: причитание песня одного человека в то время как остальные песни коллективные.
40503. Своеобразие фантастики в русской народной сказке 21 KB
  Раз исторические представления о том что возможно и невозможно меняется то меняется и представление о фантастике: с течением времени сфера фантастики расширяется а не уменьшается то что раньше не было фантастическим с течением времени может приобрести свойство сказки но назад хода нет.
40504. Сказка «Медведь на липовой ноге» и вопрос о происхождении сказок о животных 27.5 KB
  Сказка Медведь на липовой ноге и вопрос о происхождении сказок о животных. Источники: зооморфные мифы новая социальная действительность Медведь на липовой ноге Загадочность сюжета печальный финал атмосфера страха и ужаса нетипично для русского фольклора. Медведь священное животное может прогонять нечистую силу самые священные части медведя голова и лапы. Первый тип вариантов Медведь на липовой ноге.
40505. Сказка: Общая характеристика. История собирания и изучения 25 KB
  Общая характеристика сказки. Установка на вымысел показывает как носители фольклора относились к сказке: внешняя сторона Носители фольклора не верили в реальность сказки. Сказки на Руси известны с давних времен. В XVIII веке кроме рукописных сборников сказок стали появляться и печатные издания в которых обычно народные сказки подвергались переделке.
40506. Сказки о животных. Своеобразие образа главного героя 36.5 KB
  Басня Волк и ягнёнок Сказка Волк и лиса И там и там изображаются животные а подразумеваются люди. Под маской волка изображаются отдельные черты характера лицемерие и к ним не к человеку у нас однозначное отношение трусость как таковая плохо но трусливого человека можно любить за другие качества а трусость при этом деформируется. Здесь многозначное отношение к волку так как у него много черт характера. если мы говорим о лисе хитрой а волке жадном то мы превращаем сказку в басню а это ни в коем случае делать нельзя...
40507. Социально-бытовые, сатирические сказки 27.5 KB
  Два типа социальнобытовых сказок: в центре герой умный хитрый ловкий мужик. Мужик и барин Мужик и поп Мужик и богач семейный характер конфликты внутри семьи. Мужик и жена. Их герои мужик солдат работник и т.