MergeSort возвращает заголовок отсортированного списка, поэтому вызов в основном коде должен быть:
a.head = a.MergeSort(a.head)
Для отсортированного стека может показаться, что результат выполнения последовательного list.pop () должен возвращать узлы в порядке данных, но код использует «>» вместо «<=» в сравнении, в обратном порядке. </p>
Python 2.7 жаловался на использование имени для печати функция печати класса, а также жаловалась на 5 (вместо 4) пробелов перед "def SortedMerge (self, a, b):"
SortedMerge () выполняет один уровень рекурсии для каждого узла слиты. Для большого списка программа получит переполнение стека. Поскольку класс списка включает счетчик, код может использовать list.count // 2 для определения количества узлов, которые необходимо продвинуться, чтобы достичь средней точки, а затем использовать (count // 2) для размера левой половины и (count- (count // 2)) для размера правой половины. Сортировка снизу вверх еще быстрее. Однако с python накладные расходы на интерпретацию кода настолько велики, что я не знаю, будет ли это иметь значение. Вот ссылка на сортировку слиянием сверху вниз и снизу вверх для связанного списка, в java, использующего общую функцию слияния:
Сортировка слиянием для односвязного списка, кажется, удаляет любые числа больше, чем последнее число, которое я ввел в список
Я преобразовал код в python. Функция слияния одинакова для обоих примеров. Обратите внимание, что сортировка logi c одинакова, только функции pu sh и pop приводят к тому, что связанный список действует как стек. Функция слияния:
def Merge(self, a, b):
if a is None:
return b
if b is None:
return a
r = StackNode(0) # dummy node
d = r
while(True):
if(a.data <= b.data):
d.prev = a
d = a
a = a.prev
if(a == None):
d.prev = b
break
else:
d.prev = b
d = b
b = b.prev
if(b == None):
d.prev = a
break
return r.prev
Пример сверху вниз:
def MergeSort(self):
if(self.count < 2):
return
self.head = self.MergeSortR(self.head, self.count)
def MergeSortR(self, h, n):
if(n < 2):
return h
n2 = n//2
t = self.Scan(h, n2-1)
m = t.prev
t.prev = None
h = self.MergeSortR(h, n2)
m = self.MergeSortR(m, n-n2)
h = self.Merge(h, m)
return h
def Scan(self, h, n):
while(n > 0):
h = h.prev
n = n-1
return h
Пример снизу:
def MergeSort(self):
if(self.count < 2):
return
an = [None] * 32
node = self.head
while(node != None):
prev = node.prev
node.prev = None
i = 0
while((i < 32) and (an[i] != None)):
node = self.Merge(an[i], node)
an[i] = None
i = i+1
if(i == 32):
i = i-1
an[i] = node
node = prev
for i in xrange (0, 32):
node = self.Merge(an[i], node)
self.head = node
Тестовый код для узлов 512K. В моей системе, сверху вниз занимает около 4,5 секунд, снизу вверх около 3,9 секунд. Чтобы понять издержки Python, снизу вверх C требуется около 0,06 секунды.
import random
from time import time
p = [random.randint(0, 2147483647) for r in xrange(512*1024)]
a = Stack()
for i in xrange (0, len(p)):
a.push(p[i])
s = time()
a.MergeSort()
e = time()
print e - s
for i in xrange (0, len(p)):
p[i] = a.pop().data
for i in xrange (1, len(p)):
if(p[i-1] > p[i]):
print("error")
break