Во-первых, чтобы «проверить соответствие букв» между двумя строками, все, что вам действительно нужно, это <
.Строки сравниваются лексикографически: 'abc' < 'abd' < 'acd' < 'acdd'
.
При наличии связанного списка вам нужно искать узлы из головы, чтобы найти местоположение.Следите за предыдущим и следующим узлом по мере продвижения, и как только вы найдете next.head > value
, вставьте новый узел после prev
.(Если вы используете реализацию с голым узлом, убедитесь, что ваша функция возвращает заголовок, иначе нет возможности вставить перед заголовком.)
Конечно, это автоматически означает линейное время, чтобы найти правильную позицию(и, если вы используете неизменяемые узлы, то и линейное время для построения новых узлов обратно до головы).
Учитывая вашу реализацию, это может выглядеть как эти методы на SingleLinkedList
:
def find_pos(self, element):
'''Returns the position before element, or None if no such position'''
prev, node = None, self._head
while node:
if node.element > element:
return prev
prev, node = node, node.next
return prev
def insert(self, element):
pos = self.find_pos(element)
if pos:
# add it after the node we found
node = Node(element, pos.next)
pos.next = node
else:
# add it before the current head
node = Node(element, self._head)
self._head = node
self._size += 1
С такой структурой данных с произвольным доступом, как массив (Python list
), вы можете bisect
, чтобы найти правильное местоположение во время регистрации.Но с массивом вам все еще нужно линейное время, чтобы выполнить вставку, потому что все последующие значения должны быть сдвинуты вверх.(Хотя это обычно линейно с гораздо более быстрой константой, чем поиск по связанному списку.)
bisect.insort(lst, value)
И последнее: если вы выполняете тонну вставок в строке, часто более эффективноПакуй их.На самом деле, простой вызов extend
, а затем sort
может быть на самом деле быстрее, чем insort
каждый, если число добавляемых элементов составляет значительную часть списка.
ЕслиВы хотите получить лучшее из обоих миров, вам нужна более сложная структура данных:
- Сбалансированное бинарное дерево поиска некоторого вида (красно-черный, AVL и т. д.) является традиционным ответом,хотя на практике это имеет тенденцию быть довольно медленным.
- Более широкое дерево поиска, как и любой из вариантов B-дерева, позволяет избежать большей части затрат на производительность двоичных деревьев (и позволяет выполнять поиск с более высокой базой журналов,для загрузки).
- Пропускаемый список - это связанный список с журналом N «высокоуровневых» связанных списков, пронизанных через него (или расположенных над ним), так что вы можете разделить его пополам.Есть и другие варианты этой концепции «индексированного списка».
- Существует несколько реализаций сложных гибридов в Python, например, структура deque / веревка с необязательным вариантом B-дерева, сложенным сверху.
Популярные реализации включают blist.sortedlist
, sortedcontainers.SortedList
, pybst.AVLTree
и т. Д.
Но на самом деле, почтилюбая реализация любой такой структуры, которую вы найдете в Python, будет иметь встроенное поведение. Поэтому правильный ответ, вероятно, будет выглядеть примерно так:
lst.add(val)