Как вызвать функцию heapify_up на Python?

#python #algorithm #heap

#python #алгоритм #куча

Вопрос:

Я пытаюсь вызвать заданную функцию «heapify_up», которая передает значение вверх по куче. она сравнивает значение, первоначально указанное в индексе i кучи, с его родительскими значениями, и, если свойство кучи нарушено, меняет их местами.

Я продолжал получать ошибку :

 File "try.py", line 30, in heapify_up
    while (getattr(self.heap[parent], self.sorting_key) <
IndexError: list index out of range
  

ниже приведен мой код

 class Heap:
    def __init__(self, sorting_key):
        """Initializes a new instance of a heap.

        Args:
            sorting_key: Specifies the attribute of the object inserted
            into the heap, on the basis of which the heap was created.
        """
        self.heap = list()
        self.mapping = dict()
        self.sorting_key = sorting_key

    def heapify_up(self, child):
        """Standard heapify operation, as described in CLRS.
        Works by swapping the element originially at index child in the heap
        with its parent until the heap property is satisfied. Modifies the
        appropriate heap attribute

        Args:
            child: Index of the element that violates the heap property

        Returns:
            None
        """
        parent = (child - 1) / 2
        # Swaps the element originally at the index child with its parent
        # until the value of the specifed attribute of the parent is greater
        # than the value of the specified attribute of the element itself
        while (getattr(self.heap[parent], self.sorting_key) <
               getattr(self.heap[child], self.sorting_key)):
            if (parent == -1):
                # This means child was 0, which means we have reached the
                # top of the heap
                return

            # Swap the mappings as well to ensure that future references in
            # the mapping dict refer to the correct position of the object in
            # the heap
            self.mapping[self.heap[parent].player] = child
            self.mapping[self.heap[child].player] = parent

            # Swap the parent and the child
            temp = self.heap[parent]
            self.heap[parent] = self.heap[child]
            self.heap[child] = temp

            # Move the child and parent pointers up the heap
            child = parent
            parent = (child - 1) / 2

x=Heap([16,4,10,14,7,9,3,2,8,1])  # sample list
x.heapify_up(4)  # index of child that violates the heap property
print x.sorting_key
  

Ответ №1:

Вы оставляете self.heap пустой список. Любой индекс выдаст IndexError исключение:

 class Heap:
    def __init__(self, sorting_key):
        # ...
        self.heap = list()
  

Вместо этого ваш список присваивается sorting_key , что не соответствует документированному использованию для sorting_key :

 sorting_key: Specifies the attribute of the object inserted
into the heap, on the basis of which the heap was created.
  

Ваш код предполагает наличие списка объектов с атрибутами, названными в sorting_key атрибуте. Но затем ваш код передает список целых чисел и не содержит ключа сортировки. heapify_up Функция также ожидает, что элементы кучи будут иметь .player атрибут, которого также нет у целых чисел. Этот код никогда не сможет работать с введенными вами данными!

Вам нужно будет определить, какое состояние вам Heap необходимо отслеживать, и исправить это, прежде чем зацикливаться на heap_up методе.

Обратите внимание, что стандартная библиотека Python уже поставляется с heapq модулем; документация ссылается на исходный код, который является универсальным и не привязан к определенному типу элемента кучи, как представляется, этот код.

Комментарии:

1. Извините, я не понимаю. Я не использовал self. куча, когда я вызвал функцию. Я присвоил список x.sorting_key. Как это влияет на вызов x.hepify_up?

2. @user3810193: Ваш self.heap атрибут представляет собой пустой список, но вы пытаетесь проиндексировать его с помощью self.heap[child] и self.heap[parent] . В пустом списке нет элементов, поэтому вы не можете проиндексировать его. Обычно вы инициализируете свою кучу из существующего списка. Ваш sorting_key атрибут используется в качестве атрибута элементов кучи в getattr() вызовах, атрибуты никогда не могут быть списками, так что здесь действительно что-то не так. Вы вообще понимаете, что self.heap и self.sorting_key предназначены для выполнения в этом коде?

3. Спасибо Martijin. Я не совсем понимаю, как инициализировать кучу с помощью существующего списка (присвоить его self.heap). Можете ли вы привести пример? Я попробовал x=Heap(), x.heap([список]), что тоже показалось неправильным.

4. @user3810193: x = Heap(attribute_name) тогда x.heap = [element1, element2, ...] . Но ваша куча должна содержать объекты с атрибутом, который дает значение сортировки.

5. Извините, не могли бы вы объяснить, что это значит «содержать объекты с атрибутом, который дает значение сортировки»? В принципе, я хочу знать, используя класс, как создать список (например, [16,4,10,14,7,9,3,2,8,1]) и увеличить его, заменив index[2] на index[5].