I’m implementing the classic heap sort algorithm in C. I’ve been staring at this code for hours and still cannot figure out what is wrong for the life of me. The input 3 1 2 7 4 0 2 works well and produces a correct heap, but when I add an 8 on the end (and increment the size by one). It doesn’t produce a heap anymore. Any ideas? I think its just a silly off by one error. For reference http://en.wikipedia.org/wiki/Heapsort
#include <ctype.h>
#include <stdio.h>
#include <limits.h>
#include <stdlib.h>
#include <errno.h>
#include <math.h>
#include <string.h>
#define MAX_ARR 1024
void build_heap(int * fn, int len);
void heapify(int *f, int n, int size);
void verify_relations(int *f, int n);
void print_nums (int n[], int len);
void swap(int * a, int * b);
void heap_sort(int * a, int len);
int main(int argc, char **argv){
/* input works -- 3 1 2 7 4 0 2 */
/* input broken -- 3 1 2 7 4 0 2 8 */
int nums[100] = { 3, 1, 2, 7, 4, 0, 2, 8 };
int len = 8;
build_heap(nums, len);
verify_relations(nums, len);
print_nums(nums, len);
return 0;
}
void heap_sort(int nums[], int len){
int i;
build_heap(nums, len);
for (i = len; i > 0; --i)
{
swap(&nums[1], &nums[i]);
heapify(nums, 1, len);
}
}
void build_heap(int * nums, int len) {
int size = len, i;
for (i = size; i >= 0; i--){
heapify(nums, i, size);
}
}
void heapify(int f[], int n, int size){
int left = 2 * n,
right = 2 * n + 1,
largest = 0;
if (left < size && f[left] >= f[n])
largest = left;
else
largest = n;
if (right < size && f[right] >= f[largest])
largest = right;
if (largest != n) {
swap(&f[n], &f[largest]);
heapify(&n, largest, size);
}
}
void swap(int * a, int * b){
int temp = *a;
*a = *b;
*b = temp;
}
void verify_relations(int a[], int n){
if (a[0] >= a[1] && a[0] >= a[2])
printf("True - '%d >= %d && %d >= %d' \n", a[0], a[1], a[0], a[2]);
else
printf("False\n");
if (a[1] >= a[3] && a[1] >= a[4])
printf("True - '%d >= %d && %d >= %d' \n", a[1], a[3], a[1], a[4]);
else
printf("False\n");
if (a[2] >= a[4] && a[2] >= a[5])
printf("True - '%d >= %d && %d >= %d' \n", a[2], a[4], a[3], a[5]);
else
printf("False\n");
}
void print_nums (int n[], int len) {
int c;
for (c = 0; c < len; c++){
printf("%d ", n[c]);
}
}
The line
should be