我一直无法使用堆排序程序从读入文件中正确排序整数。输出电流如下所示:
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));
}
答案 0 :(得分:0)
while(heap->size) {...}
后面紧跟一个循环for (i = 0; i < heap->size; i++) {...}
。如果第一个循环退出,则第二个循环应执行零迭代,但这不是您的输出显示的内容。因此,您发布的代码与您发布的输出不对应。deletion()
功能包含printf()
来电,其输出未反映在您发布的输出中。同样,您发布的输出与您发布的代码不符。heapify()
功能错误,或者至少错误地使用了它。它不需要它的第二个参数,因为它应该始终堆积,但是许多元素实际上是在堆中。如果这恰好与最近添加的元素(您在调用中假设)的值相对应,那么这纯属巧合。heapify()
函数还包含printf()
,其输出未反映在您发布的内容中。deletion()
函数不使用其第一个参数的值。deletion()
函数有一个错误:*(heap_array->data + (heap_array->size)) = temp
。它应该分配给*(heap_array->data + (heap_array->size - 1))
(即你应该执行交换)。当您随后将堆大小减小1时,刚放置以前顶部元素的位置将不再是堆的一部分。deletion()
在堆中每个元素(剩余)调用heapify()
一次,而只需要调用一次。