Прежде всего, ваш текущий код будет генерировать не список 1 → 3 → 4 → 2 → 1 → 2, а его инверсию. Это потому, что ваше определение метода add
добавит заданное значение к списку.
Чтобы заставить add
работать правильно, он должен сначала найти последний узел в списке и добавьте новый узел после него. Поскольку это не очень эффективный метод добавления множества значений в список, я бы предложил также определить add
как метод Node и разрешить цепочку вызовов add
. Таким образом, вы можете добавить много значений в одно цепочечное выражение, не будучи неэффективным.
Кроме того, поскольку вам нужно будет сравнить значения пар , имеет смысл создать метод для Node
который вернет значение пары, образованной этим узлом и следующим в списке.
Наконец, для самого алгоритма sort
вы можете сократить список только до его первой пары (что тогда очевидно отсортировано), а остальное обрабатывается как отдельный список несортированных узлов. Затем извлеките пару за раз из несортированного списка и найдите подходящее место для добавления ее в основной список, чтобы она оставалась отсортированной.
Этот процесс представляет O (n²) сложность времени в среднем и в худшем случае. Наилучшим случаем является O (n) , который возникает, когда список изначально отсортирован в обратном порядке.
Вот как это может выглядеть:
class Node():
def __init__(self, val):
self.data = val
self.next = None
# Easy chaining: defining this method on a Node as well
def add(self, val):
node = Node(val)
node.next = self.next
self.next = node
return node
# Define how the value of a pair is calculated
def pairvalue(self):
return self.data * 10 + self.next.data
class Linkedlist():
def __init__(self):
self.head = None
def add(self, val):
# Corrected method: addition should be at the end of the list
node = Node(val)
if not self.head:
self.head = node
else: # Look for the last node in the list
curr = self.head
while curr.next:
curr = curr.next
# ...and append the new node after it
curr.next = node
return node # Allow for chaining
def display(self):
p = self.head
while p:
print(p.data, end= "→")
p = p.next
print("NIL")
def sort(self):
if not self.head:
return
# Reduce list to just its first pair
# The remainder is a temporary "todo" list
todo = self.head.next.next
self.head.next.next = None
while todo:
pair = todo # The pair that will be added to the sorted list
todo = todo.next.next
val = pair.pairvalue()
if val < self.head.pairvalue():
# The pair is a minimum: prepend it
pair.next.next = self.head
self.head = pair
else:
curr = self.head.next # odd index
# Find insertion point in sorted list
while curr.next and curr.next.pairvalue() < val:
curr = curr.next.next
# Perform insertion
pair.next.next = curr.next
curr.next = pair
m = Linkedlist()
m.add(1).add(3).add(4).add(2).add(1).add(2)
m.display() # original list
m.sort()
m.display() # final list
вывод:
1→3→4→2→1→2→NIL
1→2→1→3→4→2→NIL