Я получил этот вопрос на экзамене, но я не уверен, что понимаю, чего он хочет от меня. Не могли бы вы уточнить, правильно ли я поступил?
Вопрос
Целочисленный массив A передается в функцию makeHeap
, если A [0] содержит n, то A [1] — A [n-1] содержат числа в произвольном порядке. Написать makeHeap
такой, что A [1] — A [n-1] содержат минимальную кучу. Ваша функция должна создать кучу, обрабатывая элементы в порядке A [2], A [3], …, A [n-1].
Мое решение
void makeHeap(int A[], int n)
{
int r = n -1 ;
for(int i = 1; i <= n/2; i++)
siftUp(a, i , r );
}
/* i- parent , r - right of the array */
void siftUp(int A[], int i , int r )
{
boolean done = false ;
int j = 2* i ;
while (j <= r && !done)
{
if(A[j] > A[j+1]) // find the smalest child
j+=1 ;
if(A[i] > A[j])
{
// code to swap A[i] and A[j]
i = j ;
j = i*2 ;
}
else done = true ;
}
}
Является ли это решение хотя бы отдаленно правильным? Также является siftUp
правильное имя функции?
Мое новое решение
void makeHeap(int A[], int n)
{
for(int i = 1; i <= A[0]/2; i++)
siftUp(A, i );
}
/* i- parent */
void siftUp(int A[], int i )
{
bool done = false ;
int j = 2* i ;
while (i > 1 && !done)
{
if(A[j] > A[j+1]) // find the smallest child
j+=1 ;
if(A[i] > A[j])
{
/* swap A[j] and A[i] */
int temp = A[i];
A[i] = A[j];
A[j] = temp ;
j = i ;
i = i / 2 ;}
else done = true ;
}
}
Ваш код не будет кучи массива (игнорируя такие ошибки, как a
а также boolean
)
Для siftUp () имейте в виду свойство parent(i) = i/2
, где i
это индекс узла. Несколько псевдокодов для вставки узла в кучу (как последний узел кучи):
Algo siftUp(H[], n)
i = n
while i > 1 and H[i] < H[i/2]
swap(H[i], H[i/2])
i = i / 2
Это приведет к O (nlogn), когда вы выполняете итерацию по массиву, но есть лучший подход с конструкцией снизу вверх с O (n).
Других решений пока нет …