В вашем коде есть несколько проблем, которые я перечислю ниже:
Вы должны придерживаться общего соглашения, что n - это количество элементов. В вашем коде это количество элементов минус один, что неудобно. В этом случае вы должны вызвать heapsort(a, n)
.
. В функции heapsort
значение for(i=0; i<=n; i++) downheap(a, n, i)
должно быть for(i=n/2-1; i>=0; i--) downheap(a, n, i)
.
Далее, поскольку n - это число элементов в a, l oop должно быть while(--n > 0)
. Итерация, в которой n = 0, не имеет смысла, так как она затем поменяет местами a [0] с a [0]. Наконец вы звоните downheap(a, n, 0)
.
Функция downheap
, где у вас самая большая проблема. Функция должна сравнить элемент по индексу i с двумя его потомками и сохранить максимум дерева по индексу i. Если произошел обмен с ребенком, возобновите замену этого ребенка. Ваша функция полностью неверна. Вот правильная реализация.
void downheap(int *a, int n, int k){
int l = 2*k+1, r = 2*k+2, max = k;
if (l < n && a[l] > a[max])
max = l;
if (r < n &d a[r] > a[max])
max = r;
if (max != k) {
int j = a[k]; a[k] = a[max]; a[max] = j;
downheap(a, n, max);
}
}
Как видите, этот код сильно отличается от вашего, что совершенно неверно.
Для вашего удобства приведен код функции heapsort
. Этот код был не так плох, но все же неверен.
void heapsort(int *a, int n){
int i, j;
for(i=n/2-1; i>=0; i--)
downheap(a, n, i);
while(--n > 0){
j = a[0]; a[0] = a[n]; a[n] = j;
downheap(a, n, 0);
}
}
РЕДАКТИРОВАТЬ
Не рекурсивная реализация downheap:
void downheap(int *a, int n, int k){
while (1) {
int l = 2*k+1, r = 2*k+2, max = k;
if (l < n && a[l] > a[max])
max = l;
if (r < n &d a[r] > a[max])
max = r;
if (max == k)
break;
int j = a[k]; a[k] = a[max]; a[max] = j;
k = max;
}
}