Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
40_алгоритмов_Python.pdf
Скачиваний:
9
Добавлен:
07.04.2024
Размер:
13.02 Mб
Скачать

86

Глава 3. Алгоритмы сортировки и поиска

Когда алгоритм сортировки выбором выполнится, результат будет следующим (рис. 3.13).

Рис. 3.13

На выходе мы получаем отсортированный список.

Анализ производительности сортировки выбором

Наихудшая производительность алгоритма сортировки выбором — O(N 2), ана­ логично сортировке пузырьком. Поэтому его не следует использовать для об­ работки больших наборов данных. Тем не менее сортировка выбором — это более продуманный алгоритм, чем сортировка пузырьком, и его средняя произ­ водительность лучше из-за сокращения числа обменов значений.

Выбор алгоритма сортировки

Выбор правильного алгоритма сортировки зависит как от размера, так и от со­ стояния имеющихся входных данных. Для небольших отсортированных списков использование продвинутого алгоритма приведет к ненужному усложнению кода при незначительном приросте производительности. Например, не следует использовать сортировку слиянием для небольших наборов данных. Сортиров­ ка пузырьком будет намного проще как для понимания‚ так для и реализации. Если данные частично отсортированы, мы можем воспользоваться этим преиму­ ществом и применить сортировку вставкой. Для больших наборов данных лучше всего использовать алгоритм сортировки слиянием.

АЛГОРИТМЫ ПОИСКА

Качественный алгоритм поиска — это один из самых важных инструментов для работы со сложными структурами данных. Самый простой и не слишком эф­ фективный подход заключается в поиске совпадений в каждой точке данных. Но по мере увеличения объема данных нам потребуются все более сложные алгоритмы поиска.

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

87

В этом разделе представлены следующие алгоритмы поиска:

zz линейный поиск (linear search); zz бинарный поиск (binary search);

zzинтерполяционный поиск (interpolation search).

Давайте рассмотрим каждый из них более подробно.

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

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

Давайте посмотрим на код для линейного поиска:

def LinearSearch(list, item): index = 0

found = False

# Сравниваем значение с каждым элементом данных while index < len(list) and found is False:

if list[index] == item: found = True

else:

index = index + 1 return found

Давайте теперь посмотрим на вывод нашего кода (рис. 3.14).

Рис. 3.14

88

Глава 3. Алгоритмы сортировки и поиска

Обратите внимание, что запуск функции linearSearch возвращает значение True, если данные найдены.

Производительность линейного поиска

Как было сказано выше, перед нами простой алгоритм, который выполняет ис­ черпывающий поиск. Его наихудшая сложность — O(N).

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

Необходимым условием для работы алгоритма бинарного поиска является упо­ рядоченность данных. Алгоритм итеративно делит список на две части и от­ слеживает самые низкие и самые высокие индексы, пока не найдет искомое значение:

def BinarySearch(list, item): first = 0

last = len(list)-1 found = False

while first<=last and not found: midpoint = (first + last)//2 if list[midpoint] == item:

found = True else:

if item < list[midpoint]: last = midpoint-1

else:

first = midpoint+1

return found

Вывод выглядит следующим образом (рис. 3.15).

Рис. 3.15

Обратите внимание, что вызов функции BinarySearch вернет значение True, если значение найдено в списке ввода.

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

89

Производительность бинарного поиска

Бинарный (говорят также «двоичный») поиск назван так потому, что на каждой итерации алгоритм разделяет данные на две части. Если данные содержат N эле­ ментов, для итерации потребуется максимум O(logN) шагов. Это означает, что алгоритм имеет время выполнения O(logN).

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

Бинарный поиск основан на логике, согласно которой он сосредотачивается на средней части данных. Интерполяционный поиск более сложен. Он использует целевое значение для оценки положения элемента в отсортированном массиве. Давайте попробуем понять это на примере. Предположим, мы хотим найти слово в словаре английского языка, например river. Мы будем использовать эту информацию для интерполяции и начнем поиск слов, начинающихся с r. В обоб­ щенном виде интерполяционный поиск может быть реализован следующим образом:

def IntPolsearch(list,x ): idx0 = 0

idxn = (len(list) - 1) found = False

while idx0 <= idxn and x >= list[idx0] and x <= list[idxn]:

# Ищем срединную точку

mid = idx0 +int(((float(idxn - idx0)/( list[idxn] - list[idx0])) * ( x - list[idx0])))

# Сравниваем значение в средней точке со значением поиска if list[mid] == x:

found = True return found

if list[mid] < x: idx0 = mid + 1

return found

Вывод выглядит следующим образом (рис. 3.16).

Рис. 3.16