Как написать код Max Heap без рекурсии

Я написал метод MAX-HEAPIFY(A,i) из книги «Введение в алгоритмы». Теперь я хочу написать это без рекурсии, используя цикл while. Не могли бы вы мне помочь?


person Parisa    schedule 10.10.2014    source источник


Ответы (2)


Вы можете использовать цикл while с условием i ‹= HEAPSIZE и использовать все остальные те же условия, за исключением случаев, когда вы найдете правильную позицию, просто прервите цикл. Код:-

while ( i < = heapsize) {
 le <- left(i)
 ri <- right(i)
 if (le<=heapsize) and (A[le]>A[i])
  largest <- le
 else
  largest <- i 
 if (ri<=heapsize) and (A[ri]>A[largest])
  largest <- ri
 if (largest != i)
 {
   exchange A[i] <-> A[largest]
   i <- largest
 } 
 else
  break
}             
person aurilio    schedule 10.10.2014
comment
почему вы использовали else и прервали последнюю строку? - person Parisa; 10.10.2014
comment
Чтобы проверить граничное условие - если элемент находится в правильном положении, он больше не должен выполнять heapify и выходить из цикла. - person aurilio; 13.10.2014
comment
Я думаю, если мы поместим i‹heapsize в качестве условия, в то время как мы можем опустить оператор break в коде - person smasher; 15.09.2017

Приведенное выше решение работает, но я думаю, что следующий код ближе к рекурсивной версии.

(* Code TP compatible *)
const maxDim = 1000; 
type TElem = integer;
     TArray = array[1..maxDim]of TElem

procedure heapify(var A:TArray;i,heapsize:integer);
var l,r,largest,save:integer;
    temp:TElem;
(*i - index of node that violates heap property
  l - index of left child of node with index i
  r - index of right child of node with index i
  largest - index of largest element of the triplet (i,l,r) 
  save - auxiliary variable to save the value of i 
  temp - auxiliary variable used for swapping *)   
begin
  repeat
    l:=2*i;
    r:=2*i + 1;
    if(l <= heapsize) and (A[l] > A[i]) then
       largest:=l
    else 
       largest:=i;
    if(r <= heapsize) and (A[r] > A[largest]) then
       largest:=r;
    (*Now we save the value i to check properly the termination
     condition of repeat until loop
     The value of i will be modified soon in the if statement *)
    save:=i;
    if largest <> i then
    begin
      temp:=A[i];
      A[i]:=A[largest];
      A[largest]:=temp;
      i:=largest;
    end;
    until largest = save;
    (*Why i used repeat until istead of while ?
     because body of the called procedure will be executed 
     at least once *)
end;

Еще одна вещь, в Алгоритмах Вирта + Структуры данных = Программы
можно найти процедуру просеивания без рекурсии
но мы должны ввести логическую переменную или break, чтобы исключить оператор goto

person J Doe    schedule 03.03.2018