堆排序 - C编程

时间:2015-03-27 20:32:37

标签: c sorting structure heap

我一直无法使用堆排序程序从读入文件中正确排序整数。输出电流如下所示:

Heap created successfully!
size = 10
Insertion
9
8
7
6
3
4
2
5
1
0
Delete
8
7
6
5
4
3
2
1
0
0

我不知道我的代码的删除部分(插入似乎工作正常)发生了什么,并且已经修改了几个小时但仍然无法得到它。如果有人能对这段代码有所了解,请这样做。我将不胜感激!

struct heap_t {
    int last; 
    int size;
    int max;
    int *data;

};

void heapify(struct heap_t *heap_array, int size);
void swap(int i, int min, struct heap_t *heap_array);
void deletion(int i, struct heap_t *heap_array);

enum {INIT = 1, GROW = 2};

int main(int argc, char **argv) 
{

    char buf[LEN];
    FILE *fp = NULL;
    int i = 0;

        if (argc != 2) {
        printf("error in input\n");
        printf("usage: ./heap [FILE]\n");
        printf("[FILE] is a list of integers one per line\n");
        exit(EXIT_FAILURE);
    }
    else {
        fp = fopen(argv[1], "r");
        assert(fp);
    }

    struct heap_t *heap = malloc(sizeof(struct heap_t));
    heap->size = INIT;
    heap->max = INIT;
    heap->data = NULL;

    while (fgets(buf, LEN, fp)) {

        /* read in data from file */
        /* assign to heap->data */

        /* grow the array as necessary */
        if (heap->size > heap->max) {
            heap->data = realloc(heap->data, GROW * heap->max *sizeof(int));
            assert(heap->data);
            heap->max = GROW * heap->max;
        }
        else if (heap->data == NULL) {
            heap->data = malloc(INIT * sizeof(int));
            assert(heap->data);
        }
        *(heap->data + i) = atoi(buf);

        /* Heapifys as it inserts, thus building the heap*/
        heapify(heap, i);

        heap->size++;
        i++;
    }   
    printf("\nHeap created successfully!\n");

    /* size is off by one */
    heap->size--;
    printf("size = %d\n", heap->size);

    printf("Insertion\n");
    for (i = 0; i < heap->size; i++) {
        printf("%d\n", *(heap->data + i));  
    }

    heap->last = (heap->size);

    i = 0;
    while(heap->size){
        deletion(i, heap);
        i++;
    }

    printf("Delete\n");
    for (i = 0; i < heap->size; i++) {
        printf("%d\n", *(heap->data + i));  
    }


    /* send data to stdin -- if you correctly built a heapsort
         * this will print the data in ascending order */
    /*for (i = 0; i < heap->size; i++) {
        printf("%d\n", *(heap->data + i));  
    }*/

    /* cleanup */
    free(heap->data);
    free(heap);
    fclose(fp);

    return 0;
}

void heapify(struct heap_t *heap_array, int i)
{
    int child = i, parent = (child - 1) / 2;

    while(child != 0 && *(heap_array->data + child) > *(heap_array->data + parent)){
        swap(child, parent, heap_array);
        child = parent;
        parent = (child - 1) / 2;

        for(j = 0; j < heap_array->size; j++){
            printf("%d, ", *(heap_array->data + j));
        }
        printf("\n");
    }
}

void swap(int child, int parent, struct heap_t *heap_array)
{

    int temp = 0;
    temp = *(heap_array->data + child);
    *(heap_array->data + child) = *(heap_array->data + parent);
    *(heap_array->data + parent) = temp;
}

void deletion(int i, struct heap_t *heap_array)

{

    int temp;
    int j = 0;

    temp = *(heap_array->data + 0);
    *(heap_array->data + 0) = *(heap_array->data + (heap_array->size - 1));
    *(heap_array->data + (heap_array->size)) = temp;

    heap_array->size--;

    for(i = j; j < heap_array->size; j++){
        heapify(heap_array, j);
    }
    printf("%d -", *(heap_array->data + 0));
}

1 个答案:

答案 0 :(得分:0)

  1. 如果您的程序正确,请使用断言来测试必须为true的条件。尽管程序正确,但不要使用它们来测试可能发生的错误情况(例如内存分配失败),因为判断条件是否会被测试,这取决于程序的编译方式。
  2. 阅读每个输入后,它很难堆积,因为在添加最后一个值之前,您不需要数据以堆形式存在。
  3. 你有一个循环while(heap->size) {...}后面紧跟一个循环for (i = 0; i < heap->size; i++) {...}。如果第一个循环退出,则第二个循环应执行零迭代,但这不是您的输出显示的内容。因此,您发布的代码与您发布的输出不对应。
  4. 您的deletion()功能包含printf()来电,其输出未反映在您发布的输出中。同样,您发布的输出与您发布的代码不符。
  5. 您的heapify()功能错误,或者至少错误地使用了它。它不需要它的第二个参数,因为它应该始终堆积,但是许多元素实际上是堆中。如果这恰好与最近添加的元素(您在调用中假设)的值相对应,那么这纯属巧合。
  6. 您的heapify()函数包含printf(),其输出未反映在您发布的内容中。
  7. deletion()函数不使用其第一个参数的值。
  8. 此处deletion()函数有一个错误*(heap_array->data + (heap_array->size)) = temp。它应该分配给*(heap_array->data + (heap_array->size - 1))(即你应该执行交换)。当您随后将堆大小减小1时,刚放置以前顶部元素的位置将不再是堆的一部分。
  9. 函数deletion()在堆中每个元素(剩余)调用heapify()一次,而只需要调用一次。