Я реализовал свой собственный модуль кучи, чтобы помочь мне понять структуру данных кучи. Я понимаю, как они работают и ими управляют, но моя реализация значительно медленнее, чем стандартный модуль python heapq при предварительной сортировке кучи (для списка размером 100000 heapq занимает 0,6 секунды, а мой код занимает 2 секунды (изначально был 2,6 секунды, сократите его до 2 с, беря операторы len () из percDown и передавая длину, чтобы не приходилось вычислять len каждый раз, когда метод вызывает сам себя). Вот моя реализация:
def percDown(lst, start, end, node):
#Moves given node down the heap, starting at index start, until the heap property is
#satisfied (all children must be larger than their parent)
iChild = 2 * start + 1
i = start
# if the node has reached the end of the heap (i.e. no children left),
# return its index (we are done)
if iChild > end - 1:
return start
#if the second child exists and is smaller than the first child, use that child index
#for comparing later
if iChild + 1 < end and lst[iChild + 1] < lst[iChild]:
iChild += 1
#if the smallest child is less than the node, it is the new parent
if lst[iChild] < node:
#move the child to the parent position
lst[start] = lst[iChild]
#continue recursively going through the child nodes of the
# new parent node to find where node is meant to go
i = percDown(lst, iChild, end, node)
return i
popMin: извлекает минимальное значение (lst [0]) и меняет порядок кучи
def popMin(lst):
length = len(lst)
if (length > 1):
min = lst[0]
ele = lst.pop()
i = percDown(lst, 0, length - 1, ele)
lst[i] = ele
return min
else:
return lst.pop()
heapify: превращает список в кучу на месте
def heapify(lst):
iLastParent = math.floor((len(lst) - 1) / 2)
length = len(lst)
while iLastParent >= 0:
ele = lst[iLastParent]
i = percDown(lst, iLastParent, length, lst[iLastParent])
lst[i] = ele
iLastParent -= 1
sort: сортирует данный список в кучу, используя методы выше (не на месте)
def sort(lst):
result = []
heap.heapify(lst)
length = len(lst)
for z in range(0, length):
result.append(heap.popMin(lst))
return result
Я по ошибке добавил сложность к созданию алгоритма / кучи, или это просто модуль python heapq, который сильно оптимизирован? У меня такое чувство, что это первое, так как 0,6 с против 2 - огромная разница.