Heapsort: объяснение процедуры построения максимальной кучи

Я пытаюсь понять код для сортировки массива с помощью Heap Sort (ссылка - https://www.sanfoundry.com/java-program-implement-heap-sort/)

Функция "maxheap" использует этот расчет для получения левого и правого потомков узла (то же самое используется в нескольких различных примерах / сайтах)

int left = 2 * i;
int right = 2 * i + 1;

Какова логика / обоснование вышесказанного?

Кроме того, в функции heapify, maxheap fn вызывается с i = N / 2 -> 0
(вместо i = 0 до N -1, например.) Есть идеи, почему это делается?

public static void heapify(int arr[])
{
     N = arr.length-1;
     for (int i = N/2; i >= 0; i--)
         maxheap(arr, i);        
}

1 ответ

Решение

Какова логика / обоснование вышесказанного?

Куча - это двоичное дерево и в массиве индексов на основе 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_heapify является то, что левое и правое поддеревья узла i это максимальные кучи, но узел i может нарушать свойство max heap (оно может быть меньше, чем его дочерние элементы).
Это означает, что если мы позвоним 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]
Другие вопросы по тегам