Какова логика / обоснование вышеизложенного?
Куча - это двоичное дерево и в массиве индексов на основе 1, как показано ниже, чтобы получить левого потомкаДля узла i
вам нужен индекс 2*i
, а для правильного ребенка вы получите индекс 2*i + 1
.
Array:
[1, 2, 3, 4, 5, 6, 7]
Binary tree:
1
/ \
2 3
/ \ / \
4 5 6 7
Кроме того, в функции heapify вызывается maxheap fn с i = N / 2 -> 0 (например, вместо i = 0 - N -1). Любые идеи попочему это делается?
maxheap
или max_heapify
- это процедура, которая получает массив и индекс i
в качестве входных данных для поддержания свойства max heap.Для max_heapify
предполагается, что левые и правые поддеревья узла i
являются максимальными кучами, но узел i
может нарушать свойство максимальной кучи (оно может быть меньше, чем его дочерние элементы).
Это означает, что еслимы вызываем max_heapify
для всех элементов массива, все узлы будут поддерживать свойство max heap, и мы должны получить максимальную кучу.Однако если мы начнем с начала массива (корень дерева), мы не сможем предположить, что левое и правое поддеревья уже являются максимальными кучами, поэтому нам нужно начать с конца (листья дерева) и перейти к началу.Кроме того, у листьев нет дочерних элементов, поэтому они обычно уже имеют максимальные кучи, и нам не нужно вызывать max_heapify
для них.В куче из n элементов узлы в подмассиве [floor(n/2)+1..n]
являются листьями, поэтому мы можем выполнить цикл от floor(n/2)
до 1
и вызывать max_heapify
только для внутренних узлов.
Для 0-основанныхмассив:
left(i): 2 * i + 1
right(i): 2 * i + 2
leaves: [floor(n/2)..n-1]
internal nodes: [0..floor(n/2)-1]