Это десятая часть из 14 серий нетрадиционного введения в Python, написанного с целью научиться эффективно использовать вычислительные методы. Ссылки на все части смотрите в первой статье.

Некоторые простые алгоритмы и структуры данных

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

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

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

Алгоритм поиска – это метод поиска элемента или группы элементов с определенными свойствами в наборе элементов. Мы называем набор элементов областью поиска.

Линейный поиск и использование косвенного доступа к элементам
Python использует следующий алгоритм, чтобы определить, находится ли элемент в списке:

def search(L, e):
 for i in range(len(L)):
   if L[i] == e:
     return True
 return False

Если элемента e нет в списке, алгоритм выполнит O(len(L)) тестов, т. е. сложность в лучшем случае линейна по длине L.

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

Идея проста:

  1. Выберите индекс i, который делит список L примерно пополам.
  2. Спросите, если L[i] == e.
  3. Если нет, спросите, больше или меньше L[i] e.
  4. В зависимости от ответа найдите e в левой или правой половине буквы L.

сложность поиска O(log(len(L))).

Алгоритмы сортировки

Начнем с простого, но неэффективного алгоритма сортировка выбором.

Сортировка выбором работает, поддерживая инвариант цикла, который при разделении списка на префикс (L[0:i]) и суффикс (L[i+1:len(L)]) , префикс отсортирован, и ни один элемент в префиксе не превышает наименьший элемент в суффиксе.
Сложность всей функции составляет O(len(L)2 ). т. е. квадратичен по длине L.

Сортировка слиянием

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

  1. Пороговый размер входных данных, ниже которого задача не разбивается,
  2. Размер и количество подэкземпляров, на которые разбивается экземпляр, и
  3. Алгоритм, используемый для объединения подрешений.

Порог иногда называют рекурсивной базой.

Сортировка слиянием — это прототип алгоритма "разделяй и властвуй". Он был изобретен в 1945 году Джоном фон Нейманом и до сих пор широко используется. Как и многие алгоритмы «разделяй и властвуй», его проще всего описать рекурсивно.

  1. Если список имеет длину 0 или 1, он уже отсортирован.
  2. Если в списке более одного элемента, разделите список на два списка и используйте
  3. сортировка слиянием для сортировки каждого из них.
  4. Объедините результаты.

def merge(left,right,compare):
 '''Assume left and right are sorted lists and compare
 defines an ordering on the elements.
 Return a new sorted (by compare) list containing the 
 same elements as (left + right) would contain.'''
 
 result = []
 i,j = 0,0
 while i<len(left) and j<len(right):
  if compare(left[i], right[j]):
   result.append(left[i])
   i+=1
  else:
   result.append(right[j])
   j+=1
 while(i<len(left)):
  result.append(left[i])
  i+=1
 while(j<len(right)):
  result.append(right[j])
  j+=1
 return result
import operator
def mergeSort(L,compare = operator.lt):
 '''Assumes L is a list, compare defines an ordering on elements of L
 Returns a new sorted list containing the same elements as L'''
 if len(L) < 2:
  return L[:]
 else:
  middle = len(L)//2
  left = mergeSort(L[:middle],compare)
  right = mergeSort(L[middle:],compare)
  return merge(left, right,compare)

Сортировка в Python.
Алгоритм сортировки, используемый в большинстве реализаций Python, называется timsort. Основная идея состоит в том, чтобы воспользоваться тем фактом, что во многих наборах данных данные уже частично отсортированы. Производительность Timsort в худшем случае такая же, как и у сортировки слиянием, но в среднем она работает значительно лучше.

Хеш-таблицы

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

Хэш-функция сопоставляет большое пространство входных данных (например, все натуральные числа) с меньшим пространством выходных данных (например, натуральные числа от 0 до 5000). Хэш-функции можно использовать для преобразования большого пространства ключей в меньшее пространство целочисленных индексов.

Поскольку пространство возможных выходных данных меньше пространства возможных входных данных, хеш-функция представляет собой отображение «многие к одному», т. е. несколько различных входных данных могут быть сопоставлены с одним и тем же выходным сигналом. Когда два входа сопоставляются с одним и тем же выходом, это называется коллизией — тема, к которой мы вскоре вернемся. Хорошая хеш-функция обеспечивает равномерное распределение, т. е. все выходные данные в диапазоне равновероятны, что сводит к минимуму вероятность коллизий.

Все кредиты принадлежат профессору Джону Гуттагу, и все ссылки связаны с его вкладом в эту область.

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